1

私は 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はクラスパス エントリであることに注意してください。

問題は、jar が -bootclasspath オプション(!!)に入れられない限り、unity.jarコンパイル時にjavac が明らかにクラスを見つけられないため、コンパイルが失敗することです。

なぜこれが起こるのですか?私の知る限り、クラスの検索パスは階層的である必要があり、ブートクラスパスの後、javac はクラスパスを検索する必要があります...

gradle に jar を bootclasspath somhow に貼り付けるように指示することは可能ですか (これは不器用に問題を解決します)?

よりクリーンな/より良い方法はありますか?

洞察をありがとう!

4

1 に答える 1

1

編集:

詳しく調べてみると、それは機能しているように見えますclasspath(驚きです!) そして、Unity Technologies はミュータント クラスパスの回復力のある jar を作成しませんでした。結局のところ、これは世界を引き継ぐための最初のステップだからです...

問題はcompileステートメントへのパスにあり、それをjarへの正しい相対パスに置き換えた後、すべてが期待どおりに機能しました。

質問のポイントに対する答えは次のとおりです。

Q1: なぜこれが起こるのですか?

Java は存在しない jar 内のクラスを見つけることができないため

Q2: 何らかの方法で jar を bootclasspath に貼り付けるように gradle に指示することは可能ですか?

以下の回答を参照してください

Q3: よりクリーンな/より良い方法はありますか?

ええ:リンクしているものへのパスが正しいことを確認することは、良い出発点かもしれません:)

jargradle は、デバッグ モード (悪名高い IMHO) であっても、欠落している s に対してエラーを発行しないことに注意してください。


古い答え

どういうわけか、自分で問題を解決する必要がありました(私の回避策が最適だとは思いませんが、この質問に注意を払うと、うまくいくと思います...)

Q1: なぜこれが起こるのですか?

私が理解している限り、ひっくり返す理由はありません。

ドキュメント:

クラスの見つけ方 (Oracle canon)

ブートストラップのクラスが次のとおりであることを明確に指定します。

ブートストラップ クラスは、Java 2 プラットフォームを実装するクラスです。

つまり、プラットフォームの実装に使用されるクラスです。それがそこにある理由android.jarであり、unity.jar すべきではありません

Q2: 何らかの方法で jar を bootclasspath に貼り付けるように gradle に指示することは可能ですか?

はい!次のリンクでは、その方法について詳しく説明しています。

コンパイラ引数の bootclasspath を変更します (gradle フォーラム)

そしてそれは:

allprojects {
  gradle.projectsEvaluated {
    tasks.withType(JavaCompile) {
      options.compilerArgs << "Xbootclasspath/a:src/main/libs/unity.jar"
    }
  }
}

私のプロジェクトでは、私のAndroidライブラリのディレクトリにunity.jarあるAndroidアーカイブの後にアーカイブをロードすることにマップします。src/main/libs

Q3: よりクリーンな/より良い方法はありますか?

少なくとも、最初に jar をブートストラップにする必要がある理由を理解していなければ (これにより、ここでの問題のほとんどが無意味になります)、ブートストラップのクラスパスを変更することは、高レベルのプログラマーが行うべきことではありません。そのため、gradle がよりクリーンなショートカットを提供することは期待していません。

私はまだこの問題について何らかの洞察を持っている人を待っています (これ以上の時間を費やすことはできません) が、とにかくこれが誰かの助けになることを願っています.

于 2015-09-17T13:21:24.423 に答える