我刚刚解决了另一个*我 - 虽然我正在使用这个版本的库 - 但显然是我的应用程序服务器已经已经加载了一个更老的 - 版本的这个库 - *问题(叹气)。
是否有人知道验证(或监控)您的应用程序是否可以访问所有相应的jar文件或加载的类版本的好方法?
提前致谢!
[P.S。在我的视图中开始使用OSGi module architecture的一个很好的理由!]
更新:This文章也有帮助!通过将JBoss的类加载器写入日志文件,它让我深入了解JBoss的类加载器。
答案 0 :(得分:18)
如果您正在使用JBoss,则有一个MBean(类加载器存储库iirc),您可以在其中请求已加载某个类的所有类加载器。
如果所有其他方法都失败了,那么总会有'java -verbose:class',它将为每个正在加载的类文件打印jar的位置。
答案 1 :(得分:5)
如果您在jar清单中有适当的版本信息,则有检索和测试版本的方法。无需手动阅读清单。
java.lang.Package。getImplementationVersion()和getSpecificationVersion()以及isCompatibleWith()听起来像是在做你正在寻找的东西。
您可以使用this.getClass()。getPackage()以及其他方式获取Package。
java.lang.Package的javadoc没有为这些属性提供特定的清单属性名称。快速谷歌搜索将其调整为http://java.sun.com/docs/books/tutorial/deployment/jar/packageman.html
答案 2 :(得分:3)
在当前版本的Java中,库版本控制是一个相当糟糕的术语,它依赖于JAR与正确的清单一起正确打包。即便如此,正在运行的应用程序仍然需要以有用的方式收集这些信息。 JVm运行时没有任何帮助。
我认为最好的办法是在构建时强制执行此操作,使用Ivy或Maven等依赖管理工具来获取所有内容的正确版本。
有趣的是,Java 7可能会包含一个适当的模块版本控制框架,正是为了这类事情。这并不能帮助你,
答案 3 :(得分:2)
我认为没有一个好方法可以检查。而且我不确定你是否愿意这样做。您需要做的是熟悉app-server的类加载架构,并了解其工作原理。
它的工作原理的简化说明是:EJB或web-app将首先在其自己的模块(ejb-jar或war)中声明的库中查找类或资源。如果在那里找不到类,则类加载器将请求转发给其父类加载器,该父类加载器是声明的依赖项(通常是ejb)或应用程序类加载器,它负责加载在ear包中声明的库和资源。 。如果仍未找到类或资源,则将请求转发到将在其自己的类路径中查找的应用服务器。
这就是说,您应该记住,Java EE模块(web-app,ejb)将始终从最近范围内的jar加载类。例如,如果你在war文件中打包log4j v1,在ear level级别将log4j v2打包,并将log4j v3放在app-server的类路径中,模块将在其自己的模块中使用jar。拿走它,它将使用耳朵水平。把它取出来,它将使用app-server的类路径中的那个。当模块之间存在复杂的依赖关系时,事情变得更加棘手。
最好是将应用程序全局库放在耳边。
答案 4 :(得分:0)
必须有比我这样做更好的方式,但我倾向于以非常手动的方式做到这一点。
正如我所说,它是手动的,但它有效。