2010-03-15 43 views
8

我想打包一段代码,绝对必须在Java 1.5上运行。如果虚拟机为1.6 VM,则代码的一部分可以“增强”程序。Java:最简单的方法来打包Java 1.5和1.6代码

基本上它的这种方法:

private long[] findDeadlockedThreads() { 
    // JDK 1.5 only supports the findMonitorDeadlockedThreads() 
    // method, so you need to comment out the following three lines 
    if (mbean.isSynchronizerUsageSupported()) 
     return mbean.findDeadlockedThreads(); 
    else 
     return mbean.findMonitorDeadlockedThreads(); 
    } 

什么是有这个编译 1.5,但做1.6方法调用1.6时,最简单的方法?

在过去,我通过编译一个独特的1.6类来完成类似的工作,我将其打包到应用程序中,并在1.6上使用ClassLoader进行实例化(因为1.6 JVM完美地混合了0x32和0x31类),但我认为这有点矫枉过正(并且有点痛苦,因为在构建过程中你必须建立0x31和0x32 .class文件)。

如果我想在1.5上编译上述方法,该怎么办?也许使用反射,但再怎么(我不熟悉,在所有反射)

注意:如果你好奇,上述方法来自这篇文章:http://www.javaspecialists.eu/archive/Issue130.html

(但我不想“评论三条线”就像文章中的一样,我希望它能够在1.5和1.6上编译和运行)

回答

3

你不能在1.5上编译它,但是你可以在1.6上编译目标选项设置为1.5这将产生1.5的字节码),并在代码中使用反射来确定该方法是否可用。

此代码将查找方法: mbean.getClass()。getMethod(“findDeadlockedThreads”,new Class [0]); 问题是,如果该方法不存在而不是简单地返回null或类似的东西,则会引发NoSuchMethodException。这意味着,您需要这样的代码:

try 
{ 
    mbean.getClass().getMethod("findDeadlockedThreads", new Class<?>[0]); 
    return mbean.findDeadlockedThreads(); 
} 
catch(NoSuchMethodException ex) 
{ 
    return mbean.findMonitorDeadlockedThreads(); 
} 

这不是很好,因为它使用Exception来做出决定。这可能不是很快。另一种方法是使用getMethods,如果方法可用,则遍历返回的列表。这也不是很快。

编辑:克里斯托弗Oezbek在评论中建议只检查一次存在的方法,并保存结果,以避免Try-catch-block的开销。这是正确的,一个很好的解决方案。 matt b警告说,Java-Compiler的目标选项没有检查,如果所使用的类和方法在Java 1.5下可用。这是正确的(否则它将无法工作,因为你想用1.6方法编译),这意味着程序应该在1.5-VM下仔细测试,以避免这个问题。感谢您的评论。

+0

@Mnementh:OK,但随后会是什么反映代码的样子? – SyntaxT3rr0r 2010-03-15 16:17:23

+0

我编辑了我的答案以包含反射代码。 – Mnementh 2010-03-15 16:23:52

+0

@Menmenth:+1好极了......我会尽力在今天下午设置它:) – SyntaxT3rr0r 2010-03-15 16:26:47

2

编译为1.5。

在你的代码中使用反射。您可以从Class接口获取Method对象;它有一个invoke方法,它将mbean实例作为参数。像这样:

Class c = mbean.getClass(); //也可以做YourClass.class来获得这个

方法m = c。getMethod( “findMonitorDeadLockedThreads”); //或任何其他方法(参数 方法与类指定...第二个参数getMethod)

m.invoke(的MBean)//调用方法与实例

当然你不每次都不必这样做;在构造函数中设置Method引用,然后根据需要调用正确的引用。

+0

@danpaq:这是一个简单的情况,因为没有参数传递给方法。所以从Mnementh和你的回答中我可以看出,思考是要走的路......所以我会尝试你在这里提出的建议。 – SyntaxT3rr0r 2010-03-15 16:22:06

+0

@WizardOfOdds:如果你认为这个建议有价值,请注意。 – 2010-03-15 16:25:23

1

Maven让你可以很容易地使用配置文件来做到这一点。配置文件背后的想法是,您希望基于某些标准构建两种不同版本的东西。在此特定示例中,您可以定义jdk15jdk16配置文件,指定要编译哪个JDK版本,并指示它在jdk15配置文件中包含该类的一个副本,而另一个包含在jdk16中。

要开始,请参阅:

http://unserializableone.blogspot.com/2008/09/compile-and-test-with-different-jdk.html

介绍如何做的问题的不同的JDK版本的一部分。

来处理这个问题的第二部分,使用取决于JDK版本类的不同的定义,请参阅本:

Maven - Include Different Files at Build Time

+0

对不起,希望有所帮助...我现在没有空闲时间向您展示完整的Maven构建脚本。 – 2010-03-15 16:18:50

+0

为了确保我能理解你说的是正确的:我需要打包并发布一个独特的* .jar *,在1.5和1.6上使用1.6功能时,我可以使用Mave配置文件进行操作吗? – SyntaxT3rr0r 2010-03-15 16:20:54

+0

@WizardOfOdds:是的,这正是我之前试图描述的。我修改了我的回复,以获得比我在这里描述的更好的链接。 – 2010-03-15 18:56:41

相关问题