Android Studio)には、Gradle(src/org/luaj/vm2/lib/jse/JavaMethod.Java
)を介してプルされたパッケージから上書きする必要がある特定のファイル(dependencies {compile 'org.luaj:luaj-jse:3.0.1'}
)があります。
まったく同じパスでファイルをソースディレクトリにコピーし、変更を加えました。これは、それを使用していた個々のJUnitテストケースでは正常に機能していました。また、は私のプロジェクトの通常のコンパイルで機能しているように見えます(現時点では簡単に確認できません)。
ただし、ProjectType = "Android Tests"の構成を使用してすべてのテストを一度に実行しようとすると、Error:Error converting bytecode to dex: Cause: com.Android.dex.DexException: Multiple dex files define Lorg/luaj/vm2/lib/jse/JavaMethod$Overload;
が表示されます。
プロジェクトがローカルソースディレクトリ内のファイルを確実に選択するために、Gradleファイルに追加する必要のある特定のタスクまたはコマンドはありますか? コピータスク とsourceSets->main->Java->exclude
コマンドを試しましたが、どちらも機能していないようです(間違って行った可能性があります)。また、「コンパイル」の下にある「モジュール/グループを除外」ディレクティブを この投稿 から試しました。
実行/デバッグ確認のデフォルト以外の設定:
私のすべてのJUnitテストケースは「テスト」パッケージに含まれています。
これを機能させるどんな答えでも問題ありません。 Gradleでない場合は、おそらくAndroidマニフェストまたはローカルソースファイル自体に何かがあります。
[2016-07-24に編集]エラーは、normalコンパイルでも発生しています(私のAndroidエミュレーターはより低いAPIを実行しています。API16および19はエラーになりますが、API23はエラーになりません。
これは、Fabioの提案の後に私が追加したものです:
//Get LUAJ
buildscript { dependencies { classpath 'de.undercouch:gradle-download-task:3.1.1' }}
apply plugin: 'de.undercouch.download'
task GetLuaJ {
//Configure
def JARDownloadURL='http://central.maven.org/maven2/org/luaj/luaj-jse/3.0.1/luaj-jse-3.0.1.jar' //compile 'org.luaj:luaj-jse:3.0.1'
def BaseDir="$projectDir/luaj"
def ExtractToDir='class'
def ConfirmAlreadyDownloadedFile="$BaseDir/$ExtractToDir/lua.class"
def JarFileName=JARDownloadURL.substring(JARDownloadURL.lastIndexOf('/')+1)
def ClassesToDeleteDir="$BaseDir/$ExtractToDir/org/luaj/vm2/lib/jse"
def ClassNamesToDelete=["JavaMethod", "LuajavaLib"]
//Only run if LuaJ does not already exist
if (!file(ConfirmAlreadyDownloadedFile).exists()) {
//Download and extract the source files to /luaj
println 'Setting up LuaJ' //TODO: For some reason, print statements are not working when the "copy" directive is included below
mkdir BaseDir
download {
src JARDownloadURL
dest BaseDir
}
copy {
from(zipTree("$BaseDir/$JarFileName"))
into("$BaseDir/$ExtractToDir")
}
//Remove the unneeded class files
ClassNamesToDelete=ClassNamesToDelete.join("|")
file(ClassesToDeleteDir).listFiles().each {
if(it.getPath().replace('\\', '/').matches('^.*?/(?:'+ClassNamesToDelete+')[^/]*\\.class$')) {
println "Deleting: $it"
it.delete()
}
}
}
}
後でjarで直接動作するバージョンをアップロードします。
問題:アプリをリンクすると、リンカーは2つのバージョンを見つけます
修正方法:gradleにexclude org.luaj:luaj-jse:3.0.1:org.luaj.vm2.lib.jse.JavaMethodをビルドから指示する
Android {
packagingOptions {
exclude '**/JavaMethod.class'
}
}
私はこれを「excludeclass」で試していませんが、「COPYING」で重複するgplライセンスファイルを削除するために機能します。
この「除外」が機能しない場合は、
私はあなたの問題を完全に理解しているとは思いません。ただし、これはクラスパスの順序の問題のように聞こえますが、実際にはファイルが問題を上書きするわけではありません。
AFAIK、gradleは、「依存関係」セクションからの注文に対して「保証」を行いません。ただし、繰り返し可能になることを除けば。カスタマイズするファイルのバージョンをコンパイルするときに、テスト/システムでそのファイルを使用できるようにするには、複製元のjarファイルよりもクラスパスの前にある必要があります。
幸い、gradleを使用すると、クラスパスの前に「追加」する非常に簡単な方法が可能になります。
sourceSets.main.compileClasspath = file("path/to/builddir/named/classes") + sourceSets.main.compileClasspath
私はあなたのシステムについてそれをよりよく定義するのに十分なことを知りません。ただし、ニーズに合わせて簡単にカスタマイズできるはずです。つまり、必要に応じて、「コンパイル」を他のクラスパス(runtime、testRuntimeなど)の1つに変更できます。また、それがより良い解決策である場合は、classesディレクトリではなく作成するjarfileを指定できます。最適ではないかもしれませんが、クラスパス定義で2回指定することはかなり無害であることを覚えておいてください。
これはかなり複雑ですが、技術的には実現可能です。しかし、ポスターが尋ねたように、それは単一のタスクではありません:
./gradlew dependencies
を使用して確認してください)Linux/Macを使用していると想定しても安全な場合は、項目3で簡単なコマンドラインを実行できます。これは、広く利用可能なコマンドのみを使用しています。
mkdir newFolder ; cd newFolder ; jar xf $filename ; rm $offendingFilePath
自動依存関係管理を気にしない場合は、curlを使用してjarファイルをダウンロードできます。これはLinuxとMacの両方で広く利用できると思います。
curl http://somehost.com/some.jar -o some.jar
より堅牢な実装のために、このような単純なコマンドラインをgroovy/Javaコードに置き換えることができます。 GradleはGroovyのスーパーセットと見なすことができることを知っているのは興味深いことです。これは、ほとんどの点でJavaのスーパーセットであると言えます。つまり、Java/GroovyコードをGradleのほぼどこにでも配置できます。 .buildファイル。クリーンではありませんが、効果的であり、単なる別のオプションです。
4の場合、どちらかに沿って何かを持つことができます
sourceSets.main.Java.srcDirs += ["newFolder/class"]
build.gradleのルートレベル、または
dependencies {
. . .
compile fileTree(dir: 'newFolder', include: ['*.class'])
. . .