javaspring-bootantobfuscationyguard

Spring boot :unable to open nested entry 'WEB-INF/lib-provided/ecj-3.12.3.jar'


I am trying to obfuscate the spring boot application. Package : war

I was following the ant script approach with yguard

Link : http://codeaweso.me/2009/02/obfuscating-a-webapp-war-file-with-yguard-and-ant/

Project structure:

main.war

and many more third party dependencies.

I can see we have successfully obfuscate the required third party dependencies jar file.

Also we have kept the other libraries unobfuscated and uncompressed but some how they are getting compressed.

Exception that we getting is

java -jar webapp_obf.war
Exception in thread "main" java.lang.IllegalStateException: Failed to get nested archive for entry WEB-INF/lib-provided/ecj-3.12.3.jar
        at org.springframework.boot.loader.archive.JarFileArchive.getNestedArchive(JarFileArchive.java:109)
        at org.springframework.boot.loader.archive.JarFileArchive.getNestedArchives(JarFileArchive.java:87)
        at org.springframework.boot.loader.ExecutableArchiveLauncher.getClassPathArchives(ExecutableArchiveLauncher.java:72)
        at org.springframework.boot.loader.Launcher.launch(Launcher.java:49)
        at org.springframework.boot.loader.WarLauncher.main(WarLauncher.java:59)
Caused by: java.io.IOException: Unable to open nested jar file 'WEB-INF/lib-provided/ecj-3.12.3.jar'
        at org.springframework.boot.loader.jar.JarFile.getNestedJarFile(JarFile.java:252)
        at org.springframework.boot.loader.jar.JarFile.getNestedJarFile(JarFile.java:237)
        at org.springframework.boot.loader.archive.JarFileArchive.getNestedArchive(JarFileArchive.java:104)
        ... 4 more
Caused by: java.lang.IllegalStateException: Unable to open nested entry 'WEB-INF/lib-provided/ecj-3.12.3.jar'. It has been compressed and nested jar files must be stored without compression. Please check the mechanism used to create your executable jar file
        at org.springframework.boot.loader.jar.JarFile.createJarFileFromFileEntry(JarFile.java:285)
        at org.springframework.boot.loader.jar.JarFile.createJarFileFromEntry(JarFile.java:260)
        at org.springframework.boot.loader.jar.JarFile.getNestedJarFile(JarFile.java:248)
        ... 6 more

<project xmlns='antlib:org.apache.tools.ant'>
	<!-- prepare a temporary directory in which the war file is expanded and 
		obfuscated -->
	<tempfile property="unwar.dir" destdir="obfuscation/"
		deleteonexit="false" />
	<mkdir dir="${unwar.dir}" />
	<unwar src="../target/webapp.war"
		dest="${unwar.dir}" />

	<!-- create a jar of webapp classes (required by yguard) for obfuscation -->
	<jar destfile="${unwar.dir}/WEB-INF/lib/webapp.jar"
		whenempty="fail">
		<zipfileset dir="${unwar.dir}/WEB-INF/classes" />
		<zipfileset dir="${unwar.dir}/META-INF" />

	</jar>

	<!-- <delete dir="${unwar.dir}/WEB-INF/classes" /> -->


	<!-- create a fileset of internal libraries to be obfuscated -->
	<fileset dir="${unwar.dir}/WEB-INF/lib" id="internal.lib.set">
		<include name="first.jar" />
		<include name="second.jar" />
	
	</fileset>

	<!-- move the internal libraries to a temporary directory and make a fileset 
		out of them -->
	<tempfile property="obfuscation.dir"
		destDir="obfuscation/temp" deleteonexit="false" />
	<mkdir dir="${obfuscation.dir}" />
	<move todir="${obfuscation.dir}">
		<fileset refid="internal.lib.set" />
	</move>

	<!-- create a jar of web.xml (required by yguard) for obfuscation -->
	<jar destfile="${obfuscation.dir}/web.xml.jar" whenempty="fail">
		<zipfileset dir="${unwar.dir}/WEB-INF" includes="web.xml" />
	</jar>
	<!-- <delete file="${unwar.dir}/WEB-INF/web.xml" /> -->

	<!-- make a fileset of all jars to be obfuscated -->
	<fileset dir="${obfuscation.dir}" includes="*.jar"
		id="in-out.set" />

	<!-- make a fileset of the remaining libraries, these are not obfuscated -->
	<path id="external.lib.path">
		<fileset dir="${unwar.dir}/WEB-INF/lib" includes="*.jar" />
		<fileset dir="${unwar.dir}/WEB-INF/lib-provided" includes="*.jar" />
	</path>

	<taskdef name="yguard" classname="com.yworks.yguard.YGuardTask"
		classpath="yguard.jar" />

	<yguard>
		<inoutpairs>
			<!-- these filesets are inputs to be obfuscated -->
			<fileset refid="in-out.set" />
		</inoutpairs>
		<externalclasses refid="external.lib.path" />  <!-- external libs, not obfuscated -->
		<rename>
			<adjust replaceContent="true">
				<include name="web.xml" />  <!-- modified to reference the obfuscated Servlet -->
			</adjust>
			<keep>
				<!-- classes, packages, methods, and fields which should not obfuscated 
					are specified here -->
				<class classes="none" methods="none" fields="none" >
					<patternset>
						<include name="com.Application" />
					</patternset>
				</class>

			</keep>
		</rename>
	</yguard>

	<!-- move our newly obfuscated classes back into the lib area -->
	<move todir="${unwar.dir}/WEB-INF/lib">
		<fileset dir="${obfuscation.dir}" includes="*_obf.jar" />
	</move>

	<!-- unjar the adjusted web.xml -->
	<unzip dest="${unwar.dir}/WEB-INF/"
		src="${unwar.dir}/WEB-INF/lib/web.xml_obf.jar">
		<patternset includes="web.xml" />
	</unzip>
	<delete>
		<fileset dir="${unwar.dir}/WEB-INF/lib"
			includes="web.xml*.jar" />
	</delete>

	<!-- rebuild the war file -->
	<war destfile="webapp_obf.war" basedir="${unwar.dir}"
		needxmlfile='false'>
		<manifest>
			<attribute name="Main-Class"
				value="org.springframework.boot.loader.WarLauncher" />
			<attribute name="Start-Class"
				value="com.Application" />
			<attribute name="Spring-Boot-Classes"
				value="WEB-INF/classes/" />
			<attribute name="Spring-Boot-Lib" value="WEB-INF/lib/" />
			<attribute name="Build-Jdk" value="1.8.0_171" />
		</manifest>
	</war>
</project>

Any suggestion why we might the compression exception.


Solution

  • When you are attempting to build the jar then only provide below options.

    maven-assembly-plugin

     <archive> 
    <compress>false</compress>
     </archive>
    

    Also we can provide the same in spring-boot maven plugin.