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.