5

我正在增强一个客户,这是一个更大项目的一部分。由于缺乏速度,我被迫切换到 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(版本 1.4.3)库(和其他必需的 *.jar)。这似乎也适用于所有其他图书馆。(我的操作系统=Ubuntu)

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

编辑:

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

4

3 回答 3

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>
于 2013-12-22T23:39:11.653 回答
0

我认为您在选择实现平台时犯了几个错误:

  • 您可能不需要为了“速度”而竭尽全力在本机代码中实现东西。对于大多数事情,您可以在 Jana 中获得与本地代码大致相当的速度,尤其是当您花时间分析和优化 Java 代码时。

  • 假设你这样做了,CNI 是一个糟糕的选择。使用 JNI 或 JNA 会更好,这两者都允许您使用 Oracle HotSpot / OpenJDK 版本。

  • GCJ 是一个糟糕的选择,因为(正如您所观察到的)有些东西不起作用,而且调试更加困难。(另请参阅GNU 的 Java 编译器 (GCJ) 死了吗?

  • 依赖一个你无法获得源代码的库是不幸的。

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

于 2012-10-21T14:13:02.367 回答
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 的文件内容分配给 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 文件的内容。如果您的文件内容与我的不同 -> 改为使用您的。

最好的问候,克里斯

于 2012-10-24T14:34:46.583 回答