0

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

我想问的问题是:

由于库代码更改或安全补丁,Java 的某些部分是否会停止在各种 Java 版本中按预期工作?是否可以确定我的问题是否属于这种情况?

我相信这些信息将有助于其他编程新手,帮助他们更好地理解 Java 语言发展到新版本时发生的变化。我在此站点上发现了一个问题,该问题涉及 java 版本从 1.5 到 1.6 和 1.7 的更改(JDK 1.6 和 1.7 中的新功能),但我无法确定我的代码不起作用的原因适当地。

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

编辑

问题总结:

我的程序应该从它从系统中检索到的信息中创建一个 HTML 文件。这时候,1.5编译版与java 1.7版一起运行时,它只是创建了一个空白的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 编写、编码、编译并打包到 JAR 文件中的
  2. 在两个 Windows 7 x64 系统上进行了测试
  3. 我意识到创建特定于操作系统的代码与 Java 的目标背道而驰。
    • 该程序为其检索信息的应用程序将仅使用 Windows 操作系统。
    • 我还需要来自 Windows 注册表的信息。不确定我将如何做到这一点并维护 Java 跨平台功能。
  4. 我允许 Eclipse 自动生成清单文件
  5. 我对创建 Java 程序比较陌生。我将非常感谢任何
    有助于我解决我在本网站的编码或问题写作方面的任何问题的评论。

感谢您抽出宝贵时间查看此信息和我的问题。

编辑

从建议中获得的附加信息。

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 目录的实际位置。

如果有任何建议可以改进我的分辨率,请告诉我。

编辑

4

2 回答 2

0

Java 具有很强的向后兼容性。当问题确实出现时,很可能是由于创建的代码中存在错误。在最近的过去,由于更强大的安全措施,较旧的小程序存在问题。如果您的代码遇到问题,您应该确保在得出 Java 版本问题的结论之前使用了正确的调试技术。

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

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

于 2013-11-12T16:30:48.903 回答
0

因为有这么多评论:

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

一般来说:

  1. Java 确实是向后兼容的。

1a。然而:旧的小程序不久前由于更强大的安全措施而出现问题。

  1. 看到代码我怀疑涉及到 Java 版本不兼容。仍然...
于 2013-11-11T18:50:59.693 回答