Java Springboot application failed to start post obfuscation

We are using Proguard maven plugin to obfuscate our Springboot application. Obfuscation is happening, but application launch failed during start up due to obfuscated classes.

Can you please suggest the correct proguard configuration for a springboot application to work.

Maven plugin code

> <plugin>
> 				<groupId>com.github.wvengen</groupId>
> 				<artifactId>proguard-maven-plugin</artifactId>
> 				<version>2.0.8</version>
> 				<executions>
> 					<execution>
> 						<phase>package</phase>
> 						<goals>
> 							<goal>proguard</goal>
> 						</goals>
> 					</execution>
> 				</executions>
> 				<configuration>
> 					<exclusions>
> 						<exclusion>
> 							<groupId>org.apache.logging.log4j</groupId>
> 							<artifactId>log4j-api</artifactId>
> 						</exclusion>
> 						<exclusion>
> 							<groupId>javax.xml.bind</groupId>
> 							<artifactId>jaxb-api</artifactId>
> 						</exclusion>
> 					</exclusions>
> 					<maxMemory>2048m</maxMemory>
> 					<injar>${project.build.finalName}.jar</injar>
> 					<outjar>${project.build.finalName}.jar</outjar>
> 					<proguardVersion>6.0.3</proguardVersion>
> 					<proguardInclude>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>
> 				<dependencies>
> 					<dependency>
> 						<groupId>net.sf.proguard</groupId>
> 						<artifactId>proguard-base</artifactId>
> 						<version>6.0.3</version>
> 					</dependency>
> 				</dependencies>
> 			</plugin>

proguard.conf

-target 1.8 ##Specify the java version number
-dontshrink ##Default is enabled, here the shrink is turned off, that is, the unused classes/members are not deleted.
-dontoptimize ##Default is enabled, here to turn off bytecode level optimization
-useuniqueclassmembernames ## Take a unique strategy for confusing the naming of class members
-adaptclassstrings com.tfc.ccu2.**
-dontnote
-ignorewarnings

-keepattributes SourceFile,Signature,LineNumberTable,Exceptions, *Annotation*

-keepclasseswithmembers public class * { public static void main(java.lang.String[]);} ##Maintain the class of the main method and its method name
-keepclassmembers class * {
     @org.springframework.web.bind.annotation.ControllerAdvice *;
     @org.springframework.web.bind.annotation.RestController *;
     @org.springframework.stereotype.Component *;
     @org.springframework.stereotype.Service *;
     @org.springframework.stereotype.Repository *;
     @org.springframework.context.annotation.Configuration *;
     @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.context.annotation.PropertySource *;
     @org.springframework.boot.context.properties.ConfigurationProperties *;
     @javax.annotation.PostConstruct *;
}

-keepattributes RuntimeVisibleAnnotations
-keep @javax.persistence.* class * {
   *;
}

-allowaccessmodification
-keepdirectories com.tfc.ccu2.**
-keepdirectories org.springframework.boot.autoconfigure
-renamesourcefileattribute SourceFile

Exception during server start up

Caused by: java.lang.IllegalArgumentException: Failed to create query for method public abstract java.util.List com.tfc.ccu2.m.g.F(java.util.List)! No property f found for type FIleTransferTracker! Did you mean 'id'?
	at org.springframework.data.jpa.repository.query.PartTreeJpaQuery.<init>(PartTreeJpaQuery.java:84)
	at org.springframework.data.jpa.repository.query.JpaQueryLookupStrategy$CreateQueryLookupStrategy.resolveQuery(JpaQueryLookupStrategy.java:106)
	at org.springframework.data.jpa.repository.query.JpaQueryLookupStrategy$CreateIfNotFoundQueryLookupStrategy.resolveQuery(JpaQueryLookupStrategy.java:211)
	at org.springframework.data.jpa.repository.query.JpaQueryLookupStrategy$AbstractQueryLookupStrategy.resolveQuery(JpaQueryLookupStrategy.java:79)
	at org.springframework.data.repository.core.support.RepositoryFactorySupport$QueryExecutorMethodInterceptor.lookupQuery(RepositoryFactorySupport.java:566)
	at org.springframework.data.repository.core.support.RepositoryFactorySupport$QueryExecutorMethodInterceptor.lambda$mapMethodsToQuery$1(RepositoryFactorySupport.java:559)
	at java.util.stream.ReferencePipeline$3$1.accept(ReferencePipeline.java:193)
	at java.util.Iterator.forEachRemaining(Iterator.java:116)
	at java.util.Collections$UnmodifiableCollection$1.forEachRemaining(Collections.java:1051)
	at java.util.Spliterators$IteratorSpliterator.forEachRemaining(Spliterators.java:1801)
	at java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:482)
	at java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:472)
	at java.util.stream.ReduceOps$ReduceOp.evaluateSequential(ReduceOps.java:708)
	at java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234)
	at java.util.stream.ReferencePipeline.collect(ReferencePipeline.java:499)
	at org.springframework.data.repository.core.support.RepositoryFactorySupport$QueryExecutorMethodInterceptor.mapMethodsToQuery(RepositoryFactorySupport.java:561)
	at org.springframework.data.repository.core.support.RepositoryFactorySupport$QueryExecutorMethodInterceptor.lambda$new$0(RepositoryFactorySupport.java:551)
	at java.util.Optional.map(Optional.java:215)
	at org.springframework.data.repository.core.support.RepositoryFactorySupport$QueryExecutorMethodInterceptor.<init>(RepositoryFactorySupport.java:551)
	at org.springframework.data.repository.core.support.RepositoryFactorySupport.getRepository(RepositoryFactorySupport.java:324)
	at org.springframework.data.repository.core.support.RepositoryFactoryBeanSupport.lambda$afterPropertiesSet$5(RepositoryFactoryBeanSupport.java:297)
	at org.springframework.data.util.Lazy.getNullable(Lazy.java:211)
	at org.springframework.data.util.Lazy.get(Lazy.java:94)
	at org.springframework.data.repository.core.support.RepositoryFactoryBeanSupport.afterPropertiesSet(RepositoryFactoryBeanSupport.java:300)
	at org.springframework.data.jpa.repository.support.JpaRepositoryFactoryBean.afterPropertiesSet(JpaRepositoryFactoryBean.java:121)
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1828)
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1765)
	... 62 common frames omitted
Caused by: org.springframework.data.mapping.PropertyReferenceException: No property f found for type FIleTransferTracker! Did you mean 'id'?

Hi @Anil_Kamaraju

Thanks for your question. Do you mind if I shift this to our public forum so our Engineers can see it?

@Jesse - yes, please.

1 Like

Hi @Anil_Kamaraju ,

I’m afraid there is no such thing as a general configuration that fits all spring-boot projects.

Based on the error message it looks like name obfuscation is responsible for the issue you’re looking at;

No property f found for type FIleTransferTracker! Did you mean 'id'?

You could check your mapping file to verify whether or not there is a property being renamed to f for FileTransferTracker . If so, you need to add a -keep rule for this property. Alternatively, you can keep all properties for FileTransferTracker;

-keep class com.example.FileTransferTracker {
    <fields>;
}

I would recommend you to check out the ProGuard Playground, it allows you to visualize the parts of code you preserve using -keep rules without having to rebuild the project over and over again.

Best regards,

Jonas