我使用的是一个摩托罗拉FX9500射频识别读取器,它运行Linux1.5.0版本(我只能将应用程序部署到它--我不能更改Java或任何限制我的选项)--下面是我在检查版本时看到的:
[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上,因此它具有以下版本:
C:\>javac -version
javac 1.5.0考虑到我用那个编译器编译的应用程序在上述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);
}
}用前面提到的javac编译器编译它,并在PC上运行它,如下所示:
C:\>javac TestApp.java
C:\>java TestApp
8那里一切都很好。生活是美好的,所以我把这个.class文件放在FX9500上,然后按如下方式运行:
[cliuser@FX9500D96335 ~]$ /usr/bin/jamvm TestApp
-2Eek,您可以看到什么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让我思考(谢谢),我编写了这个附加的测试应用程序:
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上,然后像这样进行交叉编译(这一定意味着编译的文件应该很好,对吧?)
javac -source 1.4 -target 1.4 -bootclasspath classes.zip;glibj.zip -extdirs "" TestApp2.java但是,当在读取器上运行时,生成的.class文件会打印相同的消息。
发布于 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 ..。
发布于 2013-04-05 09:13:54
问题在于不同的模数实现:
public static long mod(long a, long b){
long result = a % b;
if (result < 0)
{
result += b;
}
return result;
}此代码返回-2,而如下所示:
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中断了语言规范。非常糟糕。
发布于 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上都有一个非常大的应用程序,而长时间的否定操作并没有被证明是一个无法逾越的障碍。
祝你好运丹。
https://stackoverflow.com/questions/15828884
复制相似问题