除非 .jar 包含在 bootclasspath 中,否则无法编译
Unable to compile unless .jar is included in bootclasspath
我正在尝试使用 gradle 构建一个 android 项目:这是一个带有 ndk 风格的库项目,带有外部 .jar
,由 Unity 提供。
我真的不认为 gradle 文件的详细信息很重要,只要说我将外部 jar 文件(由 Unity 提供)包含在其中就足够了:
dependencies {
compile files('libs/unity.jar')
}
实际上似乎有效,因为在 java 编译期间,gradle 发出如下命令:
BASE="<Some directory>"
javac -d "${BASE}/PluginsSources/Android/libproject/build/intermediates/classes/fat/debug" \
-g -encoding UTF-8 \
-bootclasspath /Users/myusername/Applications/adt/sdk/platforms/android-23/android.jar \
-sourcepath "${BASE}/PluginsSources/Android/libproject/build/tmp/compileFatDebugJavaWithJavac/emptySourcePathRef" \
-classpath "${BASE}/PluginsSources/Android/libproject/libs/unity.jar" \
"${BASE}/PluginsSources/Android/libproject/src/main/java/org/example/ScriptBridge/JavaClass.java" \
"${BASE}/PluginsSources/Android/libproject/build/generated/source/r/fat/debug/org/example/ScriptBridge/R.java" \
"${BASE}/PluginsSources/Android/libproject/build/generated/source/buildConfig/fat/debug/org/example/ScriptBridge/BuildConfig.java" \
-XDuseUnsharedTable=true
缩进和BASE
变量是您真正添加的。请注意,unity.jar
是一个 class 路径条目。
问题是,编译失败,因为 javac 在编译时显然无法在 unity.jar
中找到 class,除非那个 jar 被放入-bootclass路径选项 (!!).
为什么会这样? AFAIK,classes 的搜索路径应该是分层的,在启动 classpath 之后,javac 应该搜索 classpath...
是否可以告诉 gradle 将一些 jar 插入引导classpath somhow(这会笨拙地解决问题)?
有cleaner/better方法吗?
感谢您的任何见解!
编辑:
仔细检查后,看起来 classpath
有效(惊喜!)并且 Unity Technologies 没有创建变体-class路径弹性 jar,因为它是接管的第一步毕竟这个世界...
问题出在 compile
语句的路径中,在用正确的 jar 相对路径替换它之后,一切都按预期工作。
问题的答案是:
Q1:为什么会出现这种情况?
因为java无法在不存在的jar中找到class
问题 2:是否可以告诉 gradle 将一些 jar 粘贴到引导程序中 classpath somhow?
查看下面的答案
Q3:有cleaner/better方法吗?
是的:确保您 linking 的路径是正确的可能是一个好的开始:)
请注意,gradle 不会因缺少 jar
s 而发出任何错误,即使是在调试模式下(这是一个臭名昭著的恕我直言)。
旧答案
我必须以某种方式自己解决这个问题(我不认为我的解决方法是最佳的,但考虑到对这个问题的关注,我想它已经很好了...)
Q1:为什么会出现这种情况?
据我了解,没有翻转的原因。
文档:
How Classes are Found (Oracle canon)
明确指出bootstrap中的class是:
Bootstrap classes are the classes that implement the Java 2 Platform.
即用于实现平台的 classes。这就是为什么 android.jar
在那里,而 unity.jar
不应该 .
问题 2:是否可以告诉 gradle 将一些 jar 粘贴到 bootclasspath somhow 中?
是的!以下 link 详细说明:
Modify bootclasspath in compiler args (gradle forums)
那就是:
allprojects {
gradle.projectsEvaluated {
tasks.withType(JavaCompile) {
options.compilerArgs << "Xbootclasspath/a:src/main/libs/unity.jar"
}
}
}
在我的项目中,它映射到在 android 之后加载一个 unity.jar
存档,位于我的 android 库的 src/main/libs
目录中。
Q3:有cleaner/better的方法吗?
我不这么认为,至少在不理解为什么 jar 首先需要放在 bootstrap 中(这会使这里的大部分问题变得毫无意义):改变 bootstrap class路径不是高级程序员应该做的事情,所以我不希望gradle提供更简洁的快捷方式。
我仍在等待对这个问题有一些见解的人(我不能在这上面花费更多的时间),但我希望这无论如何都会对某人有所帮助。
我正在尝试使用 gradle 构建一个 android 项目:这是一个带有 ndk 风格的库项目,带有外部 .jar
,由 Unity 提供。
我真的不认为 gradle 文件的详细信息很重要,只要说我将外部 jar 文件(由 Unity 提供)包含在其中就足够了:
dependencies {
compile files('libs/unity.jar')
}
实际上似乎有效,因为在 java 编译期间,gradle 发出如下命令:
BASE="<Some directory>"
javac -d "${BASE}/PluginsSources/Android/libproject/build/intermediates/classes/fat/debug" \
-g -encoding UTF-8 \
-bootclasspath /Users/myusername/Applications/adt/sdk/platforms/android-23/android.jar \
-sourcepath "${BASE}/PluginsSources/Android/libproject/build/tmp/compileFatDebugJavaWithJavac/emptySourcePathRef" \
-classpath "${BASE}/PluginsSources/Android/libproject/libs/unity.jar" \
"${BASE}/PluginsSources/Android/libproject/src/main/java/org/example/ScriptBridge/JavaClass.java" \
"${BASE}/PluginsSources/Android/libproject/build/generated/source/r/fat/debug/org/example/ScriptBridge/R.java" \
"${BASE}/PluginsSources/Android/libproject/build/generated/source/buildConfig/fat/debug/org/example/ScriptBridge/BuildConfig.java" \
-XDuseUnsharedTable=true
缩进和BASE
变量是您真正添加的。请注意,unity.jar
是一个 class 路径条目。
问题是,编译失败,因为 javac 在编译时显然无法在 unity.jar
中找到 class,除非那个 jar 被放入-bootclass路径选项 (!!).
为什么会这样? AFAIK,classes 的搜索路径应该是分层的,在启动 classpath 之后,javac 应该搜索 classpath...
是否可以告诉 gradle 将一些 jar 插入引导classpath somhow(这会笨拙地解决问题)?
有cleaner/better方法吗?
感谢您的任何见解!
编辑:
仔细检查后,看起来 classpath
有效(惊喜!)并且 Unity Technologies 没有创建变体-class路径弹性 jar,因为它是接管的第一步毕竟这个世界...
问题出在 compile
语句的路径中,在用正确的 jar 相对路径替换它之后,一切都按预期工作。
问题的答案是:
Q1:为什么会出现这种情况?
因为java无法在不存在的jar中找到class
问题 2:是否可以告诉 gradle 将一些 jar 粘贴到引导程序中 classpath somhow?
查看下面的答案
Q3:有cleaner/better方法吗?
是的:确保您 linking 的路径是正确的可能是一个好的开始:)
请注意,gradle 不会因缺少 jar
s 而发出任何错误,即使是在调试模式下(这是一个臭名昭著的恕我直言)。
旧答案
我必须以某种方式自己解决这个问题(我不认为我的解决方法是最佳的,但考虑到对这个问题的关注,我想它已经很好了...)
Q1:为什么会出现这种情况?
据我了解,没有翻转的原因。
文档:
How Classes are Found (Oracle canon)
明确指出bootstrap中的class是:
Bootstrap classes are the classes that implement the Java 2 Platform.
即用于实现平台的 classes。这就是为什么 android.jar
在那里,而 unity.jar
不应该 .
问题 2:是否可以告诉 gradle 将一些 jar 粘贴到 bootclasspath somhow 中?
是的!以下 link 详细说明:
Modify bootclasspath in compiler args (gradle forums)
那就是:
allprojects {
gradle.projectsEvaluated {
tasks.withType(JavaCompile) {
options.compilerArgs << "Xbootclasspath/a:src/main/libs/unity.jar"
}
}
}
在我的项目中,它映射到在 android 之后加载一个 unity.jar
存档,位于我的 android 库的 src/main/libs
目录中。
Q3:有cleaner/better的方法吗?
我不这么认为,至少在不理解为什么 jar 首先需要放在 bootstrap 中(这会使这里的大部分问题变得毫无意义):改变 bootstrap class路径不是高级程序员应该做的事情,所以我不希望gradle提供更简洁的快捷方式。
我仍在等待对这个问题有一些见解的人(我不能在这上面花费更多的时间),但我希望这无论如何都会对某人有所帮助。