Friday, June 19, 2009

Creating a JBoss Seam Maven Archetype

In case you're a regular reader of this blog, I guess you're aware that I'm a frequent user of both Maven and JBoss Seam - and that I'm regularly trying to combine working with both! My usual approach for setting up a new project was either to start with an empty Maven web application project and copying the missing files over, or to start with a seam-gen project and move it into a Maven structure. Both less than ideal...

Maven provides so called archetypes for a quick project setup. As there is not (yet?) an official archetype for Seam projects, I've been working on my own - and here's how you can use it as well!

All you need is
  • a recent version of Maven downloaded (I used 2.0.10)
  • and the Maven executable referenced in your path so you can use it on the console.
Open up a console, cd to your projects directory and type:

mvn archetype:generate -DarchetypeCatalog=http://tinyurl.com/jbsarch

This will start Maven and show the following command line output:

[INFO] Scanning for projects...
[INFO] Searching repository for plugin with prefix: 'archetype'.
[INFO] ------------------------------------------------------------------------
[INFO] Building Maven Default Project
[INFO] task-segment: [archetype:generate] (aggregator-style)
[INFO] ------------------------------------------------------------------------
[INFO] Preparing archetype:generate
[INFO] No goals needed for project - skipping
[INFO] Setting property: classpath.resource.loader.class => 'org.codehaus.plexus.velocity.ContextClassLoaderResourceLoader'.
[INFO] Setting property: velocimacro.messages.on => 'false'.
[INFO] Setting property: resource.loader => 'classpath'.
[INFO] Setting property: resource.manager.logwhenfound => 'false'.
[INFO] [archetype:generate]
[INFO] Generating project in Interactive mode
[INFO] No archetype defined. Using maven-archetype-quickstart (org.apache.maven.archetypes:maven-archetype-quickstart:1.0)
Choose archetype:
1: http://tinyurl.com/jbsarch -> jboss-seam-archetype (Archetype for JBoss Seam Projects)
Choose a number: (1):


The remote archetype catalog contains so far only one archetype (BTW: the jbsarch in tinyurl.com/jbsarch stands for JBoss Seam ARCHetype - hope you can remember this better than the full URL :-) Select the archetype by typing 1 and enter your Maven project properties as well as your JBoss Server directory:

[INFO] snapshot com.ctp.archetype:jboss-seam-archetype:1.0.0-SNAPSHOT: checking for updates from jboss-seam-archetype-repo
Define value for serverDir: : /Developer/Servers/JBoss/jboss-5.1.0.GA
Define value for groupId: : com.ctp
Define value for artifactId: : fluxcapacitor
Define value for version: 1.0-SNAPSHOT: :
Define value for package: com.ctp: : com.ctp.fluxcapacitor
Confirm properties configuration:
serverType: jboss5
serverDir: /Developer/Servers/JBoss/jboss-5.1.0.GA
groupId: com.ctp
artifactId: fluxcapacitor
version: 1.0-SNAPSHOT
package: com.ctp.fluxcapacitor
Y: : y
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESSFUL
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 4 minutes 57 seconds
[INFO] Finished at: Fri Jun 19 19:12:19 CEST 2009
[INFO] Final Memory: 12M/79M
[INFO] ------------------------------------------------------------------------


Note that the serverType property defaults to jboss5. If you have a JBoss 4.2.x installation, quit with n and retype everything (hmm...) and use jboss4 instead.

In case anything fails here, make sure your archetype plugin is at least version 2.0-alpha-4 (I had to delete the local repo info file in the local repository once). Now with your project created, lets build and deploy it!

Aragorn:sandbox thug$ cd fluxcapacitor/
Aragorn:fluxcapacitor thug$ mvn package
[INFO] Scanning for projects...
[INFO] Reactor build order:
[INFO] [fluxcapacitor]
[INFO] [fluxcapacitor :: JBoss Configuration]
[INFO] [fluxcapacitor :: Web Application]


The project currently features two modules: One with the actual web application, and the other one containing JBoss Server configuration files. With the basic archetype you only get a datasource there, but you can also use it to change server ports, define security realms, queues etc.

Environment specific properties are referenced in filter property files. You can find the development filter file in ${artifactId}/environment/filters/${artifactId}-development.properties. The filter file selection happens in the parent POM. It defines a development profile which sets the environment property. Setting this property to test will look for a ${artifactId}/environment/filters/${artifactId}-test.properties filter file.

Note that the parent POM contains your JBoss installation directory hard coded. You might want to factor this out into a developer specific profile when working in a team. Fire up your JBoss instance. Everything should start up well (fingers crossed...) and you can point your browser to the base URL of your application.


Done! Import the project in your favorite IDE and start prototyping!

Unfortunately this is still far away of what seam-gen provides up to now. Maven archetypes have improved over time but are currently still not as flexible to be useful in complex setups:
  • Entering project properties is not even close to be user friendly. At least a description, input validation (enumerations) and reasonable handling of default values might help.
  • Conditional installation of files. If you know how this works - let me know :-) This would be required to distinguish between WAR and EAR projects, and for targeting different applications servers (yeah, like GlassFish!).
In case I find some time to contribute something here, I'll report back. If you have feedback / contributions to the archetype, this is as usual very welcome (the code is available at our Google Code repository)!

8 comments:

Oscar Picasso said...

Interesting.

But there are still some problems for a smooth Seam + Maven + Eclipse integration.

1 - I didn't succeed to run a simple test. I got:

org.jboss.deployers.client.spi.IncompleteDeploymentException: Summary of incomplete deployments (SEE PREVIOUS ERRORS FOR DETAILS):
*** CONTEXTS MISSING DEPENDENCIES: Name -> Dependency{Required State:Actual State}
jboss.jca:name=sixDatasource,service=DataSourceBinding
-> jboss:service=invoker,type=jrmp{Create:** NOT FOUND **}
-> jboss:service=invoker,type=jrmp{Start:** NOT FOUND **}
*** CONTEXTS IN ERROR: Name -> Error
jboss:service=invoker,type=jrmp -> ** NOT FOUND **

2 - How do you debug?

3 - Are you able, with this project structure, to use the JBoss Seam Tools inside eclipse?

I am also interested to know if you use this setup for real life projects.

Thanks

Oscar

Unknown said...

Hi Oscar

Thanks a lot for your feedback!

1. D'oh, looks like I missed the datasource XML in the test resources!

2. Probably the easiest setup is to define the server in Eclipse in the JBoss Server view (without deploying the project via WTP). Starting it in debug mode there will keep your breakpoints.

3. If you manage to enable the Seam project facet, you can adapt the paths to your Maven project structure in the project's Seam Settings. If I remember correctly, I had to enable some facets via manually change Eclipse configs. Only hot deploy turned out difficult, that's why I developed the hot deploy Maven plugin.

I didn't use any Eclipse settings files in the archetype so far, but will give it a look.

BTW, JBoss Tools 3.1 will feature Maven support! Yeah!

This whole setup evolved out of a real life project where Maven as a build tool was a given requirement and it was decided to use Seam for a new application. Still trying to improve things, though...

Hope that helps!

Unknown said...

The latest snapshot contains now also a sample unit test, as well as the possibility to use ICEfaces. Check out the blog post here.

Lucian Ochian said...

Here is what I did:

C:\D>mvn archetype:generate -DarchetypeCatalog=http://tinyurl.com/jbsarch
Confirm properties configuration:
serverType: jboss5
ajaxLibrary: richfaces
serverDir: C:/C/DEV/SERVERS/jboss-5.0.0.GA
groupId: myproject
artifactId: myproject
version: 1.0-SNAPSHOT
package: mdh
Y: : Y
[INFO] -----------
[INFO] BUILD SUCCESSFUL

Then

C:\D\myproject\environment\filters>copy __rootArtifactId__-development.properties myproject-development.properties
1 file(s) copied.

Then

C:\D\myproject>mvn test
[INFO] Scanning for projects...

-------------------------------------------------------
T E S T S
-------------------------------------------------------
Running TestSuite
Tests run: 7, Failures: 1, Errors: 0, Skipped: 6, Time elapsed: 16.75 sec <<< FAILURE!

Results :

Failed tests:
startSeam(mdh.AuthenticatorTest)

Tests run: 7, Failures: 1, Errors: 0, Skipped: 6

[INFO] ------------------------------------------------------------------------
[ERROR] BUILD FAILURE

If I add this to the test class:

@Override
@BeforeSuite
public void startSeam() throws Exception

{
try {
super.startSeam();
} catch (Exception e) {
e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates.
}
}

then I can see some errors:


C:\D\myproject>mvn test
[INFO] Scanning for projects...
[INFO] Reactor build order:
[INFO] [myproject]
[INFO] [myproject :: JBoss Configuration]
[INFO] [myproject :: Web Application]
[INFO] ------------------------------------------------------------------------
-------------------------------------------------------
T E S T S
-------------------------------------------------------
Running TestSuite
java.lang.RuntimeException: Could not create Component: org.jboss.seam.security.ruleBasedPermissionResolver
at org.jboss.seam.init.Initialization.addComponent(Initialization.java:1202)
at org.jboss.seam.init.Initialization.installComponents(Initialization.java:1118)
at org.jboss.seam.init.Initialization.init(Initialization.java:733)
at org.jboss.seam.mock.AbstractSeamTest.startSeam(AbstractSeamTest.java:919)
at org.jboss.seam.mock.SeamTest.startSeam(SeamTest.java:58)
at mdh.AuthenticatorTest.startSeam(AuthenticatorTest.java:17)
Caused by: java.lang.IllegalArgumentException: No converter for type: org.drools.RuleBase
at org.jboss.seam.util.Conversions.getConverter(Conversions.java:63)
at org.jboss.seam.Component$ConstantInitialValue.<.init.>(Component.java:2481)
at org.jboss.seam.Component.getInitialValue(Component.java:538)
at org.jboss.seam.Component.getInitialValueHonoringExceptions(Component.java:512)
at org.jboss.seam.Component.initInitializers(Component.java:489)
at org.jboss.seam.Component.<.init.>(Component.java:254)
at org.jboss.seam.Component.<.init.>(Component.java:205)
at org.jboss.seam.init.Initialization.addComponent(Initialization.java:1186)
... 27 more
Tests run: 7, Failures: 1, Errors: 0, Skipped: 6, Time elapsed: 9.969 sec <<< FAILURE!

Results :

Failed tests:
startSeam(mdh.AuthenticatorTest)

Tests run: 7, Failures: 1, Errors: 0, Skipped: 6

[INFO] ------------------------------------------------------------------------
[ERROR] BUILD FAILURE
[INFO] ------------------------------------------------------------------------
[INFO] There are test failures.

C:\D\myproject>

Any help is appreciated!

Thanks,

Lucian

Lucian Ochian said...

I forgot to add this:

C:\D\myproject>mvn -version
Maven version: 2.0.10
Java version: 1.6.0_12
OS name: "windows xp" version: "5.1" arch: "x86" Family: "windows"

Unknown said...

Hi Lucian

If you get files named __rootArtifactId__*, you most like don't use archetype version 2.1-alpha-4. You should see the version somewhere in the console output.

If so, try removing the archetype plugin metadata files in your local repository. This should afterwards download and use alpha-4.

Lucian Ochian said...

It worked great!
I deleted the whole m2/org/apache/maven and I upgraded to maven 2.2.0.

Thank you,

Lucian

Anonymous said...

I tried your artifact and get to build the SEAM project successfully from the command line with maven 2.2.0. However when I import the project as Maven project in to Eclipse 3.5 M2 0.9.8.200905041414 JDK 1.6.0_15 I get: com.ctp.seam.maven:maven-hotdeploy-plugin' does not exist or no valid version could be found pom.xml /seamTest-webapp
I wonder what I need to do to get this going?