Merging multiple jar files with Proguard

Source: Internet
Author: User
Tags serialization

Proguard (http://proguard.sourceforge.net/) can be reduced, optimized, and confused with jar files. The reduced JAR file synthesizes multiple input jar files (Injar parameters) into an output jar file (Outjar parameter). Optimized execution is similar to compiler optimizations. The basic obfuscation replaces the variable name, method name, and so on with a shorter alias. This uses the first feature (reduction) of proguard to synthesize multiple jar files into a jar file and eliminate the classes that are not available in those files.

Note: In the reduction and obfuscation operations, in order to ensure the correctness of the results, Proguard can automatically deal with Class.forName ("MyClass") and myclass.class structures, so that the class MyClass will not be excluded or confused; In some cases, the user is warned if Proguard cannot make a decision.

For example, there is an application Myapp.jar, which uses the Apache commons-lang3-3.0 Library, but uses only the individual classes, in order to avoid the Apache The commons-lang3-3.0 library and Myapp.jar are released together to combine the two jar files into one jar:myapp-dist.jar with Proguard reduction (note: It is not clear if this violates the Apache License Convention).

directory structure prior to executing Build.xml's run target:
./src/org/test/proguard/main.java
./commons-lang3-3.0/commons-lang3-3.0.jar
./lib/proguard.jar
./build.xml
./MANIFEST.MF

The directory structure after performing the Build.xml run task:
./src/org/test/proguard/main.java
./commons-lang3-3.0/commons-lang3-3.0.jar
./lib/proguard.jar

./build/org/test/proguard/main.class
./out/myapp.jar
./lib/myapp-dist.jar

./build.xml
./MANIFEST.MF
Where./build/org/test/proguard/main.class is generated by compile target;./out/myapp.jar is generated by jar target;/lib/ The Myapp-dist.jar is generated by shrink target, which is the merged jar file.



File list:
Myapp.jar/main.java:
Package Org.test.proguard;

Import Org.apache.commons.lang3.StringUtils; 
public class Main {public
	static void Main (string[] args) {
		String text = ' Thisisaverylonglongtext ';
		String Shorttext = stringutils.abbreviate (text,);
		System.out.println (text);
		System.out.println (Shorttext);
	}



Build.xml: (Note: No Proguard optimization and obfuscation function is used: optimize= "off" obfuscate = "Off")

<?xml version= "1.0" encoding= "UTF-8"?> <project name= "Proguard" default= "Run" basedir= "./" > <property N
	Ame= "Package.dir" value= "Org/test/proguard"/> <property name= "javahome" value= "/usr/local/jdk1.5.0_16"/> <property name= "Jdk.lib.dir" value= "${javahome}/lib"/> <property name= "Jre.lib.dir" value= "${javahome}/jre" /lib "/> <property name=" proguard.lib "value="/lib "/> <property name=" Commons.lang.lib "value="./common s-lang3-3.0/"/> <property name= src.dir" value= "/src/> <property" name= "Build.dir". value= "/build"
	; <property name= "Out.dir" value=./out "/> <property" name= "Dist.dir". value= "/lib/> <property" Manifest.file "value=" MANIFEST.MF "/> <property name=" outjar.file "value=" Myapp.jar "/> <property" name= " Distjar.file "value=" ${dist.dir}/myapp-dist.jar "/> <path id=" Lib.path "> <fileset dir=" ${jdk.lib.dir} "&G
				T <include name= "**/*.jaR "/> </fileset> <fileset dir=" ${jre.lib.dir} "> <include name=" **/*.jar "/> </fileset > <fileset dir= "${proguard.lib}" > <include name= "**/*.jar"/> </fileset> <fileset dir = "${commons.lang.lib}" > <include name= "**/*.jar"/> </fileset> </path> <target name= "cl
			Ean "> <tstamp/> <delete includeemptydirs=" true "quiet=" yes "> <fileset dir=" ${build.dir} "/> 		
		<fileset dir= "${out.dir}"/> </delete> </target> <target name= "compile" depends= "clean" > <mkdir dir= "${build.dir}"/> <javac srcdir= "${src.dir}/${package.dir}" destdir= "${build.dir}" debug= "Yes" &G
			T <classpath refid= "Lib.path"/> </javac> </target> <target name= "jar" depends= "compile"  
	   ; <mkdir dir= "${out.dir}"/> <jar jarfile= "${out.dir}/${outjar.file}" manifest= "${manifest.file}" > &l T;fileset DIr= "${build.dir}" > <include name= "**/*"/> </fileset> </jar> </target&
	
	Gt <target name= "shrink" depends= "jar" > <taskdef resource= "proguard/ant/task.properties"
	            Lib.path '/> <proguard optimize= ' off ' obfuscate = ' off ' printseeds= ' on ' printmapping= ' Out.map ' Renamesourcefileattribute= "SourceFile" > <!--Specify the input jars, output jars, and library jars. --> <injar file= "${out.dir}/${outjar.file}"/> <injar "file=".
	    Jar "/> <outjar file=" ${distjar.file} "/> <libraryjar file=" ${java.home}/lib/rt.jar "/>
	    <!--Libraryjar file= "Junit.jar"/--> <!--libraryjar file= "Servlet.jar"/-->
	 	  	

	    <!--Libraryjar file= "Jai_core.jar"/--> <!--.../--> <!--Preserve line NuMbers in the obfuscated stack traces. --> <keepattribute name= "linenumbertable"/> <keepattribute "name=" SourceFile <!--P Reserve all annotations. --> <keepattribute name= "*annotation*"/> <!--Preserve All public applications. --> <keepclasseswithmembers access= ' public ' > <method access = ' public static ' Ty PE = "void" name = "main" parameters= "java.lang.string[]"/> </keepclasse Swithmembers> <!--Preserve All native method names and the names of their classes. --> <keepclasseswithmembernames> <method access= "native"/> </keepclasseswithmembernam Es> <!--Preserve The methods that are required in all enumeration classes. --> <keepclassmembers extends= "Java.lang.Enum" > <method access= "public static" Typ
E= "**[]" name= "values"	              Parameters= "" "/> <method access=" public static "type=" * * "name=" valueof "parameters=" java.lang.String "/> </keepclassmembers> <!--explicitly preser ve all serialization members.
	         The Serializable interface is only a marker interface, so it wouldn ' t save them.
	         Can comment this out if your the library doesn ' t use serialization. If Your The code contains serializable classes that have to is backward compatible, please refer to the manual.
	              --> <keepclassmembers implements= "java.io.Serializable" > <field access = "Static final"
	              Type = "Long" name = "Serialversionuid"/> <field access = "Static final" Type = "java.io.objectstreamfield[]" name = "Serialpersistentfields"/> &L
T;method access = "private" type = "void"	              Name = "WriteObject" parameters= "Java.io.ObjectOutputStream"/> <method acc ESS = "private" type = "void" name = "ReadObject" parameters= java. Io.
	              ObjectInputStream "/> <method type =" Java.lang.Object "name =" Writereplace "
	              Parameters= "" "/> <method type =" Java.lang.Object "name =" Readresolve "  Parameters= ""/> </keepclassmembers> <!--Your application may contain other items that need
	         to be preserved; Typically classes that are dynamically created using Class.forName--> </proguard> </target> <ta  Rget name= "Run" depends= "shrink" > <!--run:java-jar lib/app-dist.jar--> <java jar= "${distjar.file}" fork= "yes" > </java> </target> </project>


Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.