Spring Boot 和 Proguard
Posted
技术标签:
【中文标题】Spring Boot 和 Proguard【英文标题】:Spring Boot and Proguard 【发布时间】:2017-10-15 12:06:57 【问题描述】:我有一个简单的 Spring Boot 1.5.3 应用程序,我试图使用 proguard-maven-plugin
与 Proguard 5.x 混淆。我有以下proguard.conf
。
-injars ../$FINAL_NAME$/WEB-INF/lib/$FINAL_NAME$.jar
-outjars ./
-optimizations !class/marking/final
-dontoptimize
-adaptresourcefilenames **.properties
-adaptresourcefilecontents **.properties,META-INF/MANIFEST.MF
-dontshrink
-dontoptimize
-dontobfuscate
-dontusemixedcaseclassnames
-dontpreverify
-verbose
-keep public class com.test.blah.OnboardingApp
public static void main(java.lang.String[]);
-keep public class * extends org.springframework.boot.web.support.SpringBootServletInitializer
-keep class com.test.blah**.dto.**
void set*(***);
*** get*();
-keepclassmembers class *
@org.springframework.beans.factory.annotation.Autowired *;
@org.springframework.beans.factory.annotation.Qualifier *;
@org.springframework.beans.factory.annotation.Value *;
@org.springframework.beans.factory.annotation.Required *;
@org.springframework.context.annotation.Bean *;
@org.springframework.context.annotation.Primary *;
@org.springframework.boot.context.properties.ConfigurationProperties *;
@org.springframework.boot.context.properties.EnableConfigurationProperties *;
@javax.inject.Inject *;
@javax.annotation.PostConstruct *;
@javax.annotation.PreDestroy *;
-keep @org.springframework.stereotype.Service class *
-keep @org.springframework.stereotype.Controller class *
-keep @org.springframework.stereotype.Component class *
-keep @org.springframework.stereotype.Repository class *
-keep @org.springframework.cache.annotation.EnableCaching class *
-keep @org.springframework.context.annotation.Configuration class *
-keep @org.springframework.boot.context.properties.ConfigurationProperties class *
-keep @org.springframework.boot.autoconfigure.SpringBootApplication class *
-allowaccessmodification
-keepattributes Exceptions,InnerClasses,Signature,Deprecated,SourceFile,LineNumberTable,LocalVariable*Table,*Annotation*,Synthetic,EnclosingMethod
-keepattributes *Annotation*
-keepattributes Signature
-keepattributes Exceptions
-keepattributes InnerClasses
-keepparameternames
-keepdirectories com.test.blah
-keepdirectories org.springframework.boot.autoconfigure
-keepclassmembernames class *
java.lang.Class class$(java.lang.String);
java.lang.Class class$(java.lang.String, boolean);
-keepclassmembers enum *
public static **[] values();
public static ** valueOf(java.lang.String);
public static ** fromValue(java.lang.String);
-keepnames class * implements java.io.Serializable
-keepclassmembernames public class com.test.blah.config.liquibase.AsyncSpringLiquibase
-keepclassmembers class * implements java.io.Serializable
static final long serialVersionUID;
private static final java.io.ObjectStreamField[] serialPersistentFields;
!static !transient <fields>;
!private <fields>;
!private <methods>;
private void writeObject(java.io.ObjectOutputStream);
private void readObject(java.io.ObjectInputStream);
java.lang.Object writeReplace();
java.lang.Object readResolve();
-keepclassmembers class *
@org.springframework.beans.factory.annotation.Autowired <fields>;
@org.springframework.beans.factory.annotation.Autowired <methods>;
@org.springframework.security.access.prepost.PreAuthorize <methods>;
我正在加载proguard.conf
,
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-antrun-plugin</artifactId>
<version>$maven-antrun-plugin.version</version>
<executions>
<execution>
<phase>process-classes</phase>
<goals>
<goal>run</goal>
</goals>
<configuration>
<target>
<mkdir dir="$project.build.directory/proguarded" />
<copy file="proguard.conf" todir="target/proguarded" />
<replace file="$project.build.directory/proguarded/proguard.conf"
token="$FINAL_NAME$" value="$project.build.finalName" />
</target>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>com.github.wvengen</groupId>
<artifactId>proguard-maven-plugin</artifactId>
<version>$proguard-maven-plugin.version</version>
<executions>
<execution>
<phase>prepare-package</phase>
<goals>
<goal>proguard</goal>
</goals>
</execution>
</executions>
<configuration>
<proguardInclude>$project.build.directory/proguarded/proguard.conf</proguardInclude>
<libs>
<lib>$java.home/lib/rt.jar</lib>
<lib>$java.home/lib/jce.jar</lib>
<lib>$java.home/lib/jsse.jar</lib>
</libs>
</configuration>
</plugin>
生成war
文件工件没有问题。但是,当我部署到 tomcat 实例时,出现以下错误,
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'org.springframework.boot.autoconfigure.liquibase.LiquibaseAutoConfiguration$LiquibaseConfiguration': Invocation of init method failed; nested exception is java.lang.IllegalStateException: Cannot find changelog location: class path resource [db/changelog/db.changelog-master.yaml] (please add changelog or check your Liquibase configuration)
at org.springframework.beans.factory.annotation.InitDestroyAnnotationBeanPostProcessor.postProcessBeforeInitialization(InitDestroyAnnotationBeanPostProcessor.java:137)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyBeanPostProcessorsBeforeInitialization(AbstractAutowireCapableBeanFactory.java:409)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1620)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:555)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:483)
at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:306)
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:302)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:197)
at org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorResolver.java:372)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateUsingFactoryMethod(AbstractAutowireCapableBeanFactory.java:1173)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1067)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:513)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:483)
at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:306)
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:302)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:197)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:296)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:197)
at org.springframework.context.support.AbstractApplicationContext.getBean(AbstractApplicationContext.java:1081)
at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:856)
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:542)
at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.refresh(EmbeddedWebApplicationContext.java:122)
at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:737)
at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:370)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:314)
at org.springframework.boot.web.support.SpringBootServletInitializer.run(SpringBootServletInitializer.java:151)
at org.springframework.boot.web.support.SpringBootServletInitializer.createRootApplicationContext(SpringBootServletInitializer.java:131)
at org.springframework.boot.web.support.SpringBootServletInitializer.onStartup(SpringBootServletInitializer.java:86)
at org.springframework.web.SpringServletContainerInitializer.onStartup(SpringServletContainerInitializer.java:169)
at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5196)
at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:150)
... 10 more
Caused by: java.lang.IllegalStateException: Cannot find changelog location: class path resource [db/changelog/db.changelog-master.yaml] (please add changelog or check your Liquibase configuration)
at org.springframework.util.Assert.state(Assert.java:70)
at org.springframework.boot.autoconfigure.liquibase.LiquibaseAutoConfiguration$LiquibaseConfiguration.checkChangelogExists(LiquibaseAutoConfiguration.java:92)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.springframework.beans.factory.annotation.InitDestroyAnnotationBeanPostProcessor$LifecycleElement.invoke(InitDestroyAnnotationBeanPostProcessor.java:366)
at org.springframework.beans.factory.annotation.InitDestroyAnnotationBeanPostProcessor$LifecycleMetadata.invokeInitMethods(InitDestroyAnnotationBeanPostProcessor.java:311)
at org.springframework.beans.factory.annotation.InitDestroyAnnotationBeanPostProcessor.postProcessBeforeInitialization(InitDestroyAnnotationBeanPostProcessor.java:134)
... 42 more
在我的应用程序中,我正在加载 Liquibase bean,
@Configuration("databaseConfiguration")
@EnableJpaRepositories("com.test.blah.repository")
@EnableJpaAuditing(auditorAwareRef = "springSecurityAuditorAware")
@EnableTransactionManagement
@EnableElasticsearchRepositories("com.test.blah.repository.search")
public class DatabaseConfiguration
private final Logger log = LoggerFactory.getLogger(DatabaseConfiguration.class);
@Inject
private Environment env;
@Bean
public SpringLiquibase liquibase(DataSource dataSource, LiquibaseProperties liquibaseProperties)
// Use liquibase.integration.spring.SpringLiquibase if you don't want Liquibase to start asynchronously
SpringLiquibase liquibase = new AsyncSpringLiquibase();
liquibase.setDataSource(dataSource);
liquibase.setChangeLog("classpath:config/liquibase/master.xml");
liquibase.setContexts(liquibaseProperties.getContexts());
liquibase.setDefaultSchema(liquibaseProperties.getDefaultSchema());
liquibase.setDropFirst(liquibaseProperties.isDropFirst());
if (env.acceptsProfiles(Constants.SPRING_PROFILE_NO_LIQUIBASE))
liquibase.setShouldRun(false);
else
liquibase.setShouldRun(liquibaseProperties.isEnabled());
log.debug("Configuring Liquibase");
return liquibase;
谁能告诉我为什么我看到错误?
【问题讨论】:
【参考方案1】:诀窍是使用-keepdirectories
中提到的https://www.guardsquare.com/en/proguard/manual/usage#iooptions
如果其他人遇到此问题,我只是将其添加到上述 proguard.conf
并删除了过滤器。
所以不是,
-keepdirectories com.test.blah
-keepdirectories org.springframework.boot.autoconfigure
我有,
-keepdirectories
这似乎涵盖了所有目录。
【讨论】:
非常感谢!!帮了我很大的忙以上是关于Spring Boot 和 Proguard的主要内容,如果未能解决你的问题,请参考以下文章
spring-boot-starter-web 和 spring-boot-starter-webflux 不能一起工作吗?
Spring Boot系列 Spring Boot介绍和基础POM文件
Spring Boot:Spring Boot整合Logback和PageHelper
spring-boot-starter-jta-atomikos 和 spring-boot-starter-batch