Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/357.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 摩托罗拉FX9500问题上的JamVM-我该怎么办?_Java_Jamvm - Fatal编程技术网

Java 摩托罗拉FX9500问题上的JamVM-我该怎么办?

Java 摩托罗拉FX9500问题上的JamVM-我该怎么办?,java,jamvm,Java,Jamvm,我使用的是一个RFID阅读器,它运行的Linux版本为1.5.0(我只能在上面部署应用程序-我无法更改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

我使用的是一个RFID阅读器,它运行的Linux版本为1.5.0(我只能在上面部署应用程序-我无法更改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
我是否过于理想化地认为使用该编译器编译的应用程序可以在前面提到的JAVM上正常工作?不管怎样,在无知中坚持下去,我写了这个小应用程序:

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);
    }
}
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");
    }
}
使用上述javac编译器编译并在PC上运行,如下所示:

C:\>javac TestApp.java

C:\>java TestApp
8
那里一切都很好。生活是美好的,所以我将该
.class
文件放在

[cliuser@FX9500D96335 ~]$ /usr/bin/jamvm TestApp
-2
嗯,正如你所看到的,它返回一个不同的结果

那么,为什么和谁错了,或者这类似于规范不清楚如何处理这种计算(当然不清楚)?是不是我需要用不同的编译器来编译它


我为什么关心这个问题?

我之所以出现这种情况,是因为在
java.lang.Long.toString
中发生了与之完全相同的计算,我在实际应用程序中有一个错误,我注销了一个Long,得到了一个
java.lang.ArrayIndexOutOfBoundsException
。因为我想要记录的值很可能位于
Long
的末尾

我想我可以通过检查Long.MIN_值和Long.MAX_值并记录“呃,我不能告诉你数字,但它确实很长。XXX,相信我,我会对你撒谎吗?”。但当我发现这一点时,我觉得我的应用程序现在建在沙质地基上,它需要非常坚固。我正在认真考虑说JamVM不能胜任这项工作,并用Python编写应用程序(因为读者也有Python运行时)

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


更新

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

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);
    }
}
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");
    }
}
一、 同样,在Windows计算机上编译并运行它

它打印出
Phew,这是一个非常接近的

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

它打印

……等等

W..T..F

哦,天哪。我觉得有点头晕,我想我需要一杯茶

更新2

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


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

问题在于不同的模块实现:

public static long mod(long a, long b){
    long result = a % b;
    if (result < 0)
    {
        result += b;
    }
    return result;
}
公共静态长模式(长a、长b){
长期结果=a%b;
如果(结果<0)
{
结果+=b;
}
返回结果;
}
此代码返回-2,而此代码:

public static long mod2(long a, long b){
    long result = a % b;
    if (result > 0 && a < 0)
    {
        result -= b;
    }
    return result;
}
公共静态长mod2(长a、长b){
长期结果=a%b;
如果(结果>0&&a<0)
{
结果-=b;
}
返回结果;
}
返回8。JamVM这样做的原因在我的理解背后

来自JLS:

15.17.3。余数运算符%

二进制后为整数的操作数的余数运算 数字提升(§5.6.2)产生的结果值 (a/b)*b+(a%b)等于a


根据这一点,JamVM打破了语言规范。非常糟糕。

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

所以我对这里发生的事一无所知。我想这只会影响Java长代码,因为它们很少使用,所以大多数程序都可以工作。JamVM将Java long映射为C long long,因此我猜测用于构建JamVM的编译器在32位ARM上生成了不正确的long-long处理代码

不幸的是,如果您不能替换JVM,那么除了避免长时间之外,您没有什么可以做的。您唯一能做的就是尝试关闭JIT(一种简单的代码复制JIT,也称为内联线程)。要执行此操作,请在命令行上使用-Xnoinlining,例如:


jamvm-xnoInLine…

我会发表评论,但出于某种原因,这需要声誉

长否定在此设备上不起作用。我不明白它的确切性质,但如果你做两个一元负数,你会回到你开始的地方,例如x=10-x==4294967286-x==10。4294967286非常接近整数。最大值*2(2147483647*2=4294967294)。它更接近整数。最大值*2-10

它似乎是孤立于这一个操作的,并且不会进一步从根本上影响多头。在您自己的代码中避免该操作很简单,并且通过一些巧妙的滥用bootclasspath,可以避免GNU类路径代码中的调用,用*-1s替换它们。如果需要从设备GUI启动应用程序,可以包括-Xbootclasspath=。。。切换到args参数,以便将其传递给JamVM)

该错误实际上已经在后一版本(比最新版本)的JamVM代码中修复: * *

但这对我们在设备上的固定版本没有帮助。Rob Lougher提到这个问题是发布新版本JamVM的一个原因,尽管我不知道什么时候发布,也不知道摩托罗拉是否有足够的信心更新他们的固件

FX9500实际上是在610中重新打包的Sirit,这意味着