Category Archives: Maven

Maven file structure basics

This is an old blog post that sat in draft for years, int looks complete, so I thought I’d publish it. Hopefully it’s still upto date.

As I’m working in Java again and using Maven a lot to get my projects up and running. Whilst I’ve covered some of this stuff in other posts, they’ve tended to be part of working with some specific code. So this post is mean’t to be more about using Maven itself.

Maven convention file structure

By default the following file structure is expected

/src/main/java
/src/main/resources
/src/test/java

Optionally we might have the test/resources

/src/test/resources

POM starting point

Maven (be default) expects a file name pom.xml to exist which contains version information and may include plugins, code generation, dependencies etc.

<?xml version="1.0" encoding="UTF-8"?>
<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>com.putridparrot.common</groupId>
    <artifactId>JsonPatch</artifactId>
    <version>1.0-SNAPSHOT</version>
</project>

Naming conventions (see references)

groupId – “identifies the project uniquely across all projects” hence might best be represented by the package name.
artifactId – is the name of the JAR
version – standard numbers with dots, i.e. 1.0, 1.0.1 etc. This is a string so in situations where we want a version to include the word SNAPSHOT (for example)

Maven commands

Before we get into more POM capabilities, let’s look at the basic set of Maven command’s we’ll use most.

Compiling to specific Java versions

<properties>
   <maven.compiler.source>1.8</maven.compiler.source>
   <maven.compiler.target>1.8</maven.compiler.target>
</properties>

OR

<build>
   <plugins>
      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-compiler-plugin</artifactId>
        <version>3.7.0</version>
        <configuration>
          <source>1.8</source>
          <target>1.8</target>
        </configuration>
      </plugin>
    </plugins>
</build>

References

Guide to naming conventions on groupId, artifactId and version
Setting the -source and -target of the Java Compiler

cxf-codegen-plugin not generating proxies everytime

In case this helps others out…

I am working on a Java project at the moment using Maven to build the code and run tests etc. I’m also using the cxf-codegen-plugin plugin (as below) to generate some proxies for a soap/wsdl file I have.

<plugin>
   <groupId>org.apache.cxf</groupId>
   <artifactId>cxf-codegen-plugin</artifactId>
   <version>3.2.2</version>
   <executions>
      <execution>
         <id>generate-sources</id>
         <phase>generate-sources</phase>
         <configuration>
         <wsdlOptions>
            <wsdlOption>
               <wsdl>${project.basedir}/src/main/resources/wsdl/Svc.wsdl</wsdl>
               <wsdlLocation>classpath:wsdl/Svc.wsdl</wsdlLocation>
               <extraargs>
                  <extraarg>-verbose</extraarg>
                  <extraarg>-client</extraarg>
                  <extraarg>-p</extraarg>
                  <extraarg>com.putridparrot.soap</extraarg>
               </extraargs>
            </wsdlOption>
         </wsdlOptions>
         </configuration>
         <goals>
            <goal>wsdl2java</goal>
         </goals>
      </execution>
   </executions>
</plugin>

I found that when I tried to either use mvn generate-sources mvn install the generated source folder was deleted and recreated, however the proxies folder had no proxy code/files (i.e. the files were deleted and not regenerated).

If I ran mvn clean install the proxy code would re-appear, but subsequent calls to generate-source of install would again delete the proxy code/files.

To cut a long story short it appeared that another plugin was clearing out the generated-sources folder but the cxf-codegen-plugin plugin would not regenerate it’s proxy code/files because of another file which the plugin created in the cxf-codegen-plugin-markers folder.

Within this folder is a file with a UUID style name. This was being plugin used by the plugin to check whether it needed to regenerate it’s proxy code/files (it doesn’t check if the files exist or simply regenerate them each time it’s run).

You can recreate the problem easily by running mvn generate-sources to create the proxies, then delete the generated-sources folder and run mvn generate-sources again. No proxy files are created. Now delete the marker file and the proxies will get regenerated.

Deleting this folder (or just the file within it) will fix the problem.

To stop this happening again you can either ensure the folder or file are deleted when the generate-sources folder is deleted or even simpler just write your proxies to another folder, so this would now get deleted by the other plugins.

i.e.

<configuration>
   <sourceRoot>${project.build.directory}/cxf</sourceRoot>
   <!-- other config -->
</configuration>

Running a maven plugin

Occasionally you might want to run a maven plugin without building/installing etc. at the same time – for example I am using wsdl2java to generate proxies for webservice and every now and then I want to just regenerate those proxies.

We can simply run

mvn antrun:run@your_execution_id

Creating Java classes from an XML schema using Maven

I my previous post Creating Java classes from an XML schema I used xjc to generate the Java classes for a small project.

Ultimately I try to automate my tasks as much as possible and also don’t want to have to write a document with lots of steps when passing code onto others to use. So I decided it was time to get Maven to (as part of it’s process) automatically generate the classed for me using xjc.

So now when passing my app. to somebody else to take on, I just say run mvn install and it’ll do everything else for you.

To get this to work we need to use the xjc/jaxb-2 plugin.

In your pom.xml, add the following

<build>
   <pluginManagement>
      <plugins>
         <plugin>
           <groupId>org.apache.maven.plugins</groupId>
           <artifactId>maven-compiler-plugin</artifactId>
           <configuration>
              <source>1.7</source>
              <target>1.7</target>
           </configuration>
         </plugin>
     </plugins>
   </pluginManagement>
   <plugins>
      <plugin>
         <groupId>org.codehaus.mojo</groupId>
         <artifactId>jaxb2-maven-plugin</artifactId>
         <version>1.6</version>
         <executions>
            <execution>
               <id>request-xsd</id>
               <goals>
                  <goal>xjc</goal>
               </goals>
               <configuration>
                  <packageName>com.putridparrot.request</packageName>
                  <schemaDirectory>src/main/resources/xsd/request-xsd</schemaDirectory>
                  <clearOutputDir>false</clearOutputDir>
               </configuration>
            </execution>
            <execution>
               <id>request-xsd</id>
               <goals>
                  <goal>xjc</goal>
               </goals>
               <configuration>
                  <packageName>com.putridparrot.response</packageName>
                  <schemaDirectory>src/main/resources/xsd/response-xsd</schemaDirectory>
                  <clearOutputDir>false</clearOutputDir>
               </configuration>
            </execution>
         </executions>
      </plugin>
   </plugins>
</build>

In the above example, I actually have a request xsd and a response xsd for a webservice call. The problem (and hence why I have two separate execution sections) is that they have duplicate type names, which meant if I had them both in the same folder would end up with conflicts and an error for the class generation.

Note: The folder xsd can be named anything you like and contain the XSD’s themselves or contain folders, as I’m using.

The jaxb2-maven-plugin does all the work for us, it executes xjc, creates the package for out resultant classes (i.e. com.putridparrot.request and com.putridparrot.response). It generates the classes from the schema in the schemaDirectory (i.e. all XSD’s within that directory) and it’s doesn’t clear the output folder. This is not important if you are not outputting to the source folder or don’t want the output folder cleared when maybe not regenerating everything within it, but it’s very useful to stop you accidentally deleting all your source (as I did whilst outputting to the src/main/java folder initially!).

If you do not specify and output directory then the classes will be generated into your target folder, within target/generated-sources/jaxb/<you package names>.

These files are then compiled into your application and available to use in your source.