【问题标题】:Using Proguard with a library has a @Service bean which should autowire将 Proguard 与库一起使用有一个 @Service bean,它应该自动装配
【发布时间】:2010-12-10 17:39:37
【问题描述】:

我有一个库 Common.License,我用 Proguard 混淆了它:

<plugin>
    <groupId>com.pyx4me</groupId>
    <artifactId>proguard-maven-plugin</artifactId>
    <executions>
        <execution>
            <phase>package</phase>
            <goals>
                <goal>proguard</goal>
            </goals>
        </execution>
    </executions>
    <configuration>
        <obfuscate>true</obfuscate>
        <options>
            <option>-dontoptimize</option>
            <option>-renamesourcefileattribute SourceFile</option>
            <option>-keepattributes Exceptions,InnerClasses,Signature,Deprecated,SourceFile,LineNumberTable,*Annotation*,EnclosingMethod</option>
            <option>-keep public class * { public protected *;}</option>
            <option>-keepclassmembernames class * {java.lang.Class class$(java.lang.String); java.lang.Class class$(java.lang.String, boolean);}</option>
            <option>-keepclassmembernames class * {com.common.license.LicenseSessionStore licenseSessionStore; com.common.license.LicenseStore licenseStore;}</option>
            <option>-keepclassmembers enum * {public static **[] values(); public static ** valueOf(java.lang.String);}</option>
            <option>-keepclassmembers class * implements java.io.Serializable { static final long serialVersionUID; private static final java.io.ObjectStreamField[] serialPersistentFields; private void writeObject(java.io.ObjectOutputStream); private void readObject(java.io.ObjectInputStream); java.lang.Object writeReplace(); java.lang.Object readResolve();}</option>
        </options>
        <libs>
            <lib>${java.home}/lib/rt.jar</lib>
            <lib>${java.home}/lib/jsse.jar</lib>
        </libs>
        <addMavenDescriptor>false</addMavenDescriptor>
    </configuration>
</plugin>

这个库有一个带有 @Service 注释的 Spring bean:

@Service
public class LicenseServiceImpl implements LicenseService {

    @Autowired(required = false)
    LicenseSessionStore licenseSessionStore;

    @Autowired(required = false)
    LicenseStore licenseStore;

...

}

我在网络服务 Company.License 中使用这个库,我希望 LicenseService 自动装配:

@Component
public class BackgroundTasks {

    @Autowired
    ScheduledExecutorService scheduledExecutorService;

    @Autowired
    LicenseService licenseService;

...

}

所以 Company.License 依赖于 Common.License。如果我混淆了 Common.License,那么 licenseService 将不会在 BackgroundTasks 中自动装配。我可以解决这个问题的唯一方法是将 licenseService 明确定义为 bean:

@Bean(name = "licenseService", autowire = Autowire.BY_NAME)
public LicenseService getLicenseService() {
    if (licenseService == null) {
        licenseService = new LicenseServiceImpl();
    }
    return licenseService;
}

我不需要将它显式声明为这样的 bean,因为我已经用 @Service 注释了该类,这足以使 licenseServiceBackgroundTasks Spring 中的自动装配神奇地工作。但事实并非如此!

Proguard 专门做了什么使这不起作用?我可以在 Proguard 的配置中做些什么来使其对 Spring 更友好?

授予

【问题讨论】:

    标签: spring obfuscation proguard autowired


    【解决方案1】:

    非常感谢 Eric Lafortune 帮助我指明了正确的方向:

    http://sourceforge.net/projects/proguard/forums/forum/182456/topic/2547498

    这是指定插件和所需选项的工作 pom 文件添加:

    <plugin>
        <groupId>com.pyx4me</groupId>
        <artifactId>proguard-maven-plugin</artifactId>
        <executions>
            <execution>
                <phase>package</phase>
                <goals>
                    <goal>proguard</goal>
                </goals>
            </execution>
        </executions>
        <configuration>
            <obfuscate>true</obfuscate>
            <options>
                <option>-dontoptimize</option>
                <option>-keepdirectories</option>
                <option>-renamesourcefileattribute SourceFile</option>
                <option>-keepattributes Exceptions,InnerClasses,Signature,Deprecated,SourceFile,LineNumberTable,*Annotation*,EnclosingMethod</option>
                <option>-keep public class * { public protected *;}</option>
                <option>-keepclassmembernames class * {java.lang.Class class$(java.lang.String); java.lang.Class class$(java.lang.String, boolean);}</option>
                <option>-keepclassmembernames class * {com.common.license.LicenseService licenseService; com.common.license.LicenseSessionStore licenseSessionStore;}</option>
                <option>-keepclassmembers enum * {public static **[] values(); public static ** valueOf(java.lang.String);}</option>
                <option>-keepclassmembers class * implements java.io.Serializable { static final long serialVersionUID; private static final java.io.ObjectStreamField[] serialPersistentFields; private void writeObject(java.io.ObjectOutputStream); private void readObject(java.io.ObjectInputStream); java.lang.Object writeReplace(); java.lang.Object readResolve();}</option>
                <option>-keep @org.springframework.beans.factory.annotation.Service class *</option>
                <option>-keep @org.springframework.stereotype.Controller class *</option>
                <option>-keepclassmembers class * { @org.springframework.beans.factory.annotation.Autowired *; }</option>
            </options>
            <libs>
                <lib>${java.home}/lib/rt.jar</lib>
                <lib>${java.home}/lib/jsse.jar</lib>
            </libs>
            <addMavenDescriptor>false</addMavenDescriptor>
        </configuration>
    </plugin>
    

    注意!需要使用ProGuard 4.4,最新版本的ProGuard-Maven-Plugin(2.0.4)使用的是4.3所以需要修改:

    {M2_HOME}\repository\com\pyx4me\proguard-maven-plugin\2.0.4\proguard-maven-plugin-2.0.4.pom 
    

    要有 4.4 的依赖(像这样):

    <dependency>
      <groupId>net.sf.proguard</groupId>
      <artifactId>proguard</artifactId>
      <version>4.4</version>
      <scope>runtime</scope>
      <optional>true</optional>
    </dependency>
    

    【讨论】:

    • 所以解决方案没有混淆自动装配注释类:/我看不到混淆的好处,特别是如果我广泛使用spring IOC(用于服务,dao等..)
    【解决方案2】:

    这是切换到 proguard 4.4 版的另一种方法(可能会更好一些):

    <configuration>
      <proguardVersion>4.4</proguardVersion>
      <obfuscate>true</obfuscate>
      <options>
      ... 
      </options>    
      <libs>
        <lib>${java.home}/lib/rt.jar</lib>
        <lib>${java.home}/lib/jsse.jar</lib>
      </libs>
      <addMavenDescriptor>false</addMavenDescriptor>
    </configuration>
    <dependencies>
      <dependency>
        <groupId>net.sf.proguard</groupId>
        <artifactId>proguard</artifactId>
        <version>4.4</version>
        <scope>runtime</scope>
        <optional>true</optional>
      </dependency>
    </dependencies>
    

    【讨论】:

      【解决方案3】:

      我遇到了同样的问题,-keepdirectories 指令帮我解决了这个问题。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-05-11
        • 1970-01-01
        • 1970-01-01
        • 2015-03-13
        相关资源
        最近更新 更多