2017-01-20 2 views
1

Я использовал 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, но не помогают.

+0

Я не думаю, что есть опция «-donttrashmylambdas». Если Proguard знал о несовместимости преобразования кода с использованием лямбда, он не делал преобразования. Не зная больше о конкретном случае, определить проблему невозможно. Поэтому я делаю только одно предположение: возможно ли, что Proguard превращает методы экземпляра в методы 'static', если они не используют' this'? – Holger

+0

Может, мне не стоит оглядываться вокруг лямбда, но добавить свой вариант? Поскольку ошибка говорит: «Вызывается: java.lang.invoke.LambdaConversionException: несоответствие типов для аргумента лямбда 1: класс com.goodsoft.stockbox.commons.model.c не конвертируется в int, поэтому он не может читать объект из commons.model , Невозможно преобразовать объект маски в int. Какие-либо предложения? – ACz

+0

Это не имеет ничего общего с объектами, это только проверка * типов *. Существует сигнатура типа, состоящая из «фиксированных значений (если есть) + функциональная подпись» и сигнатуры типа, состоящей из «типа приемника (если не« статического ») + параметров целевого метода». Оба должны совпадать, и обычно переименование не влияет. Но в случае, если Proguard изменил метод экземпляра на 'static', его тип приемника исчезнет из подписи и вызовет несоответствие.Я не знаю, делает ли Proguard такое преобразование, но если это так, отключив его, стоит попробовать. – Holger

ответ

1

решаемые

Существует проблема с оптимизацией меняющегося перечислений в целое.

Просто отключите эту оптимизацию и отлично работайте.

<option>-optimizations !class/unboxing/enum</option>