【问题标题】:An exception occurred while instantiating a Java object. The class must not be an interface or an abstract class. Error: javax/mail/Store实例化 Java 对象时发生异常。该类不能是接口或抽象类。错误:javax/mail/Store
【发布时间】:2013-12-23 03:47:53
【问题描述】:

对于我的特定错误,我有一个解决方法,即将路径 C:\ColdFusion10\cfusion\wwwroot\WEB-INF\classes 添加到 ColdFusion 类路径设置中。但是,我不确定为什么这是必要的。详情如下:

我一直在使用 ColdFusion 9 中的一个遗留 [我不知道它是谁写的,或者它来自哪里] Java 类来帮助读取和解析邮箱文件。当我升级到 ColdFusion 10 时,它停止工作。这是一个简短的例子:

<cfset archive = createObject("Java", "its.util.MBoxReader")>
<cfdump var="#archive#">

在 CF9 上有效。在 CF10 上,它会生成以下消息:

对象实例化异常。 实例化 Java 对象时发生异常。该类不能是接口或抽象类。错误:javax/邮件/存储。

这是堆栈跟踪:

java.lang.NoClassDefFoundError: javax/mail/Store at java.lang.Class.getDeclaredFields0(本机方法)在 java.lang.Class.privateGetDeclaredFields(Class.java:2317) 在 java.lang.Class.privateGetPublicFields(Class.java:2350) 在 java.lang.Class.getFields(Class.java:1378) 在 Coldfusion.runtime.java.ObjectHandler.Initialize(ObjectHandler.java:35) 在 Coldfusion.runtime.java.ObjectHandler.(ObjectHandler.java:30) 在 Coldfusion.runtime.java.ReflectionCache.get(ReflectionCache.java:38) 在coldfusion.runtime.java.JavaProxy.(JavaProxy.java:35) 在 Coldfusion.runtime.java.JavaProxyFactory.getProxy(JavaProxyFactory.java:121) 在coldfusion.runtime.ProxyFactory.getProxy(ProxyFactory.java:65) 在 Coldfusion.runtime.CFPage.createObjectProxy(CFPage.java:5757) 在 Coldfusion.runtime.CFPage.CreateObject(CFPage.java:5720) 在 Coldfusion.runtime.CFPage.CreateObject(CFPage.java:5654) 在 Coldfusion.runtime.CFPage.CreateObject(CFPage.java:5629) 在 Coldfusion.runtime.CFPage.CreateObject(CFPage.java:5576) 在 cfindex2ecfm915725705.runPage(C:\ColdFusion10\cfusion\wwwroot\mbox\index.cfm:1) 在coldfusion.runtime.CfJspPage.invoke(CfJspPage.java:244) 在 Coldfusion.tagext.lang.IncludeTag.doStartTag(IncludeTag.java:444) 在 Coldfusion.filter.CfincludeFilter.invoke(CfincludeFilter.java:65) 在 Coldfusion.filter.IpFilter.invoke(IpFilter.java:64) 在 Coldfusion.filter.ApplicationFilter.invoke(ApplicationFilter.java:449) 在 Coldfusion.filter.RequestMonitorFilter.invoke(RequestMonitorFilter.java:48) 在 Coldfusion.filter.MonitoringFilter.invoke(MonitoringFilter.java:40) 在coldfusion.filter.PathFilter.invoke(PathFilter.java:112) 在 Coldfusion.filter.LicenseFilter.invoke(LicenseFilter.java:30) 在 Coldfusion.filter.ExceptionFilter.invoke(ExceptionFilter.java:94) 在 Coldfusion.filter.BrowserDebugFilter.invoke(BrowserDebugFilter.java:79) 在 Coldfusion.filter.ClientScopePersistenceFilter.invoke(ClientScopePersistenceFilter.java:28) 在coldfusion.filter.BrowserFilter.invoke(BrowserFilter.java:38) 在 Coldfusion.filter.NoCacheFilter.invoke(NoCacheFilter.java:46) 在 Coldfusion.filter.GlobalsFilter.invoke(GlobalsFilter.java:38) 在 Coldfusion.filter.DatasourceFilter.invoke(DatasourceFilter.java:22) 在coldfusion.filter.CachingFilter.invoke(CachingFilter.java:62) 在 冷融合.CfmServlet.service(CfmServlet.java:219) 在 Coldfusion.bootstrap.BootstrapServlet.service(BootstrapServlet.java:89) 在 org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:305) 在 org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210) 在 Coldfusion.monitor.event.MonitoringServletFilter.doFilter(MonitoringServletFilter.java:42) 在 Coldfusion.bootstrap.BootstrapFilter.doFilter(BootstrapFilter.java:46) 在 org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:243) 在 org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210) 在 org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:224) 在 org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:169) 在 org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:472) 在 org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:168) 在 org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:98) 在 org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:928) 在 org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:118) 在 org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:414) 在 org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:987) 在 org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:539) 在 org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:298) 在 java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145) 在 java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615) 在 java.lang.Thread.run(Thread.java:722) 引起: java.lang.ClassNotFoundException:javax.mail.Store 在 org.apache.catalina.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1688) 在 org.apache.catalina.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1533) ... 55 更多

但是,如果我将此添加到我的测试页面,CF10 能够找到并加载 javax.mail.Store:

<cfset store = createObject("Java", "javax.mail.Store")>
<cfdump var="#store#">

javax.mail.Store 存在于 ColdFusion 随附的 mail.jar 文件中,分别位于 CF9 和 CF10 上的 C:\ColdFusion9\libC:\ColdFusion10\cfusion\lib

MboxReader.class 位于C:\ColdFusion9\wwwroot\WEB-INF\classes\its\utilC:\ColdFusion10\cfusion\wwwroot\WEB-INF\classes\its\util(分别为CF9 和CF10)。

如果我在 CF 管理员中手动将 C:\ColdFusion10\cfusion\wwwroot\WEB-INF\classes 添加到 ColdFusion 类路径,它就可以工作。

我不确定为什么 ColdFusion 可以找到该类,但除非我添加类路径,否则 MboxReader 类不能。根据About ColdFusion, Java, and J2EE,ColdFusion 应该加载 WEB-INF/classes 中的类。

更新:

archive对象的父类加载器:

coldfusion.bootstrap.BootstrapClassLoader

javax.mail.Store对象的父类加载器:

org.apache.catalina.loader.WebappClassLoader

【问题讨论】:

  • 顺便说一句,你为什么使用classes?通常,多个类文件捆绑在 jar 中并存储在 lib 中。除此之外,管理单个 jar 文件比管理一堆单独的 .class 文件要容易得多。
  • 这在我任职之前,但我认为这个想法是更容易将更新部署到单个类,而不是每次都重新打包一个 jar 文件。事实证明,这些类很少更新,可能应该捆绑在一起。
  • 也许这些东西是在 Ant 等工具出现之前创建的,可以通过单击按钮为您构建 jar?在我看来,单独的类会使事情更难部署,因为有更多的移动部件。另外,不同的课程更有可能不同步。用一个jar,每次只有一个文件。顺便说一句,我的意思是问 - 您的自定义 java 内容是否还包括 classes 目录中的邮件类 - 还是仅仅依赖于它已经与 CF 捆绑的事实?
  • 自定义 Java 不包含邮件类,它依赖于 CF 的 mail.jar。当我将 mail.jar 从 C:\ColdFusion10\cfusion\libs 复制到 C:\ColdFusion10\cfusion\wwwroot\WEB-INF\libs 时,它可以工作!正如您和@jhadesdev 都建议的那样,这似乎肯定表明存在类加载器问题。与将应该是动态加载类的目录添加到类路径相比,包含一个额外的 mail.jar 副本对我来说似乎是一个更好的解决方案。

标签: java coldfusion classpath coldfusion-10


【解决方案1】:

似乎某些类依赖于 javax.mail.Store,但它在运行时找不到它。如果您可以发布完整的堆栈跟踪,我们可以看到它是哪个类。

试试coldfusion中classloader链是怎么设置的,WEB-INF/classes默认包含,然后是WEB-INF/lib的所有jar。

EE 服务器可以配置为首先查看服务器,然后才查看 WEB-INF/classes/WEB-INF/lib。此配置是服务器和应用程序特定的,每个服务器具有不同的默认值(Tomcat 默认值不同于 websphere 等)。

如果 Coldfusion 使用 Java 7,您可以使用 JHades 打印类加载器链并在类路径上进行一些查询,以查看几个有问题的类的不同版本在哪里。

尝试回答这些问题,您可以随时发布部分发现:

  • 哪个类没有找到 java.mail.Store

  • 抛出异常的类驻留在哪个类加载器中

  • 对于有问题的类(javax.mail.Store 和未找到它的类),根据类加载器发布类路径中存在的不同版本(JHades 可以提供帮助)

  • 类加载器链设置是如何配置的,配置的优先级是什么等。

【讨论】:

  • 我打算提出类似的问题,即类加载器问题。但是,澄清一下 - 不是 CF 本身找不到类,而是 jvm 加载 有问题。 CF 已经包含了邮件 jars(两个版本的 IIRC)。所以事情可能会变得有点不稳定,具体取决于哪个类加载器最终加载您的自定义对象和/或...(续)
  • .. 如果你的东西还包括一个版本的邮件罐子/类。我怀疑将位置添加到类路径最终会更改对象的父类加载器,因此邮件 jar 现在可以根据class loader hierachy rules“访问”。 @jhadesdev - RE: 每个服务器的默认值不同 是的,我很确定 CF 自定义加载顺序。虽然我不确定规则到底是什么......
  • 我在帖子中添加了完整的堆栈跟踪。我还没有成功运行 JHades,所以我还没有回答你的其他问题,但是根据你的 cmets 和 @Leigh 的 cmets,这肯定是一个类加载器问题。
  • @cherdt - 如果有机会,可以转储archive 的父类加载器吗?它报告什么?我很好奇它的父...
  • @Leigh,我不确定如何获取该信息。如何访问父类加载器?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2013-08-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-08-18
  • 1970-01-01
相关资源
最近更新 更多