Motorola FX9500上的JamVM问题 - 我该怎么办?

kmp*_*kmp 10 java jamvm

我正在使用摩托罗拉FX9500 RFID阅读器,它运行带有jamvm版本1.5.0的Linux (我只能部署应用程序 - 我无法更改Java VM或任何其他因此我的选项有限) - 这就是我所看到的我查看版本:

[cliuser@FX9500D96335 ~]$ /usr/bin/jamvm -version
java version "1.5.0"
JamVM version 1.5.4
Copyright (C) 2003-2010 Robert Lougher <rob@jamvm.org.uk>

This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2,
or (at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

Build information:

Execution Engine: inline-threaded interpreter with stack-caching
Compiled with: gcc 4.2.2

Boot Library Path: /usr/lib/classpath
Boot Class Path: /usr/local/jamvm/share/jamvm/classes.zip:/usr/share/classpath/glibj.zip
Run Code Online (Sandbox Code Playgroud)

我需要编写一个应用程序,所以我抓住了Oracle Java SDK 1.5.0并将其安装到我的Windows 7 PC上,所以它有这个版本:

C:\>javac -version
javac 1.5.0
Run Code Online (Sandbox Code Playgroud)

考虑到我使用该编译器编译的应用程序可以在上述JamVM上正常工作,我是否过于理想化?无论如何,在无知中按下我写这个小应用程序:

public final class TestApp {
    public static void main(final String[] args) {
        long p = Long.MIN_VALUE;
        int o = (int)(-(p + 10) % 10);
        System.out.println(o);
    }
}
Run Code Online (Sandbox Code Playgroud)

用前面提到的javac编译器编译它并在PC上运行它,如下所示:

C:\>javac TestApp.java

C:\>java TestApp
8
Run Code Online (Sandbox Code Playgroud)

一切都很好.生活是美好的,所以我拿起那个.class文件放在FX9500上并运行它:

[cliuser@FX9500D96335 ~]$ /usr/bin/jamvm TestApp
-2
Run Code Online (Sandbox Code Playgroud)

Eek,正如你所看到的那样 - 它会返回不同的结果.

那么,为什么和谁错了或者这个规范之类的东西不清楚如何处理这个计算(肯定不是)?难道我需要用不同的编译器编译它吗?


我为什么关心这个?

我遇到这种情况的原因是,完全像在内部发生的计算java.lang.Long.toString,我在我的实际应用程序中有一个错误,我正在注销一个很长的并得到一个java.lang.ArrayIndexOutOfBoundsException.因为我想要记录的值很可能在a的末尾Long.

我想我可以通过检查Long.MIN_VALUE和Long.MAX_VALUE来解决它并记录"错误,我不能告诉你这个号码,但它真的是Long.XXX,相信我,我会欺骗你吗?".但是当我发现这个时,我觉得我的应用程序现在建立在一个沙质基础上,它需要非常强大.我正在认真地考虑说JamVM不能胜任工作并用Python编写应用程序(因为读者也有Python运行时).

我有点希望有人告诉我,我是一个笨蛋,我应该在我的Windows PC上编译它......然后它会工作,所以请告诉我(如果它是真的,当然) !


更新

Noofiz让我思考(谢谢),我敲了这个额外的测试应用程序:

public final class TestApp2 {
    public static void main(final String[] args) {

        long p = Long.MIN_VALUE + 10;

        if (p != -9223372036854775798L) {
            System.out.println("O....M.....G");
            return;
        }

        p = -p;

        if (p != 9223372036854775798L) {
            System.out.println("W....T.....F");
            return;            
        }

        int o = (int)(p % 10);

        if (o != 8) {
            System.out.println("EEEEEK");
            return;
        }

        System.out.println("Phew, that was a close one");
    }
}
Run Code Online (Sandbox Code Playgroud)

我再次在Windows机器上编译并运行它.

它打印 Phew, that was a close one

我将.class文件复制到有问题的装置并运行它.

它打印...

......等待......

W....T.....F

噢亲爱的.我觉得有点恍惚,我想我需要一杯茶......

更新2

我尝试的另一件事,没有任何区别,就是将FX9500上的classes.zip和glibj.zip文件复制到PC上,然后像这样进行交叉编译(这必须意味着编译后的文件应该没问题)对?):

javac -source 1.4 -target 1.4 -bootclasspath classes.zip;glibj.zip -extdirs "" TestApp2.java
Run Code Online (Sandbox Code Playgroud)

但是,在读取器上运行时生成的.class文件会打印相同的消息.

小智 5

我写了JamVM.正如您可能猜到的那样,此类错误现在已经被注意到了,而JamVM甚至无法通过最简单的测试套件(GNU Classpath有自己的Mauve,而OpenJDK有jtreg).我经常运行ARM(FX9500使用PXA270 ARM)和x86-64,但各种平台都作为IcedTea的一部分进行测试.

所以我对这里发生的事情并不了解.我猜它只会影响Java的长度,因为这些很少使用,所以大多数程序都可以工作.JamVM将Java longs映射到C long longs,所以我的猜测是用于构建JamVM的编译器会产生错误的代码,以便在32位ARM上进行长时间处理.

不幸的是,如果你不能取代JVM,你可以做的事情不多(除了避免多头).你唯一能做的就是尝试关闭JIT(一个简单的代码复制JIT,也就是内联线程).为此,请在命令行中使用-Xnoinlining,例如:

jamvm -Xnoinlining ...