3 ways to serialize Java Enums

This article shows you best practice for serializing Java enums to database (via Hibernate, JPA) or file. It discusses three ways to serialize enums with code examples, the pros and cons of each way and also recommends the best way. You should know this if you are serializing an Object with an enum field to a file or mapping a POJO to a database table using technologies like Hibernate or JPA.

What exactly is a Java enum constant? A Java enum is a sub-class of java.lang.Enum. An enum constant is simply an object instance of the enum class. The enum constructor must be private. Enum constants are created by the JVM via an invocation of the private constructor. Customizing the constructor signature is the most common way of adding more data to the enum class. You can add methods to the enum class just like any other class.

What does serialization and deserialization of enum mean? Serialization involves converting the enum to a value (usually primitive or a String) which can be easily stored on the disk or a database. Deserialization involves reading a stored value and converting it back to an enum. It is important to understand the different ways in which enum serialization and deserialization works. Sometimes ORM implementations (like Hibernate) may automatically do the enum serialization for you, however there are drawbacks to some of these approaches that you should know.

Let’s say we want to serialize the following enum

public enum Color {
 RED, GREEN, BLUE;
}

Following are 3 different approaches. The last approach is the most reliable way of serializing an enum class, however you should know approaches 1 and 2 so you can understand their drawbacks.

Approach 1: using the ordinal() value

Approach 2: using the name() value

Approach 3: Using a user defined business valueBest practice!

Approach 1: using the ordinal() value

Ordinal of an enum constant is the value is its position in its enum declaration. This is true for all enums. In the above example:

RED.ordinal()   == 0
GREEN.ordinal() == 1
BLUE.ordinal()  == 2

You can serialize the enum by converting the enum to its ordinal() value.

Color color = Color.GREEN;
int ordinal = color.ordinal(); // ordinal == 1
// save ordinal

At a later point, you can deserialize the saved int using the values() method on the enum which returns all the enum constants in the order in this they were declared.

// retrieve from saved value
Color savedColor = Color.values()[savedOrdinal];

This approach is simple and works. Some ORM implementations may automatically use this approach if you map your enum to and Integer column. However, the biggest drawback of this approach is that if new constants are introduced out of order then the serialized values will not be properly reconstructed.

Here’s the error scenario:

  1. Serialize an enum value Color.GREEN. Saved value gets stored as 1
  2. Developer adds a new color ORANGE between RED and GREEN
  3. The previously serialized value of 1 is now mapped to ORANGE.

Approach 2: using the name() value

The name() of any enum is the literal that is used to represent the enum constant in the Java program.

RED.name().equals("RED")
GREEN.name().equals("GREEN")
BLUE.name().equals("BLUE")

Serialize as follows:

Color color = Color.GREEN;
String savedValue = color.name();
// save value

Deserialize as follows:

Color savedColor = Color.valueOf(savedValue);

valueOf() is a built-in method which returns the enum constant with the specified specified name

This method works as well. Some ORM implementations may automatically use this approach if you map your enum to and String (char, varchar) column.The serialized form is String (as opposed to int in the previous example). The main drawback of this approach is that the serialized value, which can then be stored on disk or in database and can be persisted for a long term, is now dependent on a Java constant name. A developer may accidentally rename the constant name without realizing that it will make the previously serialized values unreadable.

Here’s the error scenario:

  1. Serialize an enum value Color.GREEN. Saved value gets stored as “GREEN”
  2. Developer renamed enum constant from Color.GREEN to Color.Green.
  3. The previously serialized value of “GREEN” can no longer be mapped to an existing color.

Approach 3: Using a user defined business value – Recommended approach!

This approach involves assigning a an explicit user defined value to each enum constant and defining a toValue() and fromValue() methods on the enum to do the serialization and deserialization.

public enum Color {
 RED("RED"), GREEN("GREEN"), BLUE("BLUE"), UNKNOWN("UNKNOWN");

 private final String value;

 Color(String value) {
   this.value = value;
 }

 public static Color fromValue(String value) {
   if (value != null) {
     for (Color color : values()) {
       if (color.value.equals(value)) {
         return color;
       }
     }
   }

   // you may return a default value
   return getDefault();
   // or throw an exception
   // throw new IllegalArgumentException("Invalid color: " + value);
 }

 public String toValue() {
   return value;
 }

 public static Color getDefault() {
   return UNKNOWN;
 }
}

This approach is better than approach 1 and approach 2 above. It neither depends on the order in which the enum constants are declared nor on the constant names.

To serialize:

Color color = Color.GREEN;
String savedValue = color.value();
// save value

To deserialize:

Color savedColor = Color.fromValue(savedValue);

Note: You can choose an Integer instead of String as a value, but remember this value must not change or you will be unable to retrieve you persisted values.

Mapping enum to database column using JPA/Hibernate

You can use any of the 3 approaches discussed above.

  1. Map the enum to an integer column. The persistence implementation should automatically convert enum to ordinal() and back for you.
  2. Map the enum to a String column. The persistence implementation should automatically convert the enum value to String value via the name() function.
  3. Map the enum using a business value. You should mark the enum field as @Transient, and create another String field which you can map to a String column in your database table. Here’s an example code snippet.
@Entity
public class Product {
 @Column
 private String colorValue;

 @Transient
 public Color getColor() {
  return Color.fromValue(colorValue);
 }

 public void setColor(Color color) {
  this.colorValue = color.toValue();
 }
}

Conclusion

We saw 3 different ways to serialized enums in this article. Approach 1 and 2 above use ordinal() and name() respectively, and require no additional work, but are inherently unsafe to use. The safest way is approach 3 which uses a custom user defined value as shown in the example above. When persisting enums with Hibernate/JPA first convert them to a user defined value.

Code Generation for Web Applications with Clickframes

What is Clickframes?

Clickframes is a Code Generation framework written in Java designed specifically to generate (Java) web applications.

Philosophy behind Clickframes

There are 2 aspects to a web application:

  1. What the application does.
  2. How it does it.

The key idea behind Clickframes is separation of these two concerns.

What the application can be defined by focusing on end user experience – what the end user sees, what the user clicks and so on. When users open a webapp in a browser they see a page, links, forms, inputs, content. They don’t see how the page was produced, which technology, framework or database was used on the back end. Defining what an application does boils does to defining a web page, after all a web application is most part is a collection of web pages linked to each other via links and form actions.

On the other hand, how an application is implemented consists of every little detail that happens “behind the scenes”. Which technology, platform and database is used, all the choices which result in a working application – but are never directly seen by the end user directly.

Clickframes separates these two aspects of the application by defining an application model called Appspec. Appspec is a rich data structure which represents the application behavior. The business analyst defines the application behavior using the Appspec model. The developer writes code generators to implement a generic Appspec and then runs them for the specific Appspec written by the business analyst. Appspec becomes a contract and a way of communication between the analyst and the developer. In the meantime QA takes the Appspec and writes tests against it. Appspec becomes a way of communication and the single source of truth for the various members of the team.

To give you a concrete sense of what I am talking about, let’s say that the Appspec has a page called “home”. The developer may choose to implement this using a simple jsp file “home.jsp”. The developer then generalizes this implementation and creates a code generator to produce a file called [page id].jsp for every page in the Appspec. Again, the philosophy being “if I can figure out how to implement one page, I can apply the same approach for all pages”. This approach implemented via a set of code generators applied against the application definition (or Appspec) is the key idea of the Clickframes approach. The result is an automatically generated application for a given target platform/technology (e.g. “jsp” in the previous example) which produces consistent code for the entire application. This code is produced using code generators at minute zero of your project, i.e. even before you start working on your project. You can then take the generated code and start customizing it. This is a great productivity boost as you can use the same code generators from one project to another as they are not specific to any particular application, but are written for the generic Appspec model for the given target technology/platform. Such code generators usually exists are code generation templates and are referred to as Clickframes Plugin.

Terminology

To recap the terminology:

Appspec (Application Specification) – Appspec is what the web application does, from an end user’s perspective. It essentially captures the behavior of the application. How many pages does the application have, how many forms does each page have. How many input fields on each page. What type of input fields (e.g. text, textarea, radio, dropdown). Are there any validation rules on the input fields (e.g. must be 8-12 characters, or must be a zipcode, must be a valid email format). What is the next page when the user submits a form on a page. How many links on the page, do the links point to another page in the application or an external link. The list goes on, but you get the idea.

Clickframes Plugin – Clickframes Plugin is a code generator, usually implemented by creating a set of templates, which inputs an Appspec and generates code. A plugin is usually a zip file consisting of dozens of templates written in plain text or velocity. Plugins can also be written or extended in Java using the Clickframes Plugin API.

Clickframes Plugin Authors – (Usually) Senior or Experienced developers who have a good understanding of the target technology create a plugin to implement the Appspec. Note that this activity needs to be done only once per technology. For example, once I have created a Seam2 plugin, you can generate any number of applications by simply writing an Appspec for your application and generate Seam code by using the plugin.

Target language/platform – Clickframes is a Code Generation framework that you use before you even start your project. It generates code that you then compile and run. Target platform refers to the platform on which the generate code runs. Example target platforms are Java/Tomcat, Java/Seam/JBoss, JSF/Tomcat, PHP. If you are willing to write your own code generation templates, you can generate code for any language/target platform.

Why Clickframes?

One advantage of Clickframes is that it acts as a medium of communication between the various members of the team.

However, the most powerful feature of Clickframes is the Clickframes Code Generation Plugins. Once you write a plugin for a technology or platform, you can instantly generate a full working application by simply writing the Appspec for that application and running the Clickframes Plugin on this Appspec . Writing an Appspec should be much easier than implementing the application itself.

Hello, World example

Let say an application has one page which has the text “Hello, World”. You can create the Appspec by either using the Java API or XML format.

Creating appspec via XML

<appspec>
  <pages>
    <page id="home">
     <contents>
      <content id="message1">Hello, world</content>
     </contents>
    </page>
  </pages>
</appspec>

Creating appspec via Java

Appspec appspec = new Appspec();
Page home = new Page();
Content message1 = new Content();
message1.setId("message1");
message1.setText("Hello, World");
home.getContents().add(message1);
appspec.getPages().addPage(home);

Clickframes sample JSP Plugin

Now lets build a simple JSP code generator. This code generator is just for the purpose of illustration and is not intended to be a real production quality plugin.

Create a file called ${page.id}.jsp. Since the file name consists of the variable ${page} this file will automatically be applied to all pages in the application.

Contents of ${page.id}.jsp below. All templates are written in Apache Velocity.

The ${page} variable passed to the template represents the Java object defined above.

<html>
 <body>
#foreach ($content in $page.contents)
  <div id="${content.id}">${content.text}</div>
#end
 </body>
</html>

Running this plugin against the above model will produce one file called “home.jsp” with the following content.

<html>
 <body>
  <div id="message1">Hello, World</div>
 </body>
</html>

You can now add a dozen pages to your application and reuse the same code generation template.

A more comprehensive demo

The above example is good to give you a quick sense of how the code generation works. However, real applications contains forms, links, inputs, actions, entities, databases and so on. The following example uses a JSF Seam2 plugin which is used to generate a simple Issue Tracker Application.

The best way to jump in and get your feet wet is by seeing and running the code. I have created a JSF Seam2 plugin which generates JSF2 and Seam based web applications.

Here’s the Appspec for the application and you can browse the generated code here. There is a hosted version of running demo at http://demo.clickframes.org/tracker/

1. Checkout the project code:

svn checkout http://clickframes-seam-issuetracker-demo.googlecode.com/svn/trunk/ clickframes-seam-issuetracker-demo

2. Run it:

cd clickframes-seam-issuetracker-demo
mvn glassfish:run

See the application run at:
http://localhost:8080/issuetracker/
You can type any login/password to login. The login module implemented by default does passes any input. In the future I plan modify the plugin to properly implement login.

Key demo features:

  • Security: pages with login-required=”true” will automatically prompt you for login.
  • AJAX input validation: inputs with validation will prompt you with an error as you type if the validation fails
  • Built-in CRUD implementation using in-memory database: actions marked with “update” or “create” will actually create an entity and store it in an in memory database

Note that this application is 100% generated directly from the Appspec. What is means is that you can modify the application behavior by modifying the Appspec and regenerate the application.

Regenerate:

mvn clickframes:generate

Can you really model every single thing about a web application?

No. Clickframes focuses on things which can be easily modeled. Even if you are able to capture 50% of the application features in the Appspec, you can generate a working application which implements 50% of requirement without writing a single line of code. That’s quite a jump in productivity. You can then hand code the remaining application the usual way.

Case for Clickframes

Clickframes is not for all web applications. If the Clickframes model fits your application model then I urge you to give Clickframes a try. With Clickframes you can produce consistent code for your entire application. You can bake the best practices right into the code generation templates. Moreover, you can use these templates from one project to another.

References and Links

Publishing to Maven Central Repo in 5 steps

Maven Central Repo is the official Maven repository where all “official” jars are published. It is also known as the “central” repo and is part of the super pom.xml which is implicitly included by every Maven project. The URL of the Maven Central Repo is http://repo1.maven.org/maven2/.

If you need to share your Maven artifacts with the world, you too can publish it on the official Maven repo! Let others discover your artifacts without any repository configuration. This article is intended to be a practical, step by step, easy to follow tutorial to publish your artifacts to the central repo.

Step 1: pom.xml configuration

  • Required elements: These elements must be present in your pom.xml: modelVersion, groupId, artifactId, packaging, name, version, description, url, licenses, scm url, dependencies
  • No <repositories> or <pluginRepositories> tag allowed. All you dependencies must be present in the central repo.
  • Choose a groupId that you own. Most common way to do this is to have control over the domain name corresponding to your groupId. For example, if your groupId is com.vineetmanohar then your must own or have control over the domain name vineetmanohar.com. This is required as maven will only download artifacts for a groupId from the corresponding domain.
  • You can only publish releases, not snapshots.

Step 2: Create your domain repo

This assumes that you have a hosted server somewhere which runs apache (or similar web server to host static files), and describes how to create a repo using by defining an path in a apache virtual server. If you have root access to the machine, Login as root and create a new user called ‘repo’

 # adduser repo
 # su - repo

As the repo user and create the repo directories.

# su - repo
$ cd /home/repo
$ chmod 755 .
$ mkdir -p html/releases html/snapshots

Now map this directory to apache

Map /home/repo/html/ to http://repo.<your domain>.com

Edit the /etc/httpd/conf/httpd.conf file and add the following mapping. Change IP address and server name as applicable. Remember that server name must match or should be a sub-domain of your groupId.

 <VirtualHost 215.12.34.111:80>
  <Directory /home/repo/html>
   Options +Indexes
   AllowOverride Limit
  </Directory>

  ServerName repo.vineetmanohar.com
  DocumentRoot /home/repo/html
  CustomLog "/home/repo/access_log" "combined"
  ErrorLog "/home/repo/error_log"
  SuexecUserGroup repo repo
 </VirtualHost>

Restart apache

/etc/init.d/httpd restart

Step 3: Publish artifacts to your repo

Add a <distributionManagement> section to your pom.xml. Here’s an example, change it to reflect your server names and paths.

<distributionManagement>
 <repository>
   <id>vineetmanohar-release-repo</id>
   <name>vineetmanohar.com Release Repo</name>
   <url>scp://repo.vineetmanohar.com/home/repo/html/releases/</url>
 </repository>

 <snapshotRepository>
   <id>vineetmanohar-snapshot-repo</id>
   <name>vineetmanohar.com Snapshot Repo</name>
   <url>scp://repo.vineetmanohar.com/home/repo/html/snapshots/</url>
 </snapshotRepository>
</distributionManagement>

Once you are ready to release, change your pom.xml version to a non-SNAPSHOT version, e.g. 0.0.1. Remember that if your version is a non-SNAPSHOT version, you cannot have any SNAPSHOT dependencies either, that’s just a universal maven rule.

Now deploy your version to your release repo.

mvn deploy

If you use scp to deploy (as in the example above) you will be asked to enter your password. Alternatively you can configure to SSH without password.

PS: Alternatively you can automatically increment version and deploy automatically by using the Maven Release plugin.

Step 4: Give permission to Maven to access your repo

The simplest way is to authorize Maven by adding its private key to your repo’s authorized ssh keys. Make sure that the permissions are set as described below.

# su - repo
$ mkdir -p .ssh
$ chmod 700 .ssh
$ cd .ssh
$ vi authorized_keys
<paste maven's public key in file authorized keys>
$ chmod 400 authorized_keys

Copy the contents of Maven’s public key and paste it in /home/repo/.ssh/authorized_keys

Step 5: Submit a request to the Maven folks

You have your artifacts published in a public repo and Maven has the permission to rsync your repo over SSH. All you need to do now is to submit a request to Maven to add your server to the list of servers they sync with.

Open an account at http://jira.codehaus.org, if you don’t have one already. Once you have created an account, submit your request here.

Here is an example request that I submitted. It took them 7 days to close the ticket, so be patient. After the ticket has been closed, it might take half a day for the servers to gets sync’d, after which I could see my artifacts appear here.

Reference

Linux command line puzzler

The file “hello.txt” shows up in directory listing via the “ls” command. The puzzler is about trying to display the contents on the file via the “cat” command.

Following is a real transcript demonstrating the puzzler.

$ whoami
vineet
$ ls -al
total 12
drwxr-xr-x  2 vineet vineet 4096 Nov 15 11:15 .
drwx------ 15 vineet vineet 4096 Nov 15 11:14 ..
-rw-r--r--  1 vineet vineet   42 Nov 15 11:14 hello.txt
$ cat hello.txt
cat: hello.txt: No such file or directory

Puzzler: Why can’t we display the contents of the file “hello.txt”?

Know the answer? Post your response below.

Tweet your builds with Maven Twitter Plugin

Introduction

Maven Twitter Plugin lets you send Twitter status updates from Maven, without writing any Java code. It increases communication between Project owners and Project users by automatically tweeting build and release status via Twitter.

Configuration

1. Add Plugin repository to your <build> <plugins> section in pom.xml

You need to add this to your list of existing plugin repositories.

<pluginRepository>
 <id>vineetmanohar-release-repo</id>
 <name>Vineet Manohar Release Repo</name>
 <url>http://repo.vineetmanohar.com/releases</url>
</pluginRepository>

2. Add your twitter username, password to your ~/.m2/settings.xml file

For security reasons, it is recommended that you put your twitter username and password in your local settings file.

<settings>
 <profiles>
  <profile>
   <id>default</id>
   <activation>
    <activeByDefault>true</activeByDefault>
   </activation>
   <properties>
    <twitterUsername>your twitter username</twitterUsername>
    <twitterPassword>your twitter password</twitterPassword>
   </properties>
  </profile>
 </profiles>
</settings>

Usage

Add the Twitter plugin to your <build> <plugins> section in pom.xml

Define the plugin as shown in example below.

<build>
 ...
 <plugins>
  <plugin>
   <groupId>com.vineetmanohar</groupId>
   <artifactId>maven-twitter-plugin</artifactId>
   <version>0.1</version>
   ...
  </plugin>
</plugins>

Now add one <execution> block to the above, for every Tweet you want to send per build. The <twitterStatus> config element defines your Twitter message and will be executed in the phase specified by the <phase> subelement.

<execution>
 <phase>...</phase>
 <configuration>
   <twitterStatus>...</twitterStatus>
 </configuration>
</execution>

You can define as many blocks as you want.

Example

This example send 2 tweets: one in the “test” phase and the other in the “deploy” phase.

<plugin>
 <groupId>com.vineetmanohar</groupId>
  <artifactId>maven-twitter-plugin</artifactId>
  <version>0.1</version>
  <executions>
   <!-- phase: test -->
   <execution>
    <id>test-passed</id>
    <configuration>
     <!-- anything you want, upto 140 chars -->
     <twitterStatus>My first tweet from using #maven twitter plugin</twitterStatus>
    </configuration>
    <phase>test</phase>
    <goals>
     <goal>tweet</goal>
    </goals>
   </execution>

   <!-- phase: deploy -->
   <execution>
    <configuration>
     <!-- Tell your users that the project is deployed -->
     <twitterStatus>Version ${project.versionId} of XYZ deployed</twitterStatus>
    </configuration>
    <id>deploy</id>
    <phase>deploy</phase>
    <goals>
     <goal>tweet</goal>
    </goals>
   </execution>
  </executions>
</plugin>

FAQ

What can I put under the <twitterStatus> element

  • static text
  • You can be creative and put variables related to your project. ${project} maps to the Maven Project Model. Examples are ${project.groupId}, ${project.artifactId}, etc
  • You can put hash tags by simply putting # before a word
  • You can put @usernames directing the message to a specific twitter account
  • You resolved twitter message, after resolving any ${vars}, should be maximum 140 chars

What happens if I send multiple message with the same text

  • Twitter seems to ignore status updates if there is not status change from your.

What happens if my <twitterStatus> is more than 140 characters

The current version does not check for length and will send your message to Twitter. Twitter will respond with an error.

Does this plugin support URL shortening?

Version 0.1 does not support URL shortening.

Does maven execution stop if the Twitter Plugin fails

No. All errors are logged, but no Exception is thrown.

Is there a limit to how many messages I can send?

Yes. Twitter has a rate limit of 150 message per hour. See details.

What are all the different Maven phases

Here’s Maven’s documentation on Phases

Reference

Customizing Yahoo! Grids CSS, for beginners

Overview

Yahoo! Grid CSS system is an easy way to create an HTML document with a desired page width and a secondary column which works out of the box. YUI Grid comes with four built-in page widths and six built-in template presets. This article shows you how to create a custom page width and a custom secondary column width.

Yahoo! Grid Page structure

The overall structure of a HTML document using yahoo grid is as follows:

<html>
 <head>
  <link href="http://yui.yahooapis.com/2.8.0r4/build/reset-fonts-grids/reset-fonts-grids.css" rel="styleSheet" type="text/css" />
 </head>
 <body>
  <div id="doc" class="yui-t1">
    <div id=”hd”></div><!-- header -->
    <div id=”bd”></div><!-- body -->
    <div id=”ft”></div><!-- footer -->
  </div>
 </body>
</html>

Page Width

You can control the overall width of the page using the id of the outermost div (<div id=”doc”, in the above example). There are 4 pre-defined doc ids:

  • doc: 750px
  • doc2: 950px
  • doc3: 100%
  • doc4: 974px

Customizing the Page Width

To create your custom page width, say 800px, add the following in your CSS

#doc20 {
 width:61.538em; /* 800/13 */
 *width:60em; /* for I.E. 800/13.3333 */
}

Then use this as your main document wrapper:

<div id="doc20">
  <div id=”hd”></div> <!-- header -->
  ...

Secondary column width with built-in templates

You can add a secondary column by simply nesting 2 blocks, <div class=”yui-b”>, under “bd”. You need to indicate which block is the main block by wrapping it in <div id=”yui-main”>.

<div id="bd">
  <!-- main block -->
  <div id="yui-main">
    <!-- main block -->
    <div class="yui-b">
    </div>
  </div>

  <!-- secondary column -->
  <div class="yui-b">
  </div>
</div>

The secondary column width and position can be controlled by the class of the <div id=”doc” class=”template preset goes here”> tag.

There are 6 built-in template presets.

  • .yui-t1 - Two columns, narrow on left, 160px
  • .yui-t2 – Two columns, narrow on left, 180px
  • .yui-t3 – Two columns, narrow on left, 300px
  • .yui-t4 – Two columns, narrow on right, 180px
  • .yui-t5 – Two columns, narrow on right, 240px
  • .yui-t6 – Two columns, narrow on right, 300px

For example:

<div id="doc" class="yui-t1">

results in a secondary column, narrow on left, 160px.

Customizing the secondary column width

Say you want to create a new template

  • .yui-t20 – Two columns, narrow on right, 120px

You can achieve this by including the following in your CSS (after the YUI grids CSS).

.yui-t20 {
  margin:auto;
  text-align:left;
}
.yui-t20 .yui-b {
  float:right;
  width:9.2308em;
  *width:9em;
}
.yui-t20 #yui-main {
  float: left;
  margin-right: -25em;
}
.yui-c20 #yui-main .yui-b {
  margin-right: 10.2308em;
  *margin-right: 10em;
}

How is the calculation done?

For all browsers, width in px / 13

width:9.2308em; /* 120/13 */

For I.E. star width in px / 13.33

*width:9em; /* for I.E. 120/13.33 */

For all browsers, right margin is width + 1em

For secondary column on left, change right and left appropriately.

References

3 ways to run Java main from Maven

Overview

Maven exec plugin lets you run the main method of a Java class in your project, with the project dependencies automatically included in the classpath. This article show you 3 ways of using the maven exec plugin to run java, with code examples.

1) Running from Command line

Since you are not running your code in a maven phase, you first need to compile the code. Remember exec:java does not automatically compile your code, you need to do that first.

mvn compile

Once your code is compiled, the following command runs your class

Without arguments:

mvn exec:java -Dexec.mainClass="com.vineetmanohar.module.Main"

With arguments:

mvn exec:java -Dexec.mainClass="com.vineetmanohar.module.Main" -Dexec.args="arg0 arg1 arg2"

With runtime dependencies in the CLASSPATH:

mvn exec:java -Dexec.mainClass="com.vineetmanohar.module.Main" -Dexec.classpathScope=runtime

2) Running in a phase in pom.xml

You can also run the main method in a maven phase. For example, you can run the CodeGenerator.main() method as part of the test phase.

<build>
 <plugins>
  <plugin>
   <groupId>org.codehaus.mojo</groupId>
   <artifactId>exec-maven-plugin</artifactId>
   <version>1.1.1</version>
   <executions>
    <execution>
     <phase>test</phase>
     <goals>
      <goal>java</goal>
     </goals>
     <configuration>
      <mainClass>com.vineetmanohar.module.CodeGenerator</mainClass>
      <arguments>
       <argument>arg0</argument>
       <argument>arg1</argument>
      </arguments>
     </configuration>
    </execution>
   </executions>
  </plugin>
 </plugins>
</build>

To run the exec plugin with above configuration, simply run the corresponding phase.

 mvn test

3) Running in a profile in pom.xml

You can also run the main method in a different profile. Simply wrap the above config in the <profile> tag.

<profiles>
 <profile>
  <id>code-generator</id>
  <build>
   <plugins>
    <plugin>
     <groupId>org.codehaus.mojo</groupId>
     <artifactId>exec-maven-plugin</artifactId>
     <version>1.1.1</version>
     <executions>
      <execution>
       <phase>test</phase>
       <goals>
        <goal>java</goal>
       </goals>
       <configuration>
        <mainClass>com.vineetmanohar.module.CodeGenerator</mainClass>
        <arguments>
         <argument>arg0</argument>
         <argument>arg1</argument>
        </arguments>
       </configuration>
      </execution>
     </executions>
    </plugin>
   </plugins>
  </build>
 </profile>
</profiles>

To call the above profile, run the following command:

 mvn test -Pcode-generator

Advanced options:

You can get a list of all available parameters by typing:

mvn exec:help -Ddetail=true -Dgoal=java

arguments (exec.arguments)

 The class arguments.

classpathScope (exec.classpathScope, Default: compile)

 Defines the scope of the classpath passed to the plugin. Set to
 compile, test, runtime or system depending on your needs

cleanupDaemonThreads (exec.cleanupDaemonThreads)

 Wether to interrupt/join and possibly stop the daemon threads upon
 quitting.  If this is false, maven does nothing about the daemon threads.
 When maven has no more work to do, the VM will normally terminate any
 remaining daemon threads.
 In certain cases (in particular if maven is embedded), you might need to
 keep this enabled to make sure threads are properly cleaned up to ensure
 they don't interfere with subsequent activity. In that case, see
 daemonThreadJoinTimeout and stopUnresponsiveDaemonThreads for further
 tuning.

commandlineArgs (exec.args)

 Arguments for the executed program

daemonThreadJoinTimeout (exec.daemonThreadJoinTimeout, Default: 15000)

 This defines the number of milliseconds to wait for daemon threads to quit
 following their interruption. This is only taken into account if
 cleanupDaemonThreads is true. A value <=0 means to not timeout (i.e. wait
 indefinitely for threads to finish). Following a timeout, a warning will
 be logged. Note: properly coded threads should terminate upon interruption
 but some threads may prove problematic: as the VM does interrupt daemon
 threads, some code may not have been written to handle interruption
 properly. For example java.util.Timer is known to not handle interruptions
 in JDK <= 1.6. So it is not possible for us to infinitely wait by default
 otherwise maven could hang. A sensible default value has been chosen, but
 this default value may change in the future based on user feedback.

executableDependency

 If provided the ExecutableDependency identifies which of the plugin
 dependencies contains the executable class. This will have the affect of
 only including plugin dependencies required by the identified
 ExecutableDependency.
 If includeProjectDependencies is set to true, all of the project
 dependencies will be included on the executable's classpath. Whether a
 particular project dependency is a dependency of the identified
 ExecutableDependency will be irrelevant to its inclusion in the classpath.

includePluginDependencies (exec.includePluginDependencies, Default: false)

 Indicates if this plugin's dependencies should be used when executing the
 main class. This is useful when project dependencies are not appropriate. Using
 only the plugin dependencies can be particularly useful when the project is not
 a java project. For example a mvn project using the csharp plugins only expects
 to see dotnet libraries as dependencies.

includeProjectDependencies (exec.includeProjectDependencies, Default: true)

 Indicates if the project dependencies should be used when executing the
 main class.

mainClass (exec.mainClass)

 The main class to execute.

sourceRoot (sourceRoot)

 This folder is added to the list of those folders containing source to be
 compiled. Use this if your plugin generates source code.

stopUnresponsiveDaemonThreads (exec.stopUnresponsiveDaemonThreads)

 Wether to call Thread.stop() following a timing out of waiting for an
 interrupted thread to finish. This is only taken into account if
 cleanupDaemonThreads is true and the daemonThreadJoinTimeout threshold has
 been reached for an uncooperative thread. If this is false, or if
 Thread.stop() fails to get the thread to stop, then a warning is logged
 and Maven will continue on while the affected threads (and related objects
 in memory) linger on. Consider setting this to true if you are invoking
 problematic code that you can't fix. An example is Timer which doesn't
 respond to interruption. To have Timer fixed, vote for this bug.

systemProperties

 A list of system properties to be passed. Note: as the execution is not
 forked, some system properties required by the JVM cannot be passed here.
 Use MAVEN_OPTS or the exec:exec instead. See the user guide for more
 information.

testSourceRoot (testSourceRoot)

 This folder is added to the list of those folders containing source to be
 compiled for testing. Use this if your plugin generates test source code.

FAQ and Errors

Why do I get this error when specifying arguments to my main method:

[ERROR] BUILD ERROR
[INFO] ------------------------------------------------------------------------
[INFO] Failed to configure plugin parameters for: org.codehaus.mojo:exec-maven-plugin:1.1.1
on the command line, specify: '-Dexec.arguments=VALUE'
Cause: Cannot assign configuration entry 'arguments' to 'class [Ljava.lang.String;' from '${exec.arguments}',
which is of type class java.lang.String
[INFO] ------------------------------------------------------------------------
[INFO] Trace
org.apache.maven.lifecycle.LifecycleExecutionException: Error configuring: org.codehaus.mojo:exec-maven-plugin.
Reason: Unable to parse the created DOM for plugin configuration
 at org.apache.maven.lifecycle.DefaultLifecycleExecutor.executeGoals(DefaultLifecycleExecutor.java:588)
 at org.apache.maven.lifecycle.DefaultLifecycleExecutor.executeStandaloneGoal(DefaultLifecycleExecutor.java:513)
 at org.apache.maven.lifecycle.DefaultLifecycleExecutor.executeGoal(DefaultLifecycleExecutor.java:483)
 at org.apache.maven.lifecycle.DefaultLifecycleExecutor.executeGoalAndHandleFailures(DefaultLifecycleExecutor.java:331)
 at org.apache.maven.lifecycle.DefaultLifecycleExecutor.executeTaskSegments(DefaultLifecycleExecutor.java:292)
 at org.apache.maven.lifecycle.DefaultLifecycleExecutor.execute(DefaultLifecycleExecutor.java:142)
 at org.apache.maven.DefaultMaven.doExecute(DefaultMaven.java:336)
 at org.apache.maven.DefaultMaven.execute(DefaultMaven.java:129)
 at org.apache.maven.cli.MavenCli.main(MavenCli.java:301)

Solution

exec.arguments was used before version 1.1 of the exec plugin, it did not support conversion of command line String to String[] array.

  1. If possible upgrade to 1.1 or later and use exec.args instead of exec.arguments.
  2. If you can't upgrade the plugin version, you can still use command line arguments with a profile and use multiple <argument> tags associated in the pom.xml

References

How to automate project versioning and release with Maven

Goal

This tutorial shows you how to tag your maven project in a source control system (like CVS, Subversion) and release the versioned “jar” or “war” to a remote repository, and all of this with a single maven command! You can even automate the entire release process by running the command in a cronjob or a Continuous Integration system.

Overview

Project lifecycle involves periodically publishing a versioned copy somewhere, and incrementing the project version. For example, every week you may increment your version from MAJOR.MINOR.<X> to MAJOR.MINOR.<X+1>, or you may choose to do a nightly build and increment your version from MAJOR.MINOR.NIGHTLY.<X> to MAJOR.MINOR.NIGHTLY.<X+1>

Maven makes the above release process very easy, and reduces it to one command.

You need to do a one time setup specifying your source control information (CVS, subversion, etc) and the repository where you would want the release published. Once the setup is complete, doing the actual release can be achieved by a typing single command. You can even automate the release by running that command in a cronjob or on your Continuous Integration server.

  • Section 1 overview: describes the one time setup you need.
  • Section 2 overview: describes the release process with detailed options (the impatient ones can skip this section and come back later if needed).
  • Section 3 overview: describes how to automate the whole release process with a single command line

Section 1: One time configuration needed for using maven release feature

a) Declare your source control management using the <scm> tag in pom.xml

Maven will tag your project and check it in your source control system. So it needs to know the location of your source control system. You generally don’t need to specify credentials as maven inherits those from the environment. If maven needs credentials it will prompt you during the release process.

Example config for CVS in pom.xml

<project>
  <scm>
    <connection>scm:cvs:ext:username@cvs.server.com:/var/lib/cvs:myapp</connection>
    <developerConnection>scm:cvs:ext:username@cvs.server.com:/cvs:myapp</developerConnection>
  </scm>

Example config for SVN in pom.xml

<project>
  <scm>
    <connection>scm:svn:http://scm.vineetmanohar.com/repos/myapp/trunk</connection>
    <developerConnection>scm:svn:http://scm.vineetmanohar.com/repos/myapp/trunk</developerConnection>
  </scm>

You can find reference documentation for the <scm> tag here.

b) Declare the remote repository where you want to publish your release to

After versioning your project, maven will deploy your project artifact (jar or war) to a remote repository of your choice.

pom.xml snippet when publishing via scp

If you have a simple maven repo hosted on apache and you have ssh access to the repo, you can publish your artifacts via scp.

<distributionManagement>
  <!-- Publish the versioned releases here -->
  <repository>
    <id>repo</id>
    <name>My maven2 repository</name>
    <url>scp://username@maven.vineetmanohar.com/home/maven2/html</url>
  </repository>
</distributionManagement>

pom.xml snippet when publishing via webdav

<distributionManagement>
  <!-- Publish the versioned releases here -->
  <repository>
    <id>repo</id>
    <name>My maven2 repository</name>
    <url>dav:http://nexus.vineetmanohar.com/nexus/content/repositories/</url>
  </repository>
</distributionManagement>

pom.xml snippet when publishing via sftp

<distributionManagement>
  <!-- Publish the versioned releases here -->
  <repository>
    <id>repo</id>
    <name>My maven2 repository</name>
    <url>sftp://maven.vineetmanohar.com.net/repo</url>
  </repository>
</distributionManagement>

c) Specify credentials needed to publish to the remote repo in your settings.xml file

Using scp or sftp? If you are using ssh as your underlying transfer mechanism, you can setup SSH without password to the repo machine otherwise maven will ask you to enter password each time.

Alternatively you can specify required remote repo credentials in your settings.xml file stored here:

USER_HOME/.m2/settings.xml

Here’s a sample snippet.

<settings>
  <servers>
    <server>
      <!-- this is the id of the repo tag specified in distributionManagement -->
      <id>repo</id>
      <username>yourusername</username>
      <password>yourpassword</password>
    </server>
  </servers>
</settings>

You can find reference documentation for the <server> tag here.

Section 2: The release process

Once the configuration is done, making the release each time is very easy. Just follow these steps.

a) Pre-requisites:

  • Make sure that your pom.xml does not include any SNAPSHOT dependencies.
  • Make sure that all local changes are checked in.
  • Make sure all unit tests pass

All of the above are required. The next step will gracefully fail with a warning if the above conditions are not met.

b) Run the release prepare command

This step does everything needed in order to make a release, including tagging the project, but does not actually make the release. It will check for local modifications, SNAPSHOT dependencies, calculate the release version, the next SNAPSHOT version.

mvn release:prepare

Some things that you should know about the above command.

  1. No local modifications. This command checks for local modifications. If you have any files which are modified but not checked in, then the command will stop and ask you to first check-in modified files.
  2. No SNAPSHOT dependencies. Your project should not have any SNAPSHOT dependencies in your project. Its a requirement.
  3. Release version and next development version. You will be asked to specify the version for your release and also the next SNAPSHOT version that you want to assign to your project. Accept the default values if unsure.
  4. Unit tests. Maven will run your unit tests to make sure that they work after changing the project version in pom.xml.
  5. Tag source. If tests pass, maven will tag the source in the source control with the release version you specified in point 3 above.
  6. release.properties. Maven will collect all the information that you provide and write a local file called “release.properties”. This file lets you continue from where you left in case of errors.
  7. Undo. You can everything you’ve done so far with mvn release:clean to start over

c) Make the actual release

Once you’ve actually prepared the release using mvn release:prepare, you can make the release by typing the following command

mvn release:perform

This command uses release.properties created by the previous step and does the following

  1. Checks out code tagged in the previous step. It figures out the tag version from the release.properties file.
  2. Runs maven deploy site-deploy goals to deploy the released version. This step is responsible for deploying the jar or war to the remote repository.
  3. Clean up. After the release is done, release.properties file will be deleted.

Section 3: Automating the release process

Single line release process

The following command will tag source control, bump up the current pom.xml version and push a tagged artifact (jar or war) to a remote repo.

mvn release:prepare release:perform -B

For example, if your current project version was 0.92-SNAPSHOT

  1. The release version will be 0.92
  2. The next development version will be 0.93-SNAPSHOT
  3. The scm tag version will be artifactId-0_92

If you want to specify the versions manually, then see Section 2 above.

A single line release command is good for productivity and great for automation. You can create a build plan on your Continuous Integration server with the above command to automatically tag the current version, and automatically bump the SNAPSHOT version. This could be useful for automatically triggerd nightly releases, or manually triggered releases.

Reference

JAXB code snippets for beginners

What is JAXB

JAXB is a Java library used for reading and writing XML files. Unlike DOM or SAX, JAXB is a high level library that maps XML directly to Java Objects. You point JAXB to an XML file and it returns you a Java object representing the XML. While JAXB is easy to use, it may take some time to get started. I’ve documented everything that you need to know, with code snippets, to help you start using JAXB in a few minutes.

Step 1/2: Mapping your schema XSD to Java

The first step to create Java classes which map to your schema. The XJC compiler does exactly that. Here’s a reference to the XJC compiler. However if you are using Maven, there is a maven jaxb plugin which automatically generates the Java mapping by defining a few snippets in your pom.xml. The following section shows you how to use JAXB from Maven.

Using JAXB from Maven: configure your pom.xml to automatically run the Maven JAXB plugin

To use JAXB from Maven, you need to add the JAXB plugin repository information and the Maven JAXB plugin declaration to your pom.xml.

<pluginRepositories>
 <pluginRepository>
  <id>maven2-repository.dev.java.net</id>
  <name>Java.net Repository for Maven</name>
  <url>http://download.java.net/maven/2/</url>
  <layout>default</layout>
 </pluginRepository>
</pluginRepositories>

Change sitemap.xsd below to your schema.xsd name. Also, change the output package “com.vineetmanohar.sitemap.jaxb” to a package of your choice. Generally, this is a brand new package with no other classes in it.

<build>
 <plugins>
  <plugin>
   <!-- jaxb plugin -->
   <groupId>org.jvnet.jaxb2.maven2</groupId>
   <artifactId>maven-jaxb2-plugin</artifactId>
   <executions>
    <execution>
     <id>sitemap</id>
     <goals>
      <goal>generate</goal>
     </goals>

     <configuration>
      <args>
       <param>-npa</param>
      </args>

      <!-- the package for the generated java classes -->
      <generatePackage>com.vineetmanohar.sitemap.jaxb</generatePackage>
      <npa>true</npa>
      <!-- include the following schemas only; by default all *.xsd files are processed -->
      <schemaIncludes>
       <include>sitemap.xsd</include>
      </schemaIncludes>

      <!-- whether old output should be removed, this field should generally be set to "true" -->
      <removeOldOutput>true</removeOldOutput>
      <!-- generate lots of output -->
      <verbose>true</verbose>
     </configuration>
    </execution>
   </executions>
  </plugin>
 </plugins>
</build

Output and Generated Classes

The JAXB plugin by default runs in the “generate-sources” phase. To run the JAXB plugin, simply run “mvn generate-sources”, or any phase which occurs after “generate-sources”, like “compile”.

mvn compile

This will run the JAXB plugin and generates Java classes for your schema (for sitemap.xsd in the above example). The output java package is “com.vineetmanohar.sitemap.jaxb”, as specified in the plugin configuration above. Here’s how the output looks after running the plugin.

target/generated-sources
target/generated-sources/xjc
target/generated-sources/xjc/META-INF
target/generated-sources/xjc/META-INF/sun-jaxb.episode
target/generated-sources/xjc/com
target/generated-sources/xjc/com/vineetmanohar
target/generated-sources/xjc/com/vineetmanohar/sitemap
target/generated-sources/xjc/com/vineetmanohar/sitemap/jaxb
target/generated-sources/xjc/com/vineetmanohar/sitemap/jaxb/ObjectFactory.java
target/generated-sources/xjc/com/vineetmanohar/sitemap/jaxb/Urlset.java
target/generated-sources/xjc/com/vineetmanohar/sitemap/jaxb/TChangeFreq.java
target/generated-sources/xjc/com/vineetmanohar/sitemap/jaxb/TUrl.java

Note that the generated classes live in the target directory. You should not modify them or check them into your source control system. These classes are temporary and will be automatically generated when your run maven compile.

Step 2/2: Using the JAXB generated classes from your Java code

Once the code is generated, you are now ready to use the code from your Java class. Here are 3 ways of using JAXB from your java code.

1. Basic way: A basic way is to create a wrapper file which hides all the JAXB details and provides an easy to use interface. See the SitemapJAXBWrapper.java file to see an example implementation. I don’t recommend this option, however, as a beginner you should try it out as it helps you understand the JAXB API. The following option, option #2 is a more preferred approach.

2. Preferred way: This is basically option 1 refactored to hide all the JAXB details. Download this re-usable JAXBWrapper.java class and use that as a wrapper class. The JAXBWrapper class gives you an easy way to do XML to Java and Java to XML conversions in just 2-3 lines of code. All you need to do it pass 2 parameters, the schema URL, and the classes that you want to bind. The classes are the classes that were previously generated using XJC or the Maven JAXB plugin above. In this example we are trying to read a sitemap.xml file and load it into the java class Urlset.java.You won’t find the Urlset.java on my Google Code project because it is a temporary file which is automatically generated when needed and never checked it. Here’s a sample code.

Create a wrapper

JaxbWrapper<Urlset> sitemapJaxbWrapper = new JaxbWrapper<Urlset>(getClass().getResource("/sitemap.xsd"), Urlset.class);

XML to Java

Urlset urlset = sitemapJaxbWrapper.xmlToObject(getClass().getResourceAsStream("/sample-sitemap.xml"));

Java to XML

Urlset urlset = new com.vineetmanohar.sitemap.jaxb.ObjectFactory().createUrlset();
String xml = sitemapJaxbWrapper.objectToXml(urlset);

3. Using Spring framework: The third way to use JAXB is through Spring OXM classes. Here’s a reference documentation. I won’t go into the details, but the idea is that you create a JaxB2Marshaller bean in your spring config, then inject the bean in the class where you want to use it.

FAQ

How to generate classes for multiple schemas in different packages

Add one <execution> step per schema. Add a different <id> per execution. Add a unique <generateDirectory> in the configuration section. By default the <generateDirectory> value is target/generated-sources/xjc. You should set it such that each one of them is different. For example target/generated-sources/xjc1, target/generated-sources/xjc2 etc. Full reference of JAXB configuration is here.

<executions>
 <execution>
  <id>id1</id>
  <goals>
   <goal>generate</goal>
  </goals>
  <configuration>
   <args>
    <param>-npa</param>
   </args>
   <generateDirectory>target/generated-sources/xjc1</generateDirectory>
   <generatePackage>some.package1</generatePackage>
  <schemaIncludes>
   <include>schema1.xsd</include>
  </schemaIncludes>
  <forceRegenerate>false</forceRegenerate>
  <removeOldOutput>true</removeOldOutput>
  <verbose>true</verbose>
  </configuration>
 </execution>

 <execution>
  <id>id2</id>
  <goals>
   <goal>generate</goal>
  </goals>
  <configuration>
   <args>
    <param>-npa</param>
   </args>
   <generateDirectory>target/generated-sources/xjc2</generateDirectory>
   <generatePackage>some.package2</generatePackage>
   <schemaIncludes>
    <include>schema2.xsd</include>
   </schemaIncludes>
   <forceRegenerate>false</forceRegenerate>
   <removeOldOutput>true</removeOldOutput>
   <verbose>true</verbose>
  </configuration>
 </execution>
</executions>

Are JAXB Marshaller and Unmarshaller thread-safe?

No. Marshaller and Unmarshaller are not thread-safe because they use a non-thread safe TransformerFactory. Therefore, you need to create a new Marshaller and Unmarshaller object per invocation. The JAXBWrapper already takes care of that detail.

Why do I get a “unable to marshal type because it is missing an @XmlRootElement annotation]”

If you get this stack trace when running JAXB, see the following solution.

[com.sun.istack.SAXException2: unable to marshal type "org.foo.xmlbindings.FooType" as an element because it is missing an @XmlRootElement annotation]
 at com.sun.xml.bind.v2.runtime.MarshallerImpl.write(MarshallerImpl.java:304)
 at com.sun.xml.bind.v2.runtime.MarshallerImpl.marshal(MarshallerImpl.java:230)
 at javax.xml.bind.helpers.AbstractMarshallerImpl.marshal(AbstractMarshallerImpl.java:96)
 at Caused by: com.sun.istack.SAXException2: unable to marshal type "org.foo.xmlbindings.FooType" as an element because it is missing an @XmlRootElement annotation
 at com.sun.xml.bind.v2.runtime.XMLSerializer.reportError(XMLSerializer.java:226)
 at com.sun.xml.bind.v2.runtime.ClassBeanInfoImpl.serializeRoot(ClassBeanInfoImpl.java:267)
 at com.sun.xml.bind.v2.runtime.XMLSerializer.childAsRoot(XMLSerializer.java:472)
 at com.sun.xml.bind.v2.runtime.MarshallerImpl.write(MarshallerImpl.java:301)
 ... 26 more
... Removed 22 stack frames
[com.sun.istack.SAXException2: unable to marshal type "org.foo.xmlbindings.FooType" as an element because it is missing an @XmlRootElement annotation]
 at com.sun.xml.bind.v2.runtime.MarshallerImpl.write(MarshallerImpl.java:304)
 at com.sun.xml.bind.v2.runtime.MarshallerImpl.marshal(MarshallerImpl.java:230)
 at javax.xml.bind.helpers.AbstractMarshallerImpl.marshal(AbstractMarshallerImpl.java:96)
 at
Caused by: com.sun.istack.SAXException2: unable to marshal type "org.foo.xmlbindings.FooType" as an element because it is missing an @XmlRootElement annotation
 at com.sun.xml.bind.v2.runtime.XMLSerializer.reportError(XMLSerializer.java:226)
 at com.sun.xml.bind.v2.runtime.ClassBeanInfoImpl.serializeRoot(ClassBeanInfoImpl.java:267)
 at com.sun.xml.bind.v2.runtime.XMLSerializer.childAsRoot(XMLSerializer.java:472)
 at com.sun.xml.bind.v2.runtime.MarshallerImpl.write(MarshallerImpl.java:301)
 ... 26 more
... Removed 22 stack frames

Solution: Make sure that the root element is an anonymous complex type and not an instance of a defined type.

Right root element example:

  <xsd:element name="foo">
    <xsd:complexType>
      <xsd:sequence>
        <xsd:element name="bar" type="p:barType" />
      </xsd:sequence>
    </xsd:complexType>
  </xsd:element>

Wrong root element example:

  <xsd:element name="foo" type="fooType">
  </xsd:element>

  <xsd:complexType name="fooType">
    <xsd:sequence>
      <xsd:element name="bar" type="p:barType" />
    </xsd:sequence>
  </xsd:complexType>

Why do I get Maven Jaxb package-info syntax error

[INFO] Applying extractor for language: java
[INFO] ------------------------------------------------------------------------
[ERROR] FATAL ERROR
[INFO] ------------------------------------------------------------------------
[INFO] syntax error @[8,7] in file:xmlbindings/package-info.java
[INFO] ------------------------------------------------------------------------
[INFO] Trace
com.thoughtworks.qdox.parser.ParseException: syntax error @[8,7] in file:xmlbindings/package-info.java
        at com.thoughtworks.qdox.parser.impl.Parser.yyerror(Parser.java:638)
        at com.thoughtworks.qdox.parser.impl.Parser.yyparse(Parser.java:747)
        at com.thoughtworks.qdox.parser.impl.Parser.parse(Parser.java:619)
        at com.thoughtworks.qdox.JavaDocBuilder.addSource(JavaDocBuilder.java:300)
        at com.thoughtworks.qdox.JavaDocBuilder.addSource(JavaDocBuilder.java:316)
        at com.thoughtworks.qdox.JavaDocBuilder.addSource(JavaDocBuilder.java:312)
        at com.thoughtworks.qdox.JavaDocBuilder$1.visitFile(JavaDocBuilder.java:369)
        at com.thoughtworks.qdox.directorywalker.DirectoryScanner.walk(DirectoryScanner.java:43)
        at com.thoughtworks.qdox.directorywalker.DirectoryScanner.walk(DirectoryScanner.java:34)
        at com.thoughtworks.qdox.directorywalker.DirectoryScanner.walk(DirectoryScanner.java:34)
        at com.thoughtworks.qdox.directorywalker.DirectoryScanner.walk(DirectoryScanner.java:34)
        at com.thoughtworks.qdox.directorywalker.DirectoryScanner.walk(DirectoryScanner.java:34)
        at com.thoughtworks.qdox.directorywalker.DirectoryScanner.walk(DirectoryScanner.java:34)
        at com.thoughtworks.qdox.directorywalker.DirectoryScanner.walk(DirectoryScanner.java:34)
        at com.thoughtworks.qdox.directorywalker.DirectoryScanner.walk(DirectoryScanner.java:34)
        at com.thoughtworks.qdox.directorywalker.DirectoryScanner.scan(DirectoryScanner.java:52)
        at com.thoughtworks.qdox.JavaDocBuilder.addSourceTree(JavaDocBuilder.java:366)
        at org.apache.maven.tools.plugin.extractor.java.JavaMojoDescriptorExtractor.discoverClasses(JavaMojoDescriptorExtractor.java:614)
        at org.apache.maven.tools.plugin.extractor.java.JavaMojoDescriptorExtractor.execute(JavaMojoDescriptorExtractor.java:581)
        at org.apache.maven.tools.plugin.scanner.DefaultMojoScanner.populatePluginDescriptor(DefaultMojoScanner.java:87)
        at org.apache.maven.plugin.plugin.AbstractGeneratorMojo.execute(AbstractGeneratorMojo.java:137)
        at org.apache.maven.plugin.DefaultPluginManager.executeMojo(DefaultPluginManager.java:447)
        at org.apache.maven.lifecycle.DefaultLifecycleExecutor.executeGoals(DefaultLifecycleExecutor.java:539)
        at org.apache.maven.lifecycle.DefaultLifecycleExecutor.executeGoalWithLifecycle(DefaultLifecycleExecutor.java:480)
        at org.apache.maven.lifecycle.DefaultLifecycleExecutor.executeGoal(DefaultLifecycleExecutor.java:459)
        at org.apache.maven.lifecycle.DefaultLifecycleExecutor.executeGoalAndHandleFailures(DefaultLifecycleExecutor.java:311)
        at org.apache.maven.lifecycle.DefaultLifecycleExecutor.executeTaskSegments(DefaultLifecycleExecutor.java:278)
        at org.apache.maven.lifecycle.DefaultLifecycleExecutor.execute(DefaultLifecycleExecutor.java:143)
        at org.apache.maven.DefaultMaven.doExecute(DefaultMaven.java:333)
        at org.apache.maven.DefaultMaven.execute(DefaultMaven.java:126)
        at org.apache.maven.cli.MavenCli.main(MavenCli.java:282)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
        at java.lang.reflect.Method.invoke(Method.java:585)
        at org.codehaus.classworlds.Launcher.launchEnhanced(Launcher.java:315)
        at org.codehaus.classworlds.Launcher.launch(Launcher.java:255)
        at org.codehaus.classworlds.Launcher.mainWithExitCode(Launcher.java:430)
        at org.codehaus.classworlds.Launcher.main(Launcher.java:375)
[INFO] ------------------------------------------------------------------------

Cause: A file called package-info.java gets generated in the output package. Here's the content of the file.

//
// This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, v2.0.2-b01-fcs
// See <a href="http://java.sun.com/xml/jaxb">http://java.sun.com/xml/jaxb</a>
// Any modifications to this file will be lost upon recompilation of the source schema.
// Generated on: 2008.06.11 at 01:20:24 PM EDT
//

@javax.xml.bind.annotation.XmlSchema(namespace = "http://www.vineetmanohar.com", elementFormDefault = javax.xml.bind.annotation.XmlNsForm.QUALIFIED)
package xmlbindings;

The error is on the period immediately following javax (@javax.)

Workaround: add the no package info generation flag to xjc

      <plugin>
        <!-- new maven jaxb -->
        <groupId>org.jvnet.jaxb2.maven2</groupId>
        <artifactId>maven-jaxb2-plugin</artifactId>

        <executions>
          <execution>
            <goals>
              <goal>generate</goal>
            </goals>
            <configuration>
              <args>
                <param>-npa</param>
              </args>

Reference

What is OpenID and how can I use it?

What is OpenID, in simple English

OpenID is a single login that you can use across many websites on the internet. With OpenID, you no longer need to create a username/password when registering on a new website. You can simply use your existing OpenID.

Using OpenID

OpenId Login

OpenId Login

Using an OpenID to login to a website is similar to the notion of showing your driver’s license at the box office when picking up tickets or showing your driver’s license at the airport security to prove your identity. OpenID is a single digital identity that you own. You present it when logging in to a website or at a blog post when submitting a comment.

You can only use OpenID on Websites which accept OpenID. Look for the OpenID symbol or text like “Login using an OpenID” as shown in the image on the right.

How does OpenID work?

  1. You get an OpenID with one of the providers (more on this in the next section). Your OpenID is a short URL, for example mine is http://www.vineetmanohar.com
  2. You go to a website which accepts OpenID, for example, Stack Overflow
  3. You enter your OpenID and hit Login
  4. Your are redirected back to your OpenID provider’s website. You login there using your login/password that you setup in step 1. After logging in, you are automatically redirected back to website X where you came from.
  5. When you land on website X, you should be logged in.
  6. You can repeat the same procedure for website Y. Note that login/password only occurs on your OpenID provider’s website, so you only need to remember one login/password.

How to get an OpenID

You probably already have an OpenID. Most email/blog service providers already give you an OpenID. Here is a list of OpenIDs associated with popular services:

  • Google or Gmail: https://www.google.com/accounts/o8/id
  • AOL or AIM: openid.aol.com/yourname
  • Yahoo!:: https://me.yahoo.com/yourname
    1. you need to first enable this feature on Yahoo’s OpenID page
    2. Yahoo! does not recommend using your yahoo login as your openID as it reveals your email address. You can change it to a longer cryptic string like https://me.yahoo.com/notyourname
    3. When asked for OpenID you can just type: yahoo.com. The website will redirect you to Yahoo! where you can login with your Yahoo! login/password.
  • My Space: www.myspace.com/username
  • Blogger: blogname.blogspot.com

Here’s an extensive List of OpenID providers

Your OpenID is your identity, so choose one carefully

Although you can sign up with any OpenID provider, you should think of it as your identity. In my opinion, good choices might be either your email provider, like Google, Yahoo or AOL, or your blog.

If you can’t decide which one to go with, go with the one where you are logged in most of the time. This could be your email provider or your social networking site. The advantage with this option is that you are probably logged in to your provider most of the time, you will not be asked to login when signing in to a third party site using OpenID.

Use your Wordpress powered website or blog as your OpenID

If you have a WordPress powered blog or website, you can use it as your OpenID. You need to install the OpenID plugin for WordPress. After the installation is complete:

  • Use your blog URL as your OpenID when logging in to other websites. For example, I can use my blog address as my OpenID: http://www.vineetmanohar.com, in which case I am redirected back to my blog which logs me in, and then redirects me back to the website where I came from.
  • You can login to your blog using OpenID instead of your WordPress login/password.
  • Visitors to your blog can leave comments using their OpenID. If you are reading this blog and have an OpenID, you can leave comments at the bottom of this page using your OpenID.

How to use your Vanilla HTML homepage as your OpenID

You need to put two meta tags in the section of your HTML.

<link rel="openid.server" href="http://<openid provider server url>">
<link rel="openid.delegate"  href="http://<your openid with this provider>">

You will need the server url for your OpenId provider. Here are some server URLs.

  • AOL/AIM: https://api.screenname.aol.com/auth/openidServer
  • LiveJournal: http://www.livejournal.com/openid/server.bml
  • MyOpenID: http://www.myopenid.com/server
  • VeriSign: https://pip.verisignlabs.com/server
  • Vox: http://www.vox.com/services/openid/server
  • myvidoop: See this page

If you want to use delegation and your provider is not listed above, then check on your provider’s website or simply ask them.

This approach gives you more flexibility. With delegation, you can later change providers but continue to use your home page URL as your OpenID.

Seatbelt: a Firefox extension for Verisign OpenID accounts

If you chose Verisign as your OpenID provider, you can use the Seatbelt extension for Firefox. It automatically logs you in to any page which accepts OpenID.

Developers: how to add OpenID support on your site

When implementing a new website, consider adding OpenID support for new users. This article explains how to OpenID-enable your website.

Here’s a Java library for OpenID

References

Leave a Comment using your OpenID

The comment section of this page accepts OpenID login. Try out your new OpenID by leaving a comment below!

Get Adobe Flash playerPlugin by wpburn.com wordpress themes