Showing posts with label maven. Show all posts
Showing posts with label maven. Show all posts

Sunday, December 29, 2013

Dangers of mixing artifact versions across maven modules



Sometimes when a quickfix is urgently required, we are tempted to branch off and make it happen on our own until the authors of the original branch release their latest version. I found myself in such a situation and decided to only use the patched version for a small~ish maven module/artifact known in my project as "commons". What could go wrong? Well I ran into the following error at runtime:
java.lang.NoSuchMethodError: org.springframework.amqp.core.AmqpAdmin.declareQueue(Lorg/springframework/amqp/core/Queue;)Ljava/lang/String;
Turns out that my "commons" module was expecting to use a slightly different method signature than what was available in my main project:
// method signature from spring-amqp-1.3.0.BUILD-SNAPSHOT
String declareQueue(Queue queue);

// method signature from spring-amqp-1.2.0M1
void declareQueue(Queue queue);
So ... lesson learned :) push the authors to release quicker ;)

Saturday, December 28, 2013

Maven plugins & extensions for working with WSDLs, XSDs and POJOs

My favorite plugin for generating a webservice from a WSDL file (WSDL-first-approach) is Apache CXF because it loops in Spring, JAX-WS and other standards and implementations to make it happen.

Before CXF became by BFF I had gone looking for a maven archetype/template that would bring everything together for me in Eclipse. I did some templates but none that used the WSDL-first-approach to generate a sample project for me. So I gave up on looking for archetypes and instead followed a mix of instructions from the following links:
Anyway, CXF is awesome for the following reasons:
  • It is easy to configure cxf-codegen-plugin for generating a Java webservice code from a WSDL file.
  • It is easy to configure cxf-xjc-plugin for generating POJO (plain-old-java-objects) classes from a XSD (schema) file.
  • Other maven extensions can be used to enhance the cxf-xjc-plugin's schema to POJO conversion process:
    • Lets say you want to use something like a builder-pattern which makes your written code more beautiful. You can do that by configuring the jaxb-fluent-api extension!
    • If some of your POJOs share the same methods then not being able to categorize all those POJOs under a common interface can lead to duplicate code. For example, lets say you have a method named: performCommonTaskOnIncomingObject(ClassName argument) ... now you may need to have multiple such method with different names because you'll need to change the argument's classname everytime to match the object you're passing in!

Friday, March 18, 2011

Escape dollar sign in maven's pom.xml file

When you want to escape stuff like <hello>world</hello> in your maven pom.xml file, you can do so by following the basic XML conventions and writing it as &lt;hello&gt;world&lt;/hello&gt;

But for some reason escaping the dollar sign doesn't seem so simple. So one usually turns to Google for an answer ... BUT before you go running around integrating velocity with maven because the top Google search results for escaping a dollar sign lead you the FAQ at http://docs.codehaus.org/display/MAVENUSER/Assembly+Plugin ... please know that something as simple as writing $${show_me} works and results in ${show_me} being escaped!

Sunday, October 31, 2010

Generating UML Diagramns with Maven

  1. Install Graphviz. After installation confirm that it is part of your PATH.
  2. Configure your maven pom files to make sure that you can get to the following repository: http://mirrors.ibiblio.org/pub/mirrors/maven2 because it has the second piece of the puzzle, the binaries for UMLGraph. You can see all the options for use in <additionalparam/> here.
  3. To generate UML diagrams as part of the "mvn javadoc:javadoc" command, add the following (+/-) to your pom.xml file's <build/> section.
          <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-javadoc-plugin</artifactId>
            <configuration>
              <doclet>org.umlgraph.doclet.UmlGraphDoc</doclet>
              <docletArtifact>
                <groupId>org.umlgraph</groupId>
                <artifactId>doclet</artifactId>
                <version>5.1</version>
              </docletArtifact>
              <additionalparam>-views</additionalparam>
              <destDir>target/uml</destDir>
              <show>private</show>
            </configuration>
          </plugin>
  4. To generate UML diagrams as part of the "mvn site" command, add the following (+/-) to your pom.xml file's <reporting/> section.
      <reporting>
        <plugins>
          <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-javadoc-plugin</artifactId>
            <reportSets>
              <reportSet>
                <id>uml</id>
                <configuration>
                  <doclet>org.umlgraph.doclet.UmlGraphDoc</doclet>
                  <docletArtifact>
                    <groupId>org.umlgraph</groupId>
                    <artifactId>doclet</artifactId>
                    <version>5.1</version>
                  </docletArtifact>
                  <additionalparam>-views</additionalparam>
                  <destDir>target/uml</destDir>
                  <show>private</show>
                </configuration>
                <reports>
                  <report>javadoc</report>
                </reports>
              </reportSet>
            </reportSets>
          </plugin>
        </plugins>
      </reporting>
  5. That's it, you should now be reaping the benefits as your javadocs will have UML diagrams inside each class's landing page. I used the following post to put all this info together: http://wiki.wsmoak.net/cgi-bin/wiki.pl?UMLGraph

Thursday, August 12, 2010

Hudson: Deploy to container based on a schedule

Challenges:
1) The schedules in Hudson jobs apply to Build Triggers. There isn't any separate place to specify a schedule for Post Build Actions like Deploy war/ear to a container.
2) A job without any build information and only deployment info, will not run the Post Build Actions.
3) Cloning an existing job only for the sake of changing the schedule for deployment will mean throwing off the Hudson build numbers placed inside of your artifacts. Even if you un-check the Archive the artifacts option in the cloned job's configuration it will be meaningless ... the clone's artifacts will continue to be published/installed into your local repository over the original ones by maven itself.
4) The clone might get associated as a downstream job and therefore would end up running whenever your original job had finished running. This would make the custom schedule pointless!

Solutions:
  1. Clone the job for which you want to schedule deployments.
  2. If you are using a pom.xml which is set up to use child modules then just directly have the cloned configuration reference the pom.xml of the child which actually puts together the war/ear artifact ... instead of the main parent project's pom.xml file.
  3. Uncheck the following option from the clone's configuration to decouple the upstream/downstream relationship if there is any:
    Build whenever a SNAPSHOT dependency is built
  4. Within the pom.xml file which actually generates your war/ear artifact, place the cargo plugin and its configuration to deploy remotely.
    1. It wouldn't hurt to start with the original documentation for reference on how to do this exactly. But it doesn't talk about the most crucial part which is the use of the cargo.tomcat.manager.url property which is covered in this blog. It is a very good example on how to do this.
    2. Since you are going to commit the altered pom.xml file you may be worried about the side-effects on your original job that performs the build. Well if you build only runs up to the install phase, you don't have to worry about anything as cargo goals are not part of the maven lifecycle up until that point. Everything about your original build will continue to work as it did.
    3. You can also check This build is parameterized and specify string parameters so that you don't have to go changing your pom.xml everytime that your source location of the war/ear file changes or the tomcat that you want to deploy to changes. Here's a sample (+/-)
        <properties>
          <artifactFileLocation>${ARTIFACT_FILE_LOCATION}</artifactFileLocation>
          <remoteTomcat>${REMOTE_TOMCAT_URL}</remoteTomcat>
        </properties>
        ...
            <plugin>
              <groupId>org.codehaus.cargo</groupId>
              <artifactId>cargo-maven2-plugin</artifactId>
              <configuration>
                <!-- Container configuration -->
                <container>
                  <containerId>tomcat6x</containerId>
                  <type>remote</type>
                </container>
                <!-- Configuration to use with the container -->
                <configuration>
                  <type>runtime</type>
                  <properties>
                    <cargo.tomcat.manager.url>${remoteTomcat}/manager</cargo.tomcat.manager.url>
                    <cargo.remote.username>username</cargo.remote.username>
                    <cargo.remote.password>password</cargo.remote.password>
                  </properties>
                </configuration>
                <!-- Deployer configuration -->
                <deployer>
                  <type>remote</type>
                  <deployables>
                    <deployable>
                      <location>${artifactFileLocation}</location>
                      <pingURL>${remoteTomcat}</pingURL>
                    </deployable>
                  </deployables>
                </deployer>
              </configuration>
            </plugin>
    4. Come to think of it, username and password would also benefit from being parameterized.
  5. Take advantage of the new configuration in your artifact generating pom.xml file by configuring the following goal in Hudson for the cloned job:
    org.codehaus.cargo:cargo-maven2-plugin:deployer-redeploy

Monday, August 2, 2010

Versioning Flex Applications: Displaying Hudson, Maven, SVN build or revision numbers

Hudson sets the values for the following environment variables:
  1. BUILD_NUMBER
  2. SVN_REVISION
In order to show the build and revision numbers in the UI, these variables could be written out to a properties file via a maven project's pom.xml file using a plugin. And then if one did this early enough in the maven lifecycle, your flex application could be compiled to read the version information as key-value pairs from the properties file and show the info on screen when it runs.

Alas there is no decent maven plugin out there to write environment variables out to a file. I found the following plugins out there but none of them (+/-) did the trick.
  1. org.codehaus.mojo:properties-maven-plugin can be found in the following repo You can find proper documentation here. It never printed anything but the Java system level variables so it was useless when it came to tracking the environment variables set by Hudson.
  2. org.sonatype.plugins:maven-properties-plugin can be found in the following repo but this isn't the one you want to use. It has only one goal called filter-file and I cannot find any page documenting its usage no matter how hard I try.
  3. Even placing the info generated by the mvn help:system command-line invocation seemed like a decent idea. But after configuring the same command to be invoked inside a pom file(+/-) I realized that it spit out some header lines that weren't commented out in a manner suited for a properties file.
          <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-help-plugin</artifactId>
            <version>2.1.1</version>
            <executions>
              <execution>
                <phase>generate-resources</phase>
                <goals>
                  <goal>system</goal>
                </goals>
                <configuration>
                  <output>${basedir}/src/locale/app.properties</output>
                </configuration>
              </execution>
            </executions>
          </plugin>

You can resort to usind the ant plugin inside Maven to do a macro-style replace technique. You can read more about it here.

Or the best way is to have a template file (+-) and leverage Maven model like this (+-)
<?xml version="1.0" encoding="UTF-8"?>
<root>
<buildNumber>${buildNumber}</buildNumber>
<svnRevisionNumber>${svnRevision}</svnRevisionNumber>
</root>
<project >
  ...
  <!-- Map the values provided by the Hudson build to local variables -->
  <properties>
    <buildNumber>${BUILD_NUMBER}</buildNumber>
    <svnRevision>${SVN_REVISION}</svnRevision>
  </properties>
  ...
  <build>
    ...
    <!-- Update version.xml file with the versioning data -->
    <resources>
      <resource>
        <targetPath>${project.build.directory}/${project.artifactId}-${project.version}</targetPath>
        <filtering>true</filtering>
        <directory>${basedir}/src/main/resources</directory>
        <includes><include>version.xml</include></includes>
      </resource>
    </resources>
    ...
  <build>
  ...
<project >

Also as a sidenote: The Hudson variables can be placed inside the manifest file if your artifact being built happens to be a war or jar file. Read more on that here.

Links:
Home / Using Flex 4 / Developer tools / Flex compilers / Using mxmlc, the application compiler / Passing Strings
How to configure flexmojos to pass in compile time variables:
gmail thread
official docs


Thursday, July 29, 2010

How to do runtime property substitution for web.xml

  1. Place ${propertyName} in you web.xml file and specify the actual value via -DpropertyName=value (see a forum entry related to this...) also known as variable substitution.
  2. If you can afford to do this at compile time then:
    1. do so using a build tool such as maven (an example)
    2. Filter the web.xml file by configuring the maven-war-plugin as shown in the last post in this thread. There are some generic examples here too but they aren't as clear cut for the web.xml file.

Thursday, March 4, 2010

Hardly a Flex-ible Journey: Moving from Flex 4-Beta 2 to a Stable Build Or Nightly Build

  1. Search and replace all instances of 4.0.0.10485 with the desired version (4.0.0.13875 in my case) which hopefully has already been published to maven or you have uploaded to your local repository.
    1. com.adobe.flex:flex-framework and com.adobe.flex.framework:compiler were updated for me
  2. Change the version of your org.sonatype.flexmojos:flexmojos-maven-plugin to be 3.6-SNAPSHOT
    1. Usually the repository for this is the following one: http://repository.sonatype.org/content/groups/flexgroup/
    2. Make DAMN sure that in your repository definition you have the snapshots enabled set to true
  3. Some of the locale related SWC files are not published on the maven repositories but you can overcome that by downloading the SDK and uploading the missing files manually to your local maven repository.
  4. Don't forget to tell your Flash Builder IDE about the SDK ... Project > Properties > Flex Compiler > Use a specific SDK: Flex 4.0 (build 13875)
  5. Replace all instances of xmlns:mx="library://ns.adobe.com/flex/halo" with xmlns:ns="library://ns.adobe.com/flex/mx" using your favorite tool, mine is pspad.
  6. Replace all instances of mx: with ns:
  7. Follow the instructions from this post to get your code compiling. Note: I said compiling ... not functioning!
  8. Update your injection libraries if you use any. I use Parsley so I went and downloaded parsley-2.2.0 and YES if you use maven then you also need to update the parsley version in pom.xml in order to use it.

Wednesday, March 3, 2010

Sun "internal" packages: Maven vs Eclipse

When working with any java classes that have the word "internal" in their package name you'll notice that your build will compile just fine in Eclipse but fail when compiled via Maven.

If you want an intelligent guess at why this may be happening, you can refer to this useful post which talks about this issue in more detail.