Я использовал Proguard с Maven для маскировки кода Java.Ошибка маскировки Proguard Maven с использованием выражений лямбда
меняю все функции от анонимного заявления на Lambda expression0, но после компиляции и запуска я получаю ошибку
2017-sty-20 08:53:46,289 ERROR [AWT-EventQueue-0] - Exception in thread "AWT-EventQueue-0"
2017-sty-20 08:53:46,289 ERROR [AWT-EventQueue-0] - java.lang.BootstrapMethodError: call site initialization exception
2017-sty-20 08:53:46,289 ERROR [AWT-EventQueue-0] - at java.lang.invoke.CallSite.makeSite(Unknown Source)
2017-sty-20 08:53:46,289 ERROR [AWT-EventQueue-0] - at java.lang.invoke.MethodHandleNatives.linkCallSiteImpl(Unknown Source)
2017-sty-20 08:53:46,289 ERROR [AWT-EventQueue-0] - at java.lang.invoke.MethodHandleNatives.linkCallSite(Unknown Source)
2017-sty-20 08:53:46,289 ERROR [AWT-EventQueue-0] - at com.goodsoft.stockbox.chart.f.c.h.a(ChartWindowPanel.java:50208)
2017-sty-20 08:53:46,289 ERROR [AWT-EventQueue-0] - at com.goodsoft.stockbox.commons.f.h.a.b.n(BaseWindowController.java:269)
2017-sty-20 08:53:46,289 ERROR [AWT-EventQueue-0] - at com.goodsoft.stockbox.commons.f.h.a.b.a(BaseWindowController.java:30)
2017-sty-20 08:53:46,289 ERROR [AWT-EventQueue-0] - at com.goodsoft.stockbox.commons.f.h.a.b$1.m(BaseWindowController.java:164)
2017-sty-20 08:53:46,289 ERROR [AWT-EventQueue-0] - at com.goodsoft.stockbox.commons.b.c.d$3.c(InstrumentController.java:324)
2017-sty-20 08:53:46,289 ERROR [AWT-EventQueue-0] - at java.awt.event.InvocationEvent.dispatch(Unknown Source)
2017-sty-20 08:53:46,289 ERROR [AWT-EventQueue-0] - at java.awt.EventQueue.dispatchEventImpl(Unknown Source)
2017-sty-20 08:53:46,289 ERROR [AWT-EventQueue-0] - at java.awt.EventQueue.access$500(Unknown Source)
2017-sty-20 08:53:46,289 ERROR [AWT-EventQueue-0] - at java.awt.EventQueue$3.run(Unknown Source)
2017-sty-20 08:53:46,289 ERROR [AWT-EventQueue-0] - at java.awt.EventQueue$3.run(Unknown Source)
2017-sty-20 08:53:46,289 ERROR [AWT-EventQueue-0] - at java.security.AccessController.doPrivileged(Native Method)
2017-sty-20 08:53:46,289 ERROR [AWT-EventQueue-0] - at java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(Unknown Source)
2017-sty-20 08:53:46,289 ERROR [AWT-EventQueue-0] - at java.awt.EventQueue.dispatchEvent(Unknown Source)
2017-sty-20 08:53:46,289 ERROR [AWT-EventQueue-0] - at java.awt.EventDispatchThread.pumpOneEventForFilters(Unknown Source)
2017-sty-20 08:53:46,289 ERROR [AWT-EventQueue-0] - at java.awt.EventDispatchThread.pumpEventsForFilter(Unknown Source)
2017-sty-20 08:53:46,289 ERROR [AWT-EventQueue-0] - at java.awt.EventDispatchThread.pumpEventsForHierarchy(Unknown Source)
2017-sty-20 08:53:46,289 ERROR [AWT-EventQueue-0] - at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
2017-sty-20 08:53:46,289 ERROR [AWT-EventQueue-0] - at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
2017-sty-20 08:53:46,289 ERROR [AWT-EventQueue-0] - at java.awt.EventDispatchThread.run(Unknown Source)
2017-sty-20 08:53:46,305 ERROR [AWT-EventQueue-0] - Caused by: java.lang.invoke.LambdaConversionException: Type mismatch for lambda argument 1: class com.goodsoft.stockbox.commons.model.c is not convertible to int
2017-sty-20 08:53:46,305 ERROR [AWT-EventQueue-0] - at java.lang.invoke.AbstractValidatingLambdaMetafactory.validateMetafactoryArgs(Unknown Source)
Интересный журнал ошибок:
Caused by: java.lang.invoke.LambdaConversionException: Type mismatch for lambda argument 1: class com.goodsoft.stockbox.commons.model.c is not convertible to int
... так что, может быть, нет никаких проблем с Lambdas, но с маскированными объектами, использующими лямбда?
Метод ДО изменения лямбда выглядит (отлично работает):
bidAskDiffChangeObserver = new BidAskDiffChangeObserver(instrument,
new IDiffValueChangeDelegate() {
@Override
public void valueChanged(int newValue, ValueChangeType type) {
mainRangeAxis.updateSpread(newValue);
}
});
... и ПОСЛЕ изменения в лямбда-выражения (не работают):
bidAskDiffChangeObserver = new BidAskDiffChangeObserver(instrument,
(newValue, type) -> mainRangeAxis.updateSpread(newValue));
It вызывается:
int newValue = computeBidAskDifference();
ValueChangeType type = previousValue > newValue ? ValueChangeType.DROP :
previousValue < newValue ? ValueChangeType.GROWTH : ValueChangeType.EQUAL;
if (delegate != null)
delegate.valueChanged(newValue, type);
Какой вариант я должен использовать для добавления лямбда-состояния?
Без маскировки все работает нормально (с опцией -dontoptimize
).
Мои варианты Proguard в pom.xml выглядеть следующим образом:
<plugin>
<groupId>com.github.wvengen</groupId>
<artifactId>proguard-maven-plugin</artifactId>
<version>2.0.10</version>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>proguard</goal>
</goals>
</execution>
</executions>
<configuration>
<injar>StockBox.jar</injar>
<outjar>StockBox.jar</outjar>
<options>
<option>-allowaccessmodification</option>
<option>-keepdirectories</option>
<option>-keep public class com.goodsoft.stockbox.Main { *; }</option>
<option>-keep public class * implements
com.goodsoft.stockbox.base.model.config.IConvertibleConfiguration
{ *;}
</option>
<option>-dontskipnonpubliclibraryclasses</option>
<option>-dontskipnonpubliclibraryclassmembers</option>
<option>-keepattributes RuntimeVisibleAnnotations</option>
<option>-keep @javax.persistence.* class * { *;}</option>
<option>-keepclassmembers enum * {
public static **[] values();
public static ** valueOf(java.lang.String);
}
</option>
<option>-keep @org.springframework.context.annotation.Configuration class *</option>
<option>-keep @org.springframework.beans.factory.annotation.Service class *</option>
<option>-keep @org.springframework.stereotype.Component class *</option>
<option>-keepclassmembers class * {
@org.springframework.beans.factory.annotation.Autowired *;
@org.springframework.beans.factory.annotation.Value *;
@org.springframework.context.annotation.Bean *;
}
</option>
<option>-adaptresourcefilecontents **.properties</option>
<option>-keepattributes
Exceptions,InnerClasses,Signature,Deprecated,SourceFile,LineNumberTable,*Annotation*,EnclosingMethod
</option>
</options>
<maxMemory>512m</maxMemory>
<libs>
<lib>${java.home}/lib/rt.jar</lib>
<lib>${java.home}/lib/jce.jar</lib>
</libs>
</configuration>
<dependencies>
<dependency>
<groupId>net.sf.proguard</groupId>
<artifactId>proguard-base</artifactId>
<version>${proguard.version}</version>
</dependency>
</dependencies>
</plugin>
EDIT
Я попытался добавить Maven варианты, как -optimizations !method/removal/parameter
и -optimizations !method/marking/static
, но не помогают.
Я не думаю, что есть опция «-donttrashmylambdas». Если Proguard знал о несовместимости преобразования кода с использованием лямбда, он не делал преобразования. Не зная больше о конкретном случае, определить проблему невозможно. Поэтому я делаю только одно предположение: возможно ли, что Proguard превращает методы экземпляра в методы 'static', если они не используют' this'? – Holger
Может, мне не стоит оглядываться вокруг лямбда, но добавить свой вариант? Поскольку ошибка говорит: «Вызывается: java.lang.invoke.LambdaConversionException: несоответствие типов для аргумента лямбда 1: класс com.goodsoft.stockbox.commons.model.c не конвертируется в int, поэтому он не может читать объект из commons.model , Невозможно преобразовать объект маски в int. Какие-либо предложения? – ACz
Это не имеет ничего общего с объектами, это только проверка * типов *. Существует сигнатура типа, состоящая из «фиксированных значений (если есть) + функциональная подпись» и сигнатуры типа, состоящей из «типа приемника (если не« статического ») + параметров целевого метода». Оба должны совпадать, и обычно переименование не влияет. Но в случае, если Proguard изменил метод экземпляра на 'static', его тип приемника исчезнет из подписи и вызовет несоответствие.Я не знаю, делает ли Proguard такое преобразование, но если это так, отключив его, стоит попробовать. – Holger