【问题标题】:Prevent dex core-library error for xalan with gradle 2.0.0使用 gradle 2.0.0 防止 xalan 的 dex 核心库错误
【发布时间】:2016-08-13 15:06:57
【问题描述】:

我尝试使用 gradle 2.0.0(gradle wrapper 2.10)让 xalan 2.7.2 与 Android 一起工作

我已将 xalan 2.7.2 和 tagsoup 1.2.1 添加到我的 gradle 依赖项中,以便从草率的 HTML 源中获取有效的 SAX2DOM 文档

但是:如果我为此设置运行 gradle 构建,我会立即收到错误:

Ill advised or mistaken usage of a core class (java.* or javax.*)
when not building a core library.
This is often due to inadvertently including a core library file
in your application's project, when using an IDE (such as
Eclipse).
[...]
If you really intend to build a core library -- which is only
appropriate as part of creating a full virtual machine
distribution, as opposed to compiling an application -- then use
the "--core-library" option to suppress this error message.

所以我尝试这样做,但在实现 --core-library 选项的过程中发现,只有 gradle 1.3.0(和 gradle wrapper 2.2)才有可能

然后这一切都与应用程序的 build.gradle 中的这些选项一起工作:

dexOptions {
   preDexLibraries = false
}

project.tasks.withType(com.android.build.gradle.tasks.Dex) {
   additionalParameters = ['--core-library']
}

我一直认为并希望对此有另一种更好的解决方案。

但是现在我真的很想摆脱这种开销,因为我想利用新的 Android Studio 2.0 功能,例如 Instant Run,它只能与 gradle 2.0.0 一起使用

所以我的问题是:在 Android 中使用像 xalan (SAX2DOM) 这样的库以及最新版本的 gradle 的正确方法是什么?

编辑:我发现它更多的是关于 xalan 而不是 tagsoup(因为 xalan 似乎依赖于 javax.xml.XMLConstants),所以我相应地编辑了问题

EDIT2:根本原因似乎是从 xalan 通过 xalan-serializer 到 xml-apis 的传递依赖。这是gradlew app:dependencies 显示的内容:

+--- xalan:xalan:2.7.2
|    \--- xalan:serializer:2.7.2
|         \--- xml-apis:xml-apis:1.3.04

xml-apis-1.3.04.jar 实际上包含 javax.xml.* 类

当前的问题是:如何将这些类包含到我的项目中,避免当前 gradle 版本的核心库问题?

EDIT3:我似乎无法正常工作。

使用 jarjar 重新打包 xml-apis、xalan-serializer 和 xalan jar 后,我将生成的 jar 文件放入项目的 libs 文件夹(我也将其包含在我的 gradle 依赖项中进行编译)。

不过,Xalan 对 xercesImpl 有另一个 可选 依赖项,该依赖项在运行时使用,因此我必须将其添加为依赖项。

但是这个 jar 似乎很旧,所以我在 gradle 构建期间从它那里得到了 ParseErrors。

其他消息来源建议从源代码重新编译 xerces,但在包含重建的 xerces jar 后,我只得到 bad class file magic (cafebabe) 异常 ....

我暂时放弃

【问题讨论】:

    标签: android android-gradle-plugin dex xalan


    【解决方案1】:

    真的不想使用 --core-library 选项。根据警告:“这仅适合作为创建完整虚拟机的一部分 分发,而不是编译应用程序”。您不是在构建“完整的虚拟机分发”,而是在编译应用程序。

    我认为这里真正的解决方案是要么

    1. 找出哪些java.*/javax.* 类正在编译到您的应用程序中,并防止它们被编译

    1. 如果您确实需要将这些类编译到您的应用程序中,请使用 jarjar 之类的东西将它们重命名为 java.*/javax.* 以外的其他名称

    【讨论】:

    • 请问为什么?我正在使用 joda-time、xalan、jackson-databind 和 tagoup 等库。如何找出这些库中的哪些正在使用 java*:* 类?
    • 您是否真的阅读了 dx 给出的完整警告? :) 它不遗余力地告诉您为什么在构建应用程序时不应该使用 --core-library。它甚至为您提供有关如何正确处理这种情况的信息,这与我在回答中提供的建议基本相符。
    • 不仅使用 java.* 类,而且实际上将它们作为 jar 的一部分。只需在文件系统上找到实际的 jar 文件,然后查看其中包含哪些类。
    • 这可能是一个传递依赖,我在我的项目中找不到任何具有 java.* 或 javax.* 类的 jar
    • 请参阅我的问题的EDIT2 ...我希望你能帮助我。从有关此问题的问题数量中猜测,这对许多其他用户也可能有很大的好处
    【解决方案2】:

    解决方案(至少大部分)非常简单,并在这篇 Android 博客文章中提到:http://jmlinnik.blogspot.de/2015/07/android-studio-android-ill-advised-or.html

    compile ('xalan:xalan:2.7.2') {
        exclude group: 'xml-apis'
    }
    

    显然,来自 xml-apis 的类已经包含在 Android 中,因此没有必要(甚至错误)将它们包含在这种传递依赖中。

    但是:使用 gradle 1.5.0 构建应用程序,在删除上述 dex 选项后,会产生很多警告,例如

    警告:忽略匿名内部类的 InnerClasses 属性 (org.apache.xml.serializer.SecuritySupport$1) 不附带 关联的 EnclosureMethod 属性。这堂课大概是 由不针对现代 .class 文件的编译器生成 格式。推荐的解决方案是从 源,使用最新的编译器并且不指定任何 “-target”类型选项。忽略此警告的后果是 此类上的反射操作将错误地指示 它不是一个内部类。

    在 gradle 2.0.0 中,这些警告变成了错误,但 apk 仍在正确构建

    错误:警告:忽略匿名内部的 InnerClasses 属性 类(org.apache.xpath.functions.SecuritySupport$8) 没有关联的 EnclosureMethod 属性。这 类可能是由没有针对的编译器生成的 现代 .class 文件格式。推荐的解决方案是 使用最新的编译器从源代码重新编译类 并且没有指定任何“-target”类型选项。这 忽略此警告的后果是反思 对此类的操作将错误地指示它是 不是内部类。

    :app:validateDebugSigning

    :app:packageDebug

    :app:zipalignDebug

    :app:fullDebugBuildInfoGenerator

    :app:assembleDebug

    信息:构建成功

    这似乎是一个错误,我希望尽快修复。

    【讨论】:

    • 这些警告不是错误。问题可能是 xalan 类的目标是非常旧的 java 版本(可能
    • 我提到了一个错误,因为曾经有警告现在被标记为不影响构建过程的错误?这似乎是一个错误,因为每个错误通常都会导致构建过程失败
    猜你喜欢
    • 1970-01-01
    • 2010-10-24
    • 1970-01-01
    • 2012-12-08
    • 2023-04-01
    • 2014-03-31
    • 1970-01-01
    • 1970-01-01
    • 2016-02-26
    相关资源
    最近更新 更多