I've written a Maven plugin and incorporated it as a goal in the package phase of another project with configuration given in that project's pom.xml. However, none of the fields set using the #parameter notation end up being populated so they just throw NullPointerExceptions when they get used.
My mojo:
/**
* #goal wrap
* #phase package
*/
public class MyMojo extends AbstractMojo {
/**
* #parameter expression="${project.build.directory}"
*/
private String outputDirectory;
/**
* #parameter
*/
private String dbDataName;
private File dbFile;
public MyMojo(){
dbFile = new File(outputDirectory, dbDataName) // throws nullpointerexception
}
public void execute() throws MojoExecutionException{
// Do stuff
}
}
Some of the mojo pom:
<groupId>com.mycompany.wrapper</groupId>
<artifactId>something-maven-plugin</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>maven-plugin</packaging>
...
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-plugin-plugin</artifactId>
<version>3.2</version>
<configuration>
<skipErrorNoDescriptorsFound>true</skipErrorNoDescriptorsFound>
</configuration>
<executions>
<execution>
<id>mojo-descriptor</id>
<goals>
<goal>descriptor</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
The relevant bit of my project pom:
<plugin>
<groupId>com.mycompany.wrapper</groupId>
<artifactId>something-maven-plugin</artifactId>
<version>1.0-SNAPSHOT</version>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>wrap</goal>
</goals>
<configuration>
<dbDataName>dcbTestData.sql</dbDataName>
</configuration>
</execution>
</executions>
</plugin>
Can anyone see what I'm doing wrong here? Most likely it's some silly mistake that I'm just not seeing.
I've solved the problem. I had done a few things wrong but after changing and tinkering, I managed to work it out.
Incidentally, this process was made rather harder by the fact that the Maven docs and user guides are a bit inconsistent about whether they prefer the annotations or the javadocs styles, and in some places they recommend deprecated methods, such as the expression="${stuff}" form.
Anyway to get it working:
I corrected the mistakes pointed out by khmarbaise in his first comment where I had slightly mangled the maven-plugin-plugin definition in my pom.
I updated to the Java annotations based way of denoting Mojos and parameters (it might have worked if I had done step 3 without doing this step, but it still seemed a good idea to update)
The main problem was that I was trying to access the parameter variables in the constructor to assign values to other variables but the mojo doesn't pick up the configuration details until the execute() method is run. So I just moved any variable assignments that used the parameters to the start of the execute() method and then they worked.
So here's what my mojo looks like now:
#Mojo(name = "wrap", defaultPhase = LifecyclePhase.PACKAGE)
public class MyMojo extends AbstractMojo {
#Parameter(property="project.build.directory")
private File outputDirectory;
#Parameter(property="dbDataName")
private String dbDataName;
private File dbFile;
public void execute()
throws MojoExecutionException {
dbFile = new File(outputDirectory, dbDataName);
// Do other stuff
}
}
You should change your code like the following:
/**
* #parameter default-value="${project.build.directory}"
*/
private String outputDirectory;
Related
My goal is read a parameter's value from costom Maven Plugin
during the processing of process, I need this value to determine whether to process annotations.
Here is what i done:
customize a maven plugin to configure the parameter of funProcess
#Mojo(defaultPhase = LifecyclePhase.COMPILE, threadSafe = true,
requiresDependencyResolution = ResolutionScope.COMPILE)
public class PamirsFunctionMojo extends AbstractMojo {
#Parameter
private Boolean funProcess;
#Override
public void execute() throws MojoExecutionException, MojoFailureException {
//todo
this.getPluginContext().put("funProcess", funProcess);
}
}
this is my maven-plugin's definition.
<groupId>pro.xxx.pamirs.plugin</groupId>
<artifactId>pamirs-maven-plugin</artifactId>
<packaging>maven-plugin</packaging>
<version>2.0.0-SNAPSHOT</version>
Build a project to process annotation #Fun which is defined in method. So,I need to define A Annotation Processor through extends AbstractProcessor,handle the method corresponding to this #Fun annotation in the process interface.
Using the value in my Annotation Processor.
I need the value of funProcess which is configured within the pom of business project which relying on this Annotation Processor project, then using the value to determine whether to process annotations In the Annotation Processor project.
The test project will rely on annotation processing projects and my maven-plugin.
This is the POM definition .
<dependencies>
<dependency>
<groupId>pro.xxx.pamirs.annotation</groupId>
<artifactId>annotation-processor</artifactId>
<version>1.0.0-SNAPSHOT</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>pro.xxx.pamirs.plugin</groupId>
<artifactId>pamirs-maven-plugin</artifactId>
<version>2.0.0-SNAPSHOT</version>
<executions>
<execution>
<configuration>
<funProcess>false</funProcess>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</dependency>
I want to know how to get the value in my Annotation Processor.
I have a case that i have 35 classes that some of them related with each other inside of them. Such as;
Addendum.java
#XmlType(name="addendum",namespace= GenericNameSpaceConstants.POLICY_NAMESPACE_URI)
#XmlAccessorType(XmlAccessType.FIELD)
public class Addendum implements Serializable {
#XmlElement(name="changeNumber",nillable=false,required=true)
private Long changeNumber;
#XmlElement(name="changeTypeDesc",nillable=false,required=true)
private String changeTypeDesc;
#XmlElement(name="changeTypeId",nillable=false,required=true)
private Integer changeTypeId;
}
Policy.java
#XmlRootElement(name="policy",namespace=GenericNameSpaceConstants.POLICY_NAMESPACE_URI)
#XmlType(name="policy",namespace= GenericNameSpaceConstants.POLICY_NAMESPACE_URI)
#XmlAccessorType(XmlAccessType.FIELD)
public class Policy {
#XmlElement(name="addendum",required=true,nillable=false)
private Addendum addendum;
}
My jaxb schemage config in pom file like that
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>jaxb2-maven-plugin</artifactId>
<version>2.2</version>
<configuration>
<createJavaDocAnnotations>false</createJavaDocAnnotations>
<sources>
<source>
${project.basedir}\src\main\java\com\aegon\common\service\bean\
</source>
</sources>
<verbose>true</verbose>
<outputDirectory>${basedir}/src/main/resources/schemas</outputDirectory>
<transformSchemas>
<transformSchema>
<toPrefix>pol</toPrefix>
<toFile>policy_model_v2.xsd</toFile>
</transformSchema>
</transformSchemas>
<generateEpisode>true</generateEpisode>
</configuration>
<executions>
<execution>
<phase>generate-resources</phase>
<goals>
<goal>schemagen</goal>
</goals>
</execution>
</executions>
</plugin>
When i run the project for phase generate-resources or generate-sources. I am getting this error Addendum is a non-static inner class, and JAXB can't handle those.
How can i resolve this problem?? How can i generate all classes xsd in a simple xsd Or how can i create xsds' one by one and import to complex one
I have found the problem. every class need a default constructor
I am not getting how do you use JavaDocs, with Spring Auto Rest Docs. I can generate my java-docs locally by using STS, UI option. However,i am not sure how to generate java-docs using Spring Auto Rest Docs. I tried writing some plugin in POM. But the auto-description.adoc and many other doc are still empty.
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-javadoc-plugin</artifactId>
<version>2.10.3</version>
<executions>
<execution>
<id>attach-javadocs</id>
<goals>
<goal>jar</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-javadoc-plugin</artifactId>
<version>3.0.0</version>
<extensions>true</extensions>
<executions>
<execution>
<id>attach-javadocs</id>
<goals>
<goal>jar</goal>
</goals>
<configuration>
<!-- switch on dependency-driven aggregation -->
<includeDependencySources>true</includeDependencySources>
</configuration>
</execution>
<execution>
<id>generate-javadoc-json</id>
<phase>compile</phase>
<goals>
<goal>javadoc-no-fork</goal>
</goals>
<configuration>
<doclet>capital.scalable.restdocs.jsondoclet.ExtractDocumentationAsJsonDoclet</doclet>
<docletArtifact>
<groupId>capital.scalable</groupId>
<artifactId>spring-auto-restdocs-json-doclet</artifactId>
</docletArtifact>
<additionalparam>
-d ${project.build.directory}/site/doccheck
</additionalparam>
<reportOutputDirectory>${project.build.directory}</reportOutputDirectory>
<useStandardDocletOptions>false</useStandardDocletOptions>
<show>package</show>
</configuration>
</execution>
</executions>
</plugin>
Basically I am not getting how to make Spring Auto Rest Docs use Java Docs to find Path Parameters. I can use mvn javadoc:javadoc command on terminal to create Javadocs whch are created in target/site/apidocs/ folder. But I still get No parameters in my auto-path-parameters.adoc
Here is the controller, I am using GraphQL so its different:
/**
* Query Controller Class
* #author shantanu
*
*/
#RestController
#RequestMapping(value="/graphql")
public class QueryController {
#Value("classpath:/graphql/actionItm.graphqls")
private Resource schemaResource;
private GraphQL graphQL;
#Autowired
#Qualifier("graphQLDate")
private GraphQLScalarType Date;
#Autowired
private AllActionItemsDataFetcher allActionItemsDataFetcher;
#Autowired
private ActionItemDataFetcher actionItemDataFetcher;
#Autowired
private PageActionItemDataFetcher pageActionItemDataFetcher;
#PostConstruct
public void loadSchema() throws IOException {
File schemaFile = schemaResource.getFile();
TypeDefinitionRegistry typeRegistry = new SchemaParser().parse(schemaFile);
RuntimeWiring wiring = buildRuntimeWiring();
GraphQLSchema schema = new SchemaGenerator().makeExecutableSchema(typeRegistry, wiring);
graphQL = GraphQL.newGraphQL(schema).build();
}
private RuntimeWiring buildRuntimeWiring() {
return RuntimeWiring.newRuntimeWiring()
.type("Query", typeWiring -> typeWiring
.dataFetcher("findAllActionItems", allActionItemsDataFetcher)
.dataFetcher("findActionItem", actionItemDataFetcher)
.dataFetcher("pageActionItems", pageActionItemDataFetcher))
.scalar(Date)
.build();
}
/**
* This
* #param query Description
* #return ResponseEntity responseEntity
*/
#PostMapping
public ResponseEntity query(#RequestBody String query) {
ExecutionResult result = graphQL.execute(query);
return ResponseEntity.ok(result.getData());
}
}
I am not getting where I am wrong, with the path-parameters. And only the .adoc files are generated with Spring Auto Rest Docs, and no JSON files.
Guys, I'm trying to obfuscate a .jar application using the proguard-maven-plugin.
When I try to perform the obfuscate process, I get error messages stating that there are unexpected classes.
I'm using the Spring Boot 1.4.1.RELEASE and Proguard Maven Plugin 2.0.13.
This is my proguard.conf
-injars /workspace/base/target/test-1.0.0.jar
-libraryjars /Library/Java/JavaVirtualMachines/jdk1.8.0_101.jdk/Contents/Home/jre/lib/rt.jar
-dontshrink
-dontoptimize
-dontobfuscate
-dontusemixedcaseclassnames
-keepattributes Exceptions,InnerClasses,Signature,Deprecated,SourceFile,LineNumberTable,LocalVariable*Table,*Annotation*,Synthetic,EnclosingMethod
-adaptresourcefilenames **.properties
-adaptresourcefilecontents **.properties,META-INF/MANIFEST.MF
-dontpreverify
-verbose
-keepclasseswithmembers public class * {
public static void main(java.lang.String[]);
}
-keepclassmembers enum * {
public static **[] values();
public static ** valueOf(java.lang.String);
}
-keep class * extends java.beans.BeanInfo
-keep class * {
void set*(***);
void set*(int,***);
boolean is*();
boolean is*(int);
*** get*();
*** get*(int);
}
-assumenosideeffects public class java.lang.System {
public static long currentTimeMillis();
static java.lang.Class getCallerClass();
public static int identityHashCode(java.lang.Object);
public static java.lang.SecurityManager getSecurityManager();
public static java.util.Properties getProperties();
public static java.lang.String getProperty(java.lang.String);
public static java.lang.String getenv(java.lang.String);
public static java.lang.String mapLibraryName(java.lang.String);
public static java.lang.String getProperty(java.lang.String,java.lang.String);
}
The pom.xml file. I am only informing the configuration by the plugin.
<plugin>
<groupId>com.github.wvengen</groupId>
<artifactId>proguard-maven-plugin</artifactId>
<version>2.0.13</version>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>proguard</goal>
</goals>
</execution>
</executions>
<configuration>
<obfuscate>false</obfuscate>
<outFilter>**/BOOT-INF/classes/ **.class</outFilter>
<proguardInclude>${basedir}/proguard.conf</proguardInclude>
<outputDirectory>${project.build.directory}</outputDirectory>
<injar>${project.build.finalName}.jar</injar>
<outjar>${project.build.finalName}-min.jar</outjar>
</configuration>
</plugin>
However, during the execution process I get the following return for all classes in my application.
Warning: class [BOOT-INF/classes/br/com/base/BaseApplication.class] unexpectedly contains class [br.com.base.BaseApplication]
Warning: class [BOOT-INF/classes/br/com/base/controller/CaixaController.class] unexpectedly contains class [br.com.base.controller.CaixaController]
[...]
And the final output of ProGuard. PS: All classes are in the BOOT-INF/classes directory
Warning: there were 97 classes in incorrectly named files.
You should make sure all file names correspond to their class names.
The directory hierarchies must correspond to the package hierarchies.
(http://proguard.sourceforge.net/manual/troubleshooting.html#unexpectedclass)
If you don't mind the mentioned classes not being written out,
you could try your luck using the '-ignorewarnings' option.
Please correct the above warnings first.
Can anyone imagine any alternatives I can try?
Thanks.
In order to fix this, I made sure to change the order of the plugins in the pom. The proguard plugin should go first, followed by the spring boot plugin.
Additionally, make sure you have the <goal>repackage</goal> specified in the spring boot configuration. With the correct order and the repackage goal specified, the proguard obfuscation/optimization/whatever you have configured will take place and produce a jar. Then the spring boot plugin will repackage that jar as an executable and everything should work.
My plugin configuration from pom.xml:
<project ...>
....
<plugin>
<groupId>com.github.wvengen</groupId>
<artifactId>proguard-maven-plugin</artifactId>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>proguard</goal>
</goals>
</execution>
</executions>
<configuration>
<proguardInclude>${basedir}/proguard.conf</proguardInclude>
<libs>
<lib>${java.home}/lib/rt.jar</lib>
<lib>${java.home}/lib/jce.jar</lib>
</libs>
</configuration>
</plugin>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<executions>
<execution>
<goals>
<goal>repackage</goal>
</goals>
<configuration>
<start-class>org.springframework.boot.loader.JarLauncher</start-class>
</configuration>
</execution>
</executions>
</plugin>
...
I am using Maven with surefire plugin to run TestNG test by extending AbstractTestNGSpringContextTests and it appears the context is not loaded even if it is in classpath, and the test works correctly inside my ide, but not in maven.
#ContextConfiguration(locations =
Array("classpath*:/com/gottex/gottware/server/offlinepuwithdummydatafeed.xml"))
My xml is under src/test/com/gottex/gottware/server
My parent pom contains:
<build>
<defaultGoal>package</defaultGoal>
<testResources>
<testResource>
<directory>src/test/java</directory>
<includes>
<include>**/*.xml</include>
<include>**/*.properties</include>
</includes>
</testResource>
</testResources>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.9</version>
<configuration>
<verbose>true</verbose>
<forkMode>never</forkMode>
</configuration>
</plugin> ...
and my children pom does not contain anything if not dependencies..
After a long debugging session, I was finally able to find the problem. It lies at ClassLoader level, and it exhibits itself when debugging
org.springframework.core.io.support.PathMatchingResourcePatternResolver
inside the method findAllClassPathResources
protected Resource[] findAllClassPathResources(String location) throws IOException {
String path = location;
if (path.startsWith("/")) {
path = path.substring(1);
}
Enumeration resourceUrls = getClassLoader().getResources(path);
Set<Resource> result = new LinkedHashSet<Resource>(16);
while (resourceUrls.hasMoreElements()) {
URL url = (URL) resourceUrls.nextElement();
result.add(convertClassLoaderURL(url));
}
return result.toArray(new Resource[result.size()]);
}
This is done when the context is loaded, and produce the following result:
When you run inside idea, the ClassLoader is java.net.URLClassLoader and this works correctly
When runnigng tests throuh Maven-Surefire plugin, a different classloader is used: ClassRealm[plugin>org.apache.maven.plugins:maven-surefire-plugin:2.9,
parent: sun.misc.Launcher$AppClassLoader#61ba34f2]
The second classLoader returns a enumeration resourceUrls with no "moreElements" and therefore the context is not loaded, but no failure is thrown by the framework.