使用较旧的JDK编译的Java代码无法与较新的JRE / JVM一起正常工作

时间:2013-11-11 16:32:22

标签: java eclipse

由于这变得很长而且非常具体,我认为插入几行来澄清问题以及为什么这对其他人有用可能是个好主意。请记住这是我的第一个问题。如果我收集的信息太少或太多,请告诉我。

我想问的问题是:

由于库代码更改或安全补丁,Java的各个部分是否会因各种版本的Java而无法正常工作?可以确定我的问题是否属于这种情况?

我相信这些信息对其他编程新手有帮助,可以帮助他们更好地理解Java语言发展到新版本时所发生的变化。我在这个网站上发现了一个问题,它将java版本从1.5改为版本1.6和1.7(New features in JDK 1.6 and 1.7),但我无法确定我的代码无法正常工作的原因。

我编写了一个程序,可以使用Runtime对象从Windows系统检索值来执行命令行请求。检索的信息主要是注册表项值。检索此信息后,我让程序创建一个File对象,并将检索到的信息输出到它创建的HTML文件中。我可以在每个版本(1.5和1.7)上创建并运行可执行的JAR文件。但是,在1.7系统上执行1.5 JAR时,会生成生成的HTML但仍为空白。程序停止工作的另一部分是它的调试选项。我创建了一个调试选项,在JAR所在的同一目录中查找名为debug.txt的文件。 1.5版本不会激活1.7上的调试选项。

修改

问题摘要:

我的程序应该根据它从系统中检索的信息创建一个HTML文件。此时,当使用java版本1.7运行1.5编译版本时,它只是创建一个空白HTML文件而不是一个填充信息的文件。另一个变化是程序通常生成一个调试日志文件,其中创建的字符串如第一个代码段catch块中所示。这应该在文件debug.txt存在时完成,但不存在。

修改

我研究了这个问题并且知道Java旨在向后兼容。我找不到任何可能指向版本问题的问题。我相信在跨版本应用时,我的代码可能会出现问题。

我已将部分代码包含在未按预期运行的部分中。

try{
    File file = new File("C:\\Users\\" + System.getProperty("user.name") + "\\Desktop\\Results.html");

    FileWriter outFile = new FileWriter(file);
    PrintWriter out = new PrintWriter(outFile);

    out.println("A large" + amount + "of concatenated" + strings);
    out.flush();
    out.close();
}catch(IOException e){
    //debugErrorString currently has global scope
    debugErrorString += ("*************************************************************\r\n" + 
                                "There was an issue with writting the results.html document" + e + 
                                "\r\n**********************************************************\r\n\r\n\r\n\r\n");
}

public static void writeDebugLog(){
    try{
        final String debugLogFile = "C:\\Users\\" + System.getProperty("user.name") + 
                                                "\\Documents\\WorkstationDebugLogFile.txt";

        PrintWriter out = new PrintWriter(new FileWriter(debugLogFile));

        //registry currently has global scope
        out.println(debugErrorString + "\n\n\n" + registry.getDebugString() + "\r\n");
        out.flush();
        out.close();

    }catch(Exception e){
        System.out.println(e);
    }
}

其他信息:

  1. 使用Eclipse
  2. 编写,编码,编译并打包到JAR文件中
  3. 在两个Windows 7 x64系统上执行测试
  4. 我意识到创建特定于操作系统的代码是违背目标的 Java的。
    • 此程序检索信息的应用程序仅使用 Windows操作系统。
    • 我还需要Windows注册表中的信息。不知道我会怎么做 并维护Javas跨平台功能。
  5. 我允许Eclipse自动生成清单文件
  6. 我对创建Java程序比较陌生。我将非常感谢任何评论 这有助于我解决我的编码或本网站问题的任何问题。
  7. 感谢您抽出宝贵时间查看此信息和我的问题。

    编辑

    从建议中获得的其他信息。

    Exception in thread "main" java.lang.reflect.InvocationTargetException
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.lang.reflect.Method.invoke(Method.java:601)
        at org.eclipse.jdt.internal.jarinjarloader.JarRsrcLoader.main(JarRsrcLoader.java:58)
        Caused by: java.lang.StringIndexOutOfBoundsException: String index out of range:-1
        at java.lang.String.substring(String.java:1958)
        at com.McKesson.WorkstationDiagnostic.WorkstationDiagnostic.createPage(WorkstationDiagnostic.java:321)
        at com.McKesson.WorkstationDiagnostic.WorkstationDiagnostic.main(WorkstationDiagnostic.java:125)
        ... 5 more 
    

    有问题的一行是:

    if(new File(envVar.substring(envVar.indexOf("C:\\oracle\\product\\"), envVar.indexOf("\\bin;C:\\") + 4)).exists())
    

    虽然我不确定为什么只有在跨越版本时才找到子字符串,我现在有一些东西要看。我将不得不处理这个未找到的子字符串并超出搜索字符串的限制,以及确定跨越版本时此问题的原因。

    这也引导我回到最初的问题。为什么这样的事情只有在使用更新的版本执行时才能起作用?

    修改

    编辑

    根据评论,我做了以下更改:

    if(new File(envVar.substring(envVar.indexOf("C:\\oracle\\product\\"), envVar.indexOf("\\bin;C:\\") + 4)).exists())
    

    已更改为

    String tokens [] = envVar.split(";");
    
        for(int i = 0; i < tokens.length; i++)
            if(tokens[i].contains("C:\\Oracle\\Product") && new File(tokens[i]).exists())
    

    这也应该消除抛出看到的数组索引错误的可能性。我也在想,如果第一次测试是假的,那么第二次测试将不会被执行。

    我试图通过这一行来达到的目标是确定环境变量包含Oracle bin目录的实际位置。

    如果有任何改进我的决议的建议,请告诉我。

    修改

2 个答案:

答案 0 :(得分:0)

因为有很多评论:

值得检查的一件事:使用两个Java版本编译应用程序。然后,您可以使用Java 7运行时检查是否存在差异。

一般来说:

  1. Java确实强烈向后兼容。
  2. 1a上。但是:由于更强的安全措施,不久前的旧Applet会出现问题。

    1. 看到代码我怀疑涉及Java版本不兼容。仍然...

答案 1 :(得分:0)

Java强烈向后兼容。当出现问题时,可能是由于创建的代码中存在错误。在最近的过去,由于更强的安全措施,旧Applet存在问题。如果您遇到代码问题,在得出Java版本问题之前,应确保使用正确的调试技术。

对于这个特殊问题,环境变量的读取方式存在缺陷。通过搜索以“\ bin”结尾的子字符串,可以在起始字符串“C:\ oracle \ product \”之前到达此公共字符串。这将引发错误,因为请求的子字符串的结尾将在开始之前。这导致所看到的行为的原因是由于JDK 1.5在环境变量中的放置。

由于调试操作不当,也漏掉了这个问题。虽然IDE(本例中为Eclipse)对编写和调试代码很有用,但通常情况下可以从命令行中运行程序中检索更多有用的信息。在此示例中,程序在Eclipse中运行时正常执行,但不是作为JAR运行。因此,当双击执行JAR时,没有要检查的系统输出。使用命令提示符运行JAR允许错误具有可查看的可见空间。