JarJar не переименовывает ссылки
Я использую jarjar от Google для переупаковки зависимостей в толстый jar моего приложения. При запуске переупакованной банки, я получаю NoClassDefFoundError
например:
Exception in thread "main" java.lang.NoClassDefFoundError: ch/qos/logback/classic/LoggerContext
Caused by: java.lang.ClassNotFoundException: ch.qos.logback.classic.LoggerContext
Я декомпилировал перепакованный jar и увидел, что ссылки на зависимости в операторах импорта и в моем коде не были реорганизованы. Куда я иду не так?
Вот как я запускаю jarjar:
java -jar jarjar-1.4.jar process repackageRules.txt myApp.jar app_repackaged.jar
Правила, которые я перечислил в repackageRules.txt:
rule javassist.** company.@0
rule org.eclipse.** company.@0
rule ch.qos.** company.@0
rule com.fasterxml.** company.@0
rule biz.paluch.** company.@0
Мой build.gradle:
/* Gradle version: 3.0 */
apply plugin: 'java'
apply plugin: 'jacoco'
group='com.company'
version=0.1
repositories {
jcenter()
}
dependencies {
compile group: 'org.javassist', name: 'javassist', version: '3.20.0-GA'
compile group: 'ch.qos.logback', name: 'logback-classic', version: '1.1.7'
compile group: 'com.fasterxml.jackson.core', name: 'jackson-databind', version: '2.8.6'
compile group: 'org.eclipse.jdt', name: 'org.eclipse.jdt.core', version: '3.12.2'
compile 'biz.paluch.logging:logstash-gelf:1.11.0'
testCompile 'junit:junit:4.12'
}
// Create jar with manifest as described
jar {
manifest {
attributes ('Premain-Class': 'com.company.instrumentation.Agent',
'Can-Redefine-Classes': true,
'Can-Retransform-Classes': true,
'Can-Set-Native-Method-Prefix': true,
'Main-Class': 'com.company.Main')
}
}
//create a single Jar with all dependencies
task fatJar(type: Jar) {
manifest.from jar.manifest
classifier = 'all'
from {
configurations.compile.collect { it.isDirectory() ? it : zipTree(it) }
} {
// to prevent duplicate files in jar
exclude "META-INF/*"
exclude '.api_description'
exclude '.options'
exclude '*.html'
exclude 'plugin.properties'
exclude 'plugin.xml'
exclude 'about_files/*'
}
with jar
}
Я попытался проверить, правильно ли jarjar определяет зависимости между классами, используя java -jar jarjar-1.4.jar find class myApp.jar
И я получаю такие ошибки для всех классов в моем коде: Error reading com/company/Main.class: null
Что вызывает эту проблему?
1 ответ
Ошибка вызвана тем, что JarJar использует ASM 4.0, который не поддерживает байт-код JDK 8. Эту проблему можно решить, построив этот форк JarJar, модифицированный для использования ASM 5.0.