I am currently working in Nouméa, New Caledonia (western part of the pacific) to setup an environment for the continuous integration of ADF Faces applications for a department of the local government. The main challenges are to be able to perform all the tasks in the development lifecycle like compile, test, build, deploy, release etc. outside of JDeveloper and to manage the library depencies by ourself and not by JDeveloper. For this we use Maven2.
Since Maven is not tied to a certain IDE it cannot, and should not, rely on the IDE’s project files but instead it uses its own project file, the pom.xml. In this file you define almost everything that’s important for the project, libraries (with version), the source control system, the developers, the application servers etc. etc. With this information all the steps in the development lifecycle, like compile, test, build, release, deploy etc. can be performed, independent of any IDE. You can (could) even use this information to create the IDE’s projectfiles and have an easy start for new developers or everybody might even use their own favorite IDE. Maven follows the ‘convention over configuration’ principle and takes care of many configuration issues, but off course you still need to define the project’s information.
So we started off to create a set of standard pom files that includes all the information for an ADF Faces project, especially all the required libraries. That is, we defined a so called multimodule application with a model, a viewController and an ear project each with its own pom file. Notice that the ear project is not a standard JDeveloper project but we need it to build and deploy the ear file by Maven. By the way, for other IDE’s, this is quite a common construction.
Now, when you start a new ADF Faces project you can just copy and paste these files and you’re ready. But when you try to make a build (an almost empty one, but a build anyway), using the command mvn package it will fail, because it cannot retrieve the ADF libraries. This needs some explanation. Maven uses the concept of a library (also called a dependency) repository. When it has to perform a certain task (compile, test, build etc.) it checks for the dependencies in the local repository and if they are not available it will try to download them from the central repository on the internet. Almost all of the open source libraries are available in the central repository (or its mirrors), but the commercial ones and your companies components are not. So you need to setup an internal repository and deploy the required commercial libraries in there. By the way, your own projects will be able to deploy their artifacts automatically. An internal repository is actually nothing more than a directory, that is accessible via HTTP to download and with scp or ftp to deploy the artifact. During deployment, maven will add some metadata and takes care of versions. To find and deploy all the ADF libraries, with its version, is quite some work, but when it’s finally done you’ll enjoy a lifelong advantage from it. To use this repository, you only have to add its information to your local Maven configuration file, settings.xml. Now the build will be succesfull.
Although this provides already full Maven support for an ADF Faces project, it is not completely what we wanted, because we would like JDeveloper to conform to the Maven standards, like its proposed directory layout. You can off course define this in every JDeveloper installation in the default project properties (and make sure it is defined again in every new installation), but we wanted a more Maven approach: generate the default directory layout and generate the JDeveloper project files.
Creating a default directory layout, what maven calls an archetype, is quite simple and is described in their documentation. With the help of the MyFaces project, that provided us with an example of a multi-module archetype, we created the required directory structure. With the help of a simple jsf application that we created in JDeveloper, we added the web.xml, adf-faces-config.xml and faces-config.xml files and a very simple jsf page to the project. We added also the pom files we made earlier and added all the files to the archetype.xml file. That’s it :
To use it, it must be installed in the local repository first. Issue the command mvn install (in the main project directory) and you’re done. To let others use it, it must be installed in the internal repository : mvn deploy and that’s done too :-). We versioned this archetype, according to the matching JDeveloper version: 10.1.3.1
We can now create the project everywhere on our machine, so go to your favorite project directory and issue the command : mvn archetype:create -DarchetypeGroupId=nc.recif.maven2 -DarchetypeArtifactId=jdev-adf-archetype -DarchetypeVersion=10.1.3.1 -Dversion=1.1-SNAPSHOT -DgroupId=nc.dtsi.axi.demo.greatComponent -DartifactId=greatComponent and see the magic happen.
The last piece of the process is to create the jdeveloper project files. We thank the MyFaces – Trinidad project for the maven-jdev-plugin. In a previous post I described how to install it in your local repository. Configure it in the parent’s pom file and issue the command mvn jdev:jdev and again some magic happens: the jws and several jpr files are created that you can open with JDeveloper and start working. Notice that these are still 10.1.3.0.4 version files and will be automatically migrated.
You can run the jsf file within JDeveloper, but you can also build, a nice and functional war file is generated that can also be deployed on the applicationserver. How you’d do that from Maven is another story.
Unfortunately the jdeveloper plugin generates a project compiler configuration that seems to be incompatible with the behaviour of the JDeveloper business components wizard. It quite easy to fix but it resulted in our own (temporary) fork of the plugin. We’re sure it will be fixed soon in the official (but still snapshot) version.
To summarize, we developed a maven ADF Faces archetype that includes all the dependencies and all the necessary configuration. Within the generated project directory we use the maven JDeveloper plugin to generate the JDeveloper project that will function as the starting point for development. This project is also ‘Maven enabled’ and thus fully available for continuous integration which gives much more control over the build, deploy, test and release processes.
Aino,
Your blogs have been very helpful, in getting started with ADF and Maven, but I’m struggling with the most important part — developing an archetype for my team. Have you contributed your archetype with an open repository like CodeHaus, or would you otherwise be willing to share it by another means? I’m struggling mainly with “creating a standard set of POM files” for an ADF project. Any assistance you can provide (or direct me to) would be greatly appreciated.
Hi Aino,
Online documentation for our future architecture ?
See you later.
Aino,
I’m working on the same kind of thing. I have cobbled together some code to extract the library definitions from a JDeveloper installation and generate “jar only” pom definitions for Maven 2. It also generates some shell scripts that will copy all of the jars from JDeveloper into your local maven repo using mvn deploy-file commands.
The next step will be to modify the plugin from the trinidad project to generate references to the “library” pom’s.
Please let me know if this makes sense. I think we could wrap all these pieces together into a single solution!
The next step to continuous integration with Continuum may involve some nuisances. I wrote a post based on my own experiences with Maven 2 and Continuum on my own blog, which you may find interesting to read as well.
Top-location to do your work, by the way, I envy you a lot!
Great post Aino ! 😉