首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >JamVM关于摩托罗拉FX9500的问题-我该怎么办?

JamVM关于摩托罗拉FX9500的问题-我该怎么办?
EN

Stack Overflow用户
提问于 2013-04-05 08:07:28
回答 3查看 1.6K关注 0票数 10

我使用的是一个摩托罗拉FX9500射频识别读取器,它运行Linux1.5.0版本(我只能将应用程序部署到它--我不能更改Java或任何限制我的选项)--下面是我在检查版本时看到的:

代码语言:javascript
复制
[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

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

代码语言:javascript
复制
C:\>javac -version
javac 1.5.0

考虑到我用那个编译器编译的应用程序在上述JamVM上正确工作,我是不是太理想化了?不管怎样,在无知中我写了一个小应用程序:

代码语言:javascript
复制
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);
    }
}

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

代码语言:javascript
复制
C:\>javac TestApp.java

C:\>java TestApp
8

那里一切都很好。生活是美好的,所以我把这个.class文件放在FX9500上,然后按如下方式运行:

代码语言:javascript
复制
[cliuser@FX9500D96335 ~]$ /usr/bin/jamvm TestApp
-2

Eek,您可以看到什么the...as -它返回一个不同的结果。

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

我为什么要关心这个?

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

我想我可以通过检查Long.MIN_VALUE和Long.MAX_VALUE并记录“呃,我不能告诉你号码,但它真的是Long.XXX,相信我,我会对你撒谎吗?”但是当我发现这一点时,我觉得我的应用程序现在是建立在沙质地基上的,它需要非常健壮。我正认真考虑说JamVM不适合这个工作,并且用Python编写应用程序(因为读者也有一个Python运行时)。

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

更新

Noofiz让我思考(谢谢),我编写了这个附加的测试应用程序:

代码语言:javascript
复制
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, that was a close one

我将.class文件复制到有问题的设备中并运行它。

印出来了..。

...wait为它..。

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

哦,亲爱的。我觉得有点头晕,我想我需要一杯茶.

更新2

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

代码语言:javascript
复制
javac -source 1.4 -target 1.4 -bootclasspath classes.zip;glibj.zip -extdirs "" TestApp2.java

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

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2013-04-06 01:14:45

我写了JamVM。正如您可能猜到的,到现在为止,这样的错误已经被注意到了,而且JamVM甚至不会通过它们中最简单的测试套件( guess有自己的Mauve,而OpenJDK有jtreg)。我经常在ARM上运行( FX9500使用PXA270 ARM)和x86-64,但是各种平台都作为IcedTea的一部分进行测试。

所以我一点也不知道这里发生了什么。我想它只会影响Java长,因为它们很少使用,所以大多数程序都能工作。JamVM将handling映射为C long,因此我猜想用于构建JamVM的编译器在32位ARM上产生了长时间处理错误的代码。

不幸的是,如果您不能替换JVM,您就无能为力了(除了避免长时间之外)。您唯一能做的就是关闭JIT (一个简单的代码-复制JIT,也就是内联线程)。要做到这一点,请在命令行上使用-Xnoinlining,例如:

-Xnoinlining ..。

票数 5
EN

Stack Overflow用户

发布于 2013-04-05 09:13:54

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

代码语言:javascript
复制
public static long mod(long a, long b){
    long result = a % b;
    if (result < 0)
    {
        result += b;
    }
    return result;
}

此代码返回-2,而如下所示:

代码语言:javascript
复制
public static long mod2(long a, long b){
    long result = a % b;
    if (result > 0 && a < 0)
    {
        result -= b;
    }
    return result;
}

返回8。JamVM这么做的原因是我所理解的。

来自JLS:

15.17.3.剩余运算符% 对于二进制数字提升后为整数的操作数的剩余操作(§5.6.2)产生一个结果值,使得( a /b)*b+(a%b)等于a。

据此,JamVM中断了语言规范。非常糟糕。

票数 4
EN

Stack Overflow用户

发布于 2013-09-04 14:33:39

如果不是出于某种原因,我会发表评论的,这需要声誉。

长时间的否定在这个设备上不起作用。我不明白它的确切性质,但是如果你做了两个一元的小片段,你就会回到你开始的地方,例如x=10;-x==4294967286;-x==10. 4294967286非常接近Integer.MAX_VALUE*2 (2147483647*2 = 4294967294)。它甚至更接近Integer.MAX_VALUE*2-10!

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

实际上,在后者(比最新的版本) JamVM代码中,该bug已经修复:* https://github.com/ansoncat/jamvm/commit/736c2cb76baf1fedddc1eda5825908f5a0511373 * https://github.com/ansoncat/jamvm/commit/ac83bdc886ac4f6e60d684de1b4d0a5e90f1c489

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

FX9500实际上是一个重新打包的Sirit IN610,这意味着两个设备都共享这个bug。与摩托罗拉相比,Sirit更友好,并且正在提供固件升级,将在不久的将来推出。我希望摩托罗拉也会包括修复,虽然我不知道双方之间安排的细节。

无论是哪种方式,我们在FX9500上都有一个非常大的应用程序,而长时间的否定操作并没有被证明是一个无法逾越的障碍。

祝你好运丹。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/15828884

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档