Skip to main content

Maven note: exec-maven-plugin

I'm currently working on a development package containing a series of .xsd files which will be used to define the external interface for our web service. Due to some other project constraints, it was decided that this package also needed to include the .wsdl files which will further define the web service.

I'm a lazy (the good kind) programmer, so I decided that I did not want to update these files every time the schema changed nor did I want to make anyone else figure it out later. I wrote a quick utility for creating the .wsdl files, based on the current .xsd files. Since we're already expecting to use Spring-WS for message dispatching, I wrote some file generation code around the org.springframework.ws.wsdl.wsdl11.DefaultWsdl11Definition class and wrote up a Spring configuration which put it all together.

My next task was to figure out a way to get this utility to run within the context of the Maven package phase. Since the code needed to generate the .wsdl files was the only code in this development package, it made sense to hook into the prepare-package phase instead of the generate-sources phase. Now that I knew when the utility should run, I just needed to figure out a way to do it. One Google search later, and I had the exec-maven-plugin. This Maven plugin provides two goals which can be hooked into arbitrary phases in the Maven life cycle:

  • exec -- execute an arbitrary executable from within the Maven runtime
  • java -- execute the main method, with arguments, of a specified class, from within the Maven runtime

So I set up my pom as shown below, and ran mvn package. The end result was a .jar file which contained both the .xsd and the .wsdl files we need. One mvn deploy later and these files were now available to all who needed them.

pom.xml

<project>
  ...
  <build>
    <plugins>
      <plugin>
        <groupId>org.codehaus.mojo</groupId>
        <artifactId>exec-maven-plugin</artifactId>
        <version>1.2</version>
        <executions>
          <execution>
            <phase>prepare-package</phase>
            <goals>
              <goal>java</goal>
            </goals>
          </execution>
        </executions>
        <configuration>
          <mainClass>my.utility.ClassName</mainClass>
          <arguments>
            <argument>${project.build.outputDirectory}</argument>
          </arguments>
        </configuration>
      </plugin>
    </plugins>
  </build>
  ...
</project>

Comments

Jaco Greyling said…
Thanks for the update - I am trying to do exactly that as well and this is pointing me in the right direction.

If I may ask - have you come across something something similar. I received an XSD and with JAXB generated the 282 Java classes, but these classes must be persisted into a DB (using JDO) when we unmarshal the XML files. That's the rule...

Currently I have written a small Java class to add @PersistenceCapable to the required generated classes. So "exec-maven" will greatly assist me in automating the process, as the XSD would probably change only once every 2 years.

I wrote the Java class because I can not seem to get annox-maven / hyperjaxb3 or datanucleus to help me out, meaning make the generated classes JDO persistent? Ideas?
Ryan Ransford said…
Sorry, I'm unfamiliar adding annotations to classes pre-compile-time. To me, your annotation scheme sounds quite edge-case and will likely not rate a maven plugin. (a quick Google search seems to confirm this)

If you already have a class which does what you need, this should be the best way I know to integrate it with the maven build process.

Not knowing the rest of your application, would it be correct to assume that generating wrapper classes for the xjc-generated classes is impossible? That would be my ideal solution, I don't like to touch anything which is generated.

Popular posts from this blog

Using MonoDevelop to Create an ASP.NET Web Service

NOTE : instructions below are for MonoDevelop 2.6 Beta 2 - built on 2011-04-06 03:37:58+0000 Getting Started Create a new ASP.NET Web Application in MonoDevelop: From the menu, select: File → New → Solution… Expand C# . Select ASP.NET → Web Application . Enter a name for the ASP.NET project that will be created in the solution in Name: . Change the root location for the solution in Location: , if desired. Change the name of the root solution in Solution Name: , if desired. The Results – I What you have after executing the new ASP.NET Web Application project wizard is a solution containing one ASP.NET Web Application project. In the default project view in MonoDevelop, you'll find the following items: Default.aspx – This is the default web form rendered and presented in the browser when http://<server>:<port>/ is accessed. Default.aspx.cs – This C# file contains the developer-created common code and event handlers which can be used to affect the process

Testing Toolbelt: SpringJUnit4ClassRunner

The org.springframework.test.context.junit4.SpringJUnit4ClassRunner class is another implementation of the JUnit TestRunner class which is used to enable various features of Spring for every run of the test class and every test within it. To use the features provided by the SpringJUnit4ClassRunner class, you need to mark the class using the RunWith annotation using SpringJUnit4ClassRunner as its parameter. In addition to the custom test runner, you will want to mark the class with the ContextConfiguration annotation. The ContextConfiguration annotation is used to mark classes which will automatically read a Spring configuration file and use it to create an ApplicationContext . By default, this file located at <package path>/<test class name>-context.xml . Use the locations argument to over-ride. The ApplicationContext used by the Spring-integrated test will only be loaded once for the whole test class. This behavior can be over-ridden by annotating a test metho