用gcj编译java& XStream的。 (例外:无法创建XmlPullParser)

时间:2012-10-21 13:25:57

标签: java xstream xmlpullparser compiled gcj

我正在增强一个客户,这是一个更大的项目的一部分。由于速度不足,我被迫切换到CNI,因此我必须使用GNU-gcj编译器生成本机代码(gnu 4.6.3)。

编译和链接工作正常(感谢-findirect-dispatch标志),我在执行输出时没有任何问题。 但是当涉及到客户端和服务器之间的通信时,客户端会立即断开连接。原因是:

  

[XStreamClient Reader] WARN - 客户端断开连接(例外:   com.thoughtworks.xstream.io.StreamException:无法创建   XmlPullParser)

(此Exeption仅出现在客户端的gcj编译版本中。当我使用java解释器运行代码时 - 事情运行良好(但速度太慢^^)) - >具有挑战性的部分是我无法检索发生此异常的源代码,因为它位于客户端使用的预编译(Java类文件)库中。 (我无法联系该图书馆的作者)

我想库会调用XppReader然后尝试创建一个XmlPullParser类并失败。

我通过解压缩它们并编译创建的* .class文件然后链接目标文件来绑定XStream(vers.1.4.3)库(以及其他必需的* .jars)。这似乎也适用于所有其他图书馆。 (我的OS = Ubuntu)

我已经做了什么来克服这个问题: 我搜索了XStream / XmlPullParser和gcj,并用不同版本替换了“xmlpull” - 和“kxml2”文件。 但没有任何效果。 你们中的任何人都知道可能是什么解决方案吗?

编辑:

我发现XmlPullParser创建失败的原因是XmlPullParserFactory.newInstance函数无法找到带有/services/org.xmlpull.v1.XmlPullParserFactory文件的META-INF目录。 这是因为我只编译并链接了* .jar的* .class文件。 因此,只要我找到了将META-INF目录链接到该函数可以找到并访问它的可执行文件的方法,就应该解决问题。 你们中的任何人都知道这样做吗?

3 个答案:

答案 0 :(得分:3)

我认为xmlpull需要一个可以使用xpp3作为其实现的实现。 请将以下代码添加到您的pom.xml中,如果需要,请将这些jar文件添加到需要它们的软件中。

<dependency>
    <groupId>xmlpull</groupId>
    <artifactId>xmlpull</artifactId>
    <version>1.1.3.1</version>
</dependency>
<dependency>
    <groupId>xpp3</groupId>
    <artifactId>xpp3</artifactId>
    <version>1.1.3.3</version>
</dependency>

答案 1 :(得分:0)

我认为您在实施平台选择中犯了一些错误:

  • 您可能不需要在本机代码中“实现速度”的实现。对于大多数事情,您可以在Jana中获得与本机代码大致相当的速度,特别是如果您花时间分析和优化Java代码。

  • 假设你做到了,CNI是一个糟糕的选择。您最好使用JNI或JNA,这两种方法都允许您使用Oracle HotSpot / OpenJDK版本。

  • GCJ是一个糟糕的选择,因为(正如你所观察到的)有些东西不起作用,调试也比较困难。 (另见Is GNU's Java Compiler (GCJ) dead?

  • 依赖于您无法获取源代码的库是不幸的。

我的建议是重新审视尽可能多的“失误”。

答案 2 :(得分:0)

正如我已编辑到我的问题中,创建失败的原因是XmlPullParserFactory.newInstance方法无法使用以下行访问/META-INF/services/org.xmlpull.v1.XmlPullParserFactory文件代码:

InputStream is = context.getResourceAsStream (RESOURCE_NAME);

(RESOURCE_NAME等于“/ META-INF/services/org.xmlpull.v1.XmlPullParserFactory”)

我必须承认,我没有找到一种方法将所需的META-INF目录绑定到可执行文件中,这可能是最优雅的解决方案之一。 但由于XmlPullParserFactory.java文件(和XStream库)是开源的,你只需要在上面的源文件中添加一行代码并用新的类替换旧类 - 就是这样。

public static XmlPullParserFactory newInstance (String classNames, Class context)函数中,程序只想在classNames == null时读取RESOURCE_NAME文件。 因此,我们要做的是避免这种情况,即我们自己将RESOURCE_NAME的文件内容分配给classNames变量,并且对于那个位置,这行代码高于if (classNames == null || classNames.length() == 0 || "DEFAULT".equals(classNames))语句:

classNames = "org.xmlpull.mxp1.MXParser,org.xmlpull.mxp1_serializer.MXSerializer";

“org.xmlpull.mxp1.MXParser,org.xmlpull.mxp1_serializer.MXSerializer”是我的RESOURCE_NAME文件的内容。如果您的文件内容与我的不同 - &gt;把它放进你的。

最好的问候,克里斯