Has anyone used proguard to obfuscation of .war file and succeed? - proguard

Has anyone used proguard to obfuscation of .war file and succeed? if yes then please tell me the exact steps to obfuscation of war.
I am not finding any ideal document on web for my requirement.
I have created my web application in spring boot and jsp.
<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>5.3.3</proguardVersion>
<injar>${project.build.finalName}.jar</injar>
<outjar>${project.build.finalName}.jar</outjar>
<obfuscate>true</obfuscate>
<options>
<option>-dontshrink</option>
<option>-dontoptimize</option>
<option>-adaptclassstrings</option>
<option>-keepattributes
Exceptions,InnerClasses,Signature,Deprecated,
SourceFile,LineNumberTable,*Annotation*,EnclosingMethod</option>
<option>-keepnames interface **</option>
<option>-keepparameternames</option>
<option>-keep class
!com.slm.proguard.example.spring.boot.domain.**
{ *; }</option>
<option>-keep class com.slm.proguard.example.spring.boot.service {
*; }</option>
<option>-keep interface * extends * { *; }</option>
<option>-keepclassmembers class * {
#org.springframework.beans.factory.annotation.Autowired *;
#org.springframework.beans.factory.annotation.Value *;
}
</option>
</options>
<libs>
Include main JAVA library required.
<lib>${java.home}/lib/rt.jar</lib>
Include crypto JAVA library if necessary.
<lib>${java.home}/lib/jce.jar</lib>
</libs>
</configuration>
<dependencies>
<dependency>
<groupId>net.sf.proguard</groupId>
<artifactId>proguard-base</artifactId>
<version>5.3.3</version>
</dependency>
</dependencies>
</plugin>

I had problems with a JAR created by proguard, it seemed ok but tomcat didn't find anything inside. After a long search I found that unzipping and re-zipping with an ant-task the exact same file make a working one.
Here is the added configuration:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-antrun-plugin</artifactId>
<version>1.3</version>
<executions>
<execution>
<id>fixzip</id>
<phase>prepare-package</phase>
<goals>
<goal>run</goal>
</goals>
<configuration>
<tasks>
<!-- ******************** ********* ******************** -->
<!-- ******************** IMPORTANT ******************** -->
<!-- ******************** ********* ******************** -->
<!-- It may seems strange to unzip and re-jar the file -->
<!-- but the JAR made by Proguard is somehow not readable -->
<!-- by Tomcat and Spring beans aren't recognized -->
<!-- *************************************************** -->
<!-- Fixing JAR. -->
<move file="target/${project.build.finalName}/WEB-INF/lib/${project.artifactId}-${project.version}.jar"
tofile="target/${project.artifactId}-${project.version}_proguard_base.jar" />
<jar destfile="target/${project.build.finalName}/WEB-INF/lib/${project.artifactId}-${project.version}.jar">
<zipfileset
src="target/${project.artifactId}-${project.version}_proguard_base.jar"
includes="**/*.*" />
</jar>
</tasks>
</configuration>
</execution>
</executions>
</plugin>

Related

I have a problem with packing my maven selenium project in a standalone jar-file. There is no cp for testclasses despite being in jar file

I try to pack my maven selenium autotest project into a standalone jar. I use the next main class to start test classes:
public static void main(String[] args) {
InvocationRequest request = new DefaultInvocationRequest();
request.setPomFile(new File("pom.xml"));
request.setGoals(Collections.singletonList("install"));
Invoker invoker = new DefaultInvoker();
invoker.setMavenHome(new File(System.getenv("MAVEN_HOME")));
try {
invoker.execute(request);
} catch (MavenInvocationException e) {
e.printStackTrace();
}
}
I have no problem with this, the tests are perfectly running from the mainclass. The next step is to pack the project into a jar-file. So I use maven-jar-plugin and maven-assembly-plugin for that purpose:
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<executions>
<execution>
<goals>
<goal>test-jar</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-assembly-plugin</artifactId>
<version>3.1.0</version>
<executions>
<execution>
<id>make-assembly</id>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
</execution>
</executions>
<configuration>
<archive>
<manifest>
<mainClass>common.MainClass</mainClass>
</manifest>
</archive>
<appendAssemblyId>false</appendAssemblyId>
<descriptors>
<descriptor>src/test/resources/assembly.xml</descriptor>
</descriptors>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>3.0.0-M5</version>
<configuration>
<suiteXmlFiles>
<suiteXmlFile>testng.xml</suiteXmlFile>
</suiteXmlFiles>
</configuration>
</plugin>
</plugins>
</build>
and my assembly:
<assembly xmlns="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.0 http://maven.apache.org/xsd/assembly-1.1.0.xsd">
<id>test-jar-with-dependencies</id>
<formats>
<format>jar</format>
</formats>
<includeBaseDirectory>false</includeBaseDirectory>
<dependencySets>
<dependencySet>
<outputDirectory>/</outputDirectory>
<useProjectArtifact>true</useProjectArtifact>
<!-- we're creating the test-jar as an attachement -->
<useProjectAttachments>true</useProjectAttachments>
<unpack>true</unpack>
<scope>test</scope>
</dependencySet>
</dependencySets>
<fileSets>
<fileSet>
<directory>${project.build.directory}/test-classes</directory>
<outputDirectory>/</outputDirectory>
<includes>
<include>*.class</include>
</includes>
<useDefaultExcludes>true</useDefaultExcludes>
</fileSet>
</fileSets>
</assembly>
I manage to pack both common and test classes in a jar-file. I manually put the pom file and the testing file in the same directory as the jar file, so I have no trouble with starting the project. But the tests don't run, because the test-classes are not found, despite being inside the project.
I will be very appreciative if anyone gives me a clue about what I do wrong.
P.S. I put here a refer to my project: https://bitbucket.org/Max1203/donatiton-script.git
Test class not found may be misconfiguration
Can you reimport maven dependencies it will solve
Maven cycle-Reload All maven projects
In case anybody needs the answer. Just change the code in MainClass to the next one:
TestNG testNG = new TestNG();
testNG.setTestSuites(Arrays.asList("testng.xml"));
testNG.setPreserveOrder(true);
testNG.run();
It is gonna solve the problem.

#MicronautTest does not start the embedded server

I am writing a Spock test for controllers in an app using Micronaut. When using #MicronautTest(application=Application), it throws exception with message #MicronautTest used on test but no bean definition for the test present..
On examining the code, I see the following 2 reasons why Micronaut throws this exception. From io.micronaut.test.extensions.spock.MicronautSpockExtension :
if (this.specDefinition == null) {
if (!this.isTestSuiteBeanPresent((Class)spec.getReflection())) {
throw new InvalidSpecException("#MicronautTest used on test but no bean definition for the test present. This error indicates a misconfigured build or IDE. Please add the 'micronaut-inject-java' annotation processor to your test processor path (for Java this is the testAnnotationProcessor scope, for Kotlin kaptTest and for Groovy testCompile). See the documentation for reference: https://micronaut-projects.github.io/micronaut-test/latest/guide/");
}
...
}
My POM configuration is:
<plugin>
<groupId>org.codehaus.gmavenplus</groupId>
<artifactId>gmavenplus-plugin</artifactId>
<version>1.6</version>
<executions>
<execution>
<goals>
<goal>addTestSources</goal>
<goal>addSources</goal>
<goal>compileTests</goal>
<goal>compile</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.7.0</version>
<configuration>
<source>${jdk.version}</source>
<target>${jdk.version}</target>
<encoding>UTF-8</encoding>
<compilerArgs>
<arg>-parameters</arg>
</compilerArgs>
<annotationProcessorPaths>
<path>
<groupId>org.mapstruct</groupId>
<artifactId>mapstruct-processor</artifactId>
<version>${mapstruct.version}</version>
</path>
<path>
<groupId>io.micronaut</groupId>
<artifactId>micronaut-inject-java</artifactId>
<version>${micronaut.version}</version>
</path>
<path>
<groupId>io.micronaut</groupId>
<artifactId>micronaut-validation</artifactId>
<version>${micronaut.version}</version>
</path>
</annotationProcessorPaths>
</configuration>
<executions>
<execution>
<id>test-compile</id>
<goals>
<goal>testCompile</goal>
</goals>
<configuration>
<compilerArgs>
<arg>-parameters</arg>
</compilerArgs>
<annotationProcessorPaths>
<path>
<groupId>org.mapstruct</groupId>
<artifactId>mapstruct-processor</artifactId>
<version>${mapstruct.version}</version>
</path>
<path>
<groupId>io.micronaut</groupId>
<artifactId>micronaut-inject-java</artifactId>
<version>${micronaut.version}</version>
</path>
</annotationProcessorPaths>
</configuration>
</execution>
</executions>
</plugin>
If I do not define the annotation the test #MicronautTest, it seems that the application doesn't even start.
Below is the spec code:
#MicronautTest(application= Application)
#PropertySource(value = [
#Property(name='spec.name', value = 'EndpointSpec'),
#Property(name = 'endpoints.health.details-visible', value = 'ANONYMOUS'),
#Property(name = MongoSettings.EMBEDDED, value = 'true'),
])
class EndpointSpec extends Specification {
#Inject
EmbeddedServer embeddedServer
#Inject
ApplicationContext applicationContext
#Unroll
def "test health endpoint is working"() {
given: 'a RxHttpClient'
URL server = embeddedServer.getURL()
RxHttpClient client = new DefaultHttpClient(server, new DefaultHttpClientConfiguration(), '/management')
when: '/health is called'
HttpResponse response = client.toBlocking().exchange('/health')
then: 'response is 200 OK and contains valid headers'
response.status == HttpStatus.OK
response.headers.size() == 5
response.headers.contains('uber-trace-id')
response.headers.contains('Date')
response.headers.contains('content-type') && response.headers.get('content-type') == MediaType.APPLICATION_JSON
response.headers.contains('content-length')
response.headers.contains('connection')
//and: 'response contains valid HealthResult'
//HealthResult healthResult = response.body()
// Want to validate the health result here but nothing is present in body
}
}
How I can either defined the specDefinition value or mark the test in such a way that it is present as a bean definition and what is the reason for such a behavior. Any help would be greatly appreciated.
Micronaut-test makes the tests themselves beans. In order for a Groovy test to be a bean, you need to have micronaut-inject-groovy on the compilation path for test.
Yes, adding the micronaut-inject-groovy to your maven build will resolve the issue. Add the following.
<dependency>
<groupId>io.micronaut.test</groupId>
<artifactId>micronaut-test-spock</artifactId>
<scope>test</scope>
</dependency>

Generate classes with gradle and jaxb for tests with different configuration

I'm using
id "com.bmuschko.docker-java-application" version "3.0.7"
https://github.com/rackerlabs/gradle-jaxb-plugin
gradle plugin and this configuration:
jaxb {
xsdDir = "${project.projectDir}/src/main/xsd/"
bindingsDir = "${project.projectDir}/src/main/xsd/"
xjc {
taskClassname = "org.jvnet.jaxb2_commons.xjc.XJC2Task"
args = [
'-Xfluent-api'
]
}
}
sourceSets.main.java.srcDirs += "${generatedSources}"
compileJava.dependsOn xjc
for tests I want to add more arguments to xjc. And run this new task with regular gradle build (depending the test task on this one). Maven solves this with help of executions
<plugin>
<groupId>org.jvnet.jaxb2.maven2</groupId>
<artifactId>maven-jaxb2-plugin</artifactId>
<version>0.13.1</version>
<executions>
<execution>
<id>prod</id>
<goals>
<goal>generate</goal>
</goals>
</execution>
<execution>
<id>test</id>
<phase>process-test-sources</phase>
<goals>
<goal>generate</goal>
</goals>
<configuration>
<generateDirectory>target/generated-test-sources/xjc</generateDirectory>
<addCompileSourceRoot>false</addCompileSourceRoot>
<addTestCompileSourceRoot>true</addTestCompileSourceRoot>
<args>
<arg>-Xfluent-api</arg>
<arg>-Xinheritance</arg>
<arg>-Xannotate</arg>
<arg>-Xvalue-constructor</arg>
<arg>-Xequals</arg>
<arg>-XhashCode</arg>
<arg>-XtoString</arg>
</args>
</configuration>
</execution>
</executions>
<configuration>
<schemaDirectory>src/main/xsd</schemaDirectory>
<bindingDirectory>src/main/xsd</bindingDirectory>
<removeOldOutput>true</removeOldOutput>
<extension>true</extension>
<verbose>true</verbose>
<readOnly>true</readOnly>
<args>
<arg>-Xfluent-api</arg>
</args>
</configuration>
</plugin>
But how to solve it in gradle? I want as result 2 sets of classes in different folders - one for production code and one for tests (with additional jaxb plugins enabled).
Simple
task tst(type: org.openrepose.gradle.plugins.jaxb.task.JaxbXjc) {
}
Requires separate configuration
> No value has been specified for property 'bindings'.
> No value has been specified for property 'episodeDirectory'.
> No value has been specified for property 'generatedFilesDirectory'.
> No value has been specified for property 'schemasDirectory'.
> No value has been specified for property 'xsds'.
different from dsl. How to reuse the dsl-based configuration?

Commons Logging - ClassNotFoundException

For whatever reason I can't seem to run my jar file without receiving a ClassNotFound Exception. I am new to Maven, so I believe the issue could be caused by my POM.XML file. Allow me to elaborate. I have isolated the problem to an example HelloWorld log.
package com;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
public class HelloLog {
public static Log log = LogFactory.getLog(HelloLog.class);
public static void main(String[] args){
log.info("Hello World!");
}
}
I have also simplified my pom.xml to only two dependencies.
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>--MygroupId--</groupId>
<artifactId>--MyArtID--</artifactId>
<version>--MyVer--</version>
<dependencies>
<dependency>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
<version>1.1.3</version>
</dependency>
<dependency>
<groupId>org.hibernate.javax.persistence</groupId>
<artifactId>hibernate-jpa-2.0-api</artifactId>
<version>1.0.1.Final</version>
</dependency>
</dependencies>
<build>
<sourceDirectory>src</sourceDirectory>
<resources>
<resource>
<directory>src</directory>
<excludes>
<exclude>**/*.java</exclude>
</excludes>
</resource>
</resources>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>2.4</version>
<configuration>
<archive>
<manifest>
<addClasspath>true</addClasspath>
<classpathPrefix>lib</classpathPrefix>
<mainClass>com.HelloLog</mainClass>
</manifest>
</archive>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.1</version>
<configuration>
<verbose>true</verbose>
<fork>true</fork>
<compilerVersion>1.6</compilerVersion>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<version>2.5.1</version>
<executions>
<execution>
<id>copy-dependencies</id>
<phase>package</phase>
<goals>
<goal>copy-dependencies</goal>
</goals>
<configuration>
<outputDirectory>
${project.build.directory}/dependency-jars/
</outputDirectory>
<overWriteReleases>false</overWriteReleases>
<overWriteSnapshots>false</overWriteSnapshots>
<overWriteIfNewer>true</overWriteIfNewer>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
<pluginManagement>
<plugins>
<!--This plugin's configuration is used to store Eclipse m2e settings only. It has no influence on the Maven build itself.-->
<plugin>
<groupId>org.eclipse.m2e</groupId>
<artifactId>lifecycle-mapping</artifactId>
<version>1.0.0</version>
<configuration>
<lifecycleMappingMetadata>
<pluginExecutions>
<pluginExecution>
<pluginExecutionFilter>
<groupId>
org.apache.maven.plugins
</groupId>
<artifactId>
maven-dependency-plugin
</artifactId>
<versionRange>
[2.5.1,)
</versionRange>
<goals>
<goal>copy-dependencies</goal>
</goals>
</pluginExecutionFilter>
<action>
<ignore></ignore>
</action>
</pluginExecution>
</pluginExecutions>
</lifecycleMappingMetadata>
</configuration>
</plugin>
</plugins>
</pluginManagement>
</build>
</project>
When I run the HelloLog class in Eclipse all is good and I get the expected output. However, when I execute java -jar on the Jar file I receive the ClasNotFoundException on LogFactory at line 7. The jar file is accompanied in the target folder with the dependency-jars folder. The dependency-jars folder holds these two dependencies.
Found the problem, it was Maven related. Hadn't noticed my classpathPrefix was set as lib. Where as I outputted the dependencies to dependency-jars.

How to attach an artifact with assembly-plugin during custom lifecycle

i'm trying to create a plugin with a custom lifecycle :
/**
* #goal my-goal
* #execute lifecycle="my-custom-lifecycle" phase="attach-foo"
*/
public class MyMojo extends AbstractMojo {
...
with src/main/resources/META-INF/maven/lifecycle.xml file :
<lifecycles>
<lifecycle>
<id>attach-foo</id>
<phases>
<phase>
<id>package</id>
<executions>
<execution>
<goals>
<goal>
org.apache.maven.plugins:maven-assembly-plugin:single
</goal>
</goals>
<configuration>
<descriptorRefs>
<descriptor>adescriptor.xml</descriptor>
</descriptorRefs>
</configuration>
</execution>
</executions>
</phase>
</phases>
</lifecycle>
</lifecycles>
Assembly-plugin is called unfortunately the zip artifact generated is not attached and install in repo...
Any ideas ?
Thanks
Which version of the maven-assembly-plugin was used? Per the plugin docs, there is an optional parameter attach available in versions 2.2-beta-1 and later. The value defaults to true meaning the created artifact should end up in the repository.