编程知识 cdmana.com

The latest version of springboot combined with Proguard to achieve code obfuscation

SpringBoot combination ProGuard Implement code obfuscation

    • Reference cases
    • Preface
    • ProGuard Integrate
      • 1.maven Configuration of
      • 2. Related exception resolution
      • matters needing attention

Reference cases

1、Springboot+proguard+maven confusion . 2、proguard-spring-boot-example 3、 Official explanation 4、Proguard Of Keep Usage method 5、ProGuard The most complete confusion rule states 6、ProGuard Code obfuscation technology in detail 7、 Use proguard confusion springboot Code

Preface

Research ProGuard It also took two days , In fact, the most important time is spent in front of proguard Read jar When the bag is related to jar The question of conflict , But in general, there's no need to split SpringBoot It's comfortable to project and implement code obfuscation .

ProGuard Integrate

1.maven Configuration of

The specific configuration is as follows :

<build>
		<finalName>${artifactId}</finalName>
		<plugins>
			<plugin>
				<groupId>com.github.wvengen</groupId>
				<artifactId>proguard-maven-plugin</artifactId>
				<executions>
					<execution>
						<phase>package</phase>
						<goals><goal>proguard</goal></goals>
					</execution>
				</executions>
				<configuration>
					<proguardVersion>6.2.2</proguardVersion>
					<injar>${project.build.finalName}.jar</injar>
					<outjar>${project.build.finalName}.jar</outjar>
					<!--<proguardInclude>${project.basedir}/proguard.cfg</proguardInclude>-->
					<obfuscate>true</obfuscate>
					<options>
						<!--  No contraction ( Delete Note 、 Unreferenced code )-->
						<option>-dontshrink</option>
						<!--  No optimization ( Change the code implementation logic )-->
						<option>-dontoptimize</option>
						<!-- Keep the directory structure , otherwise spring Automatic injection is not available -->
						<!--<option>-keepdirectories</option>-->
						<option>-keepattributes Exceptions,InnerClasses,Signature,Deprecated,
							SourceFile,LineNumberTable, *Annotation*,EnclosingMethod
						</option>
						<option>-adaptclassstrings</option>
						<option>
							<!--  Protect program entry  -->
							 -keep class com.jingchen.ccny.CmepApplication { *; }
						</option>
						<option>-keepnames interface ** { *; }</option>
						<!--  Fix several classes and don't confuse -->
						<option>-keepnames class com.jingchen.ccny.base.BaseService { *; }</option>
						<option>-keep class com.jingchen.ccny.common.cache.ConvertorNewCache { *; }</option>
						<option>-keep class com.jingchen.ccny.base.ControllerContext { *; }</option>
						<option>-keep class * extends com.jingchen.ccny.base.BaseService</option>
						<option>-keep class * implements com.jingchen.ccny.common.service.CallBackGuiService</option>
						<option>-keep class * implements com.jingchen.ccny.common.service.CallBackUDService</option>
						<option>-keep class com.jingchen.ccny.util.SpringUtil</option>
						<!--<option>-keep interface * extends * { *; }</option>-->
						<!--  This option will save all the original defined annotations in all classes of all packages .-->
						<option>
							    -keep class * {
							@org.springframework.beans.factory.annotation.Autowired *;
							@org.springframework.beans.factory.annotation.Value *;
							@org.springframework.stereotype.Service *;
							@org.springframework.stereotype.Component *;
							@org.springframework.scheduling.annotation.Scheduled *;

							}
						</option>
					</options>
					<libs>
						<!-- Include main JAVA library required.-->
						<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>6.2.2</version>
					</dependency>
				</dependencies>
			</plugin>

			<!-- Maven assembly must be run after proguard obfuscation so it take already obfuscated files.-->
			<plugin>
				<groupId>org.springframework.boot</groupId>
				<artifactId>spring-boot-maven-plugin</artifactId>
				<executions>
					<execution>
						<goals>
							<goal>repackage</goal>
						</goals>
						<configuration>
							<mainClass>com.jingchen.ccny.CcnyApplication</mainClass>
						</configuration>
					</execution>
				</executions>
			</plugin>
		</plugins>
	</build>

Here's a cascading reference to jar quite a lot , It is suggested that people who have configured private services first configure the image address as maven Central warehouse address , In this way, the related dependency packages will be downloaded first , And then upload it to your private clothes . As far as I know from my research jar There is :

Be careful : Not connected to the Internet configuration maven In the case of the central warehouse , Less jar You're going to have a headache . And more than net.sf.proguard Related packages , It also includes com.guardsquare.proguard-base and com.guardsquare.proguard-core dependent jar, So it's really important to get off the Internet !!!!

Recommend a IDEA solve maven Reference conflicting plug-ins :Maven Helper

2. Related exception resolution

  • idea A required class was missing … org/apache/tools/ant/BuildListener Question why : This is the problem mentioned above because apache The compilation of the ant-1.9.3 My bag , This is a concatenated reference , At first I was the intranet maven Private clothes , Simple introduction net.sf.proguard Related and com.github.wvengen dependent jar There will still be a lot missing jar Solution : Connect to the Internet , Configure your maven Of setting.xml Of mirror Mirror address , configure Maven The address of the central warehouse , Will be relevant jar All down , And then send you to the local government by order maven The warehouse jar Upload it to private servers
  • Can’t process class [META-INF/versions/9/org/apache/logging/log4j/util/Base64Util.class]
  • Can’t process class [META-INF/versions/11/module-info.class] Question why There are many reasons for this problem , The main thing is our jdk The version is 1.8, I started with ProGuard yes 5.3.3 edition , But we SpringBoot The version is 2.3.3 edition ,SpringBoot2.3.3 The version is so new , The relevant packages quoted in it are all java9 and java11 Version of , such ProGuard reading jar You can't recognize . These problems are rising Proguard Version to 6.2.2 And then it all worked out Solution At first, my solution was to ignore the relevant jar, For example, in pom.xml Of option To configure :
<option>-libraryjars  ${settings.localRepository}/com/zaxxer/HikariCP/3.4.5/HikariCP-3.4.5.jar(META-INF/versions/11/module-info.class)</option>

But after I configure it like this , Repackaging will prompt :

  • The same input jar [E:\maven\repo\com\zaxxer\HikariCP\3.4.5\HikariCP-3.4.5.jar] is specified twice. Solution Reference resources And I tried maven When referencing, exclude these cascading references of higher versions jar, Single reference to the lower version , But in the end, it was too cumbersome to give up . Direct promotion Proguard Version to 6.2.2 These readings jar The version problem of is solved .
  • Annotation-specified bean name ‘a’ for bean class Question why : The problem is mainly after confusion ,bean It's a double name ,spring By default, the first letter of the class name is loaded into the container in lowercase , After we confuse class names , It's easy to cause beanName repeat . Solution : Fortunately, , We can change it spring load bean To solve this problem , Take the bag name with you , At the same time, it's getting Spring Context getBean When , Add the package name path Start class configuration , As follows :
@SpringBootApplication
public class CcnyApplication{

	public static class CustomGenerator implements BeanNameGenerator {

		@Override
		public String generateBeanName(BeanDefinition definition, BeanDefinitionRegistry registry) {
			return definition.getBeanClassName();
		}
	}

	public static void main(String[] args) {
		SpringApplicationBuilder sab=new SpringApplicationBuilder(CcnyApplication.class)
				.beanNameGenerator(new CustomGenerator());
		// Here, if you want to print the Spring Of bean, You can do this :
		ApplicationContext ac =sab.run(args);
		Arrays.stream(ac.getBeanDefinitionNames()).forEach(System.out::println);
	}
}

This configuration , When you start up, you can see all the loaded beanName( here Service Will take it package route )

other place getBean Usage of :

// there packagePath = com.jingchen.ccny.service
CallBackGuiService callBackGuiService = (CallBackGuiService) SpringUtil.getBean(packagePath+serviceName);
                    callBackResult = callBackGuiService.excute(convertMap);

So you can normally get Spring Container loaded beanName 了

matters needing attention

  • Basically, there are some of the above problems that affect packaging and startup , The rest is the details of your project ,
  • such as DAO To keep , Want to be with mybatis Inside Mapper Mapping correspondence ,DAO The method of reference should be changed map Or entities , In addition, the serialized entity should be preserved
  • Controller The method in it can be used as reference , If you use entities , This part of the entity should also be retained ( Ensure that its variables are not confused , Otherwise, you can't get it )
  • The other is you spring dependent XML Inside , If configured separately Bean and Bean Attribute , This kind of bean To keep , Can't be confused
  • I keep all the interfaces and the methods in the interfaces , We have customized the abstract class BaseService The method names in it will not be confused , You can define these for yourself , And I've defined tagging here @Component Class names are also reserved , According to my configuration above , Basically, you don't have to rebuild beanName. natural application Start and it's over
  • The others are gone , It depends on whether you have any specific classes that can't be confused , And the intensity of your confusion ( Our requirement is to keep all class names 、 Interface information and abstract class information , All other classes and methods are confused !)

All in all, it took two days , It is also gratifying to have such achievements , The day before jar There are many conflicts , The main reason is that in the beginning XX The architect builds the project using the latest SpringBoot edition ,jdk Indeed 1.8 , A lot of incompatibility .

Let's have a final rendering :

Participation of this paper Tencent cloud media sharing plan , You are welcome to join us , share .

版权声明
本文为[The blank of writing memory]所创,转载请带上原文链接,感谢
https://cdmana.com/2020/12/20201224104023993T.html

Scroll to Top