Knappsack Archetypes Part 1

This set of articles will document the contents of the Java EE archetypes for Maven. The archetypes come in four flavors, basic,minimal, sandbox and sandbox demo with each one being based on the previous one. In part 1, we’ll give an overview of the archetypes and the structure and configuration used in all of the archetypes.

The Java EE 6 Archetypes

These Maven archetypes will help developers to get up and running with a new Java EE project quickly by creating the project structure that includes pre-defined configuration files. This lets developers create a project, remove parts they don’t need, and tweak those they want to keep. The balance is to provide something useful without burdening developers with a bunch of unwanted code and configuration. The basic and minimal archetypes serve this purpose. The basic archetype contains virtually no content, just configuration and a JSF page to confirm that it is working. The minimal archetype contains just a single page of content that demonstrates that JSF, JPA, CDI and validation are working. There are also two additional archetypes for servlet containers that can be used to run core features of Java EE 6 in a servlet contain such as Tomcat or Jetty.

The sandbox archetype takes things a bit further by adding a simple JPA model pre-populated with data. This gives developers a sandbox to play in with everything configured and data to use so they can test out ideas or play around with different pieces of Java EE. I also plan on using it as the foundation project for tutorials and articles on Java EE 6 that developers can follow along with. It removes the need to create and document creating a project with a data model and example data for each tutorial. With a pre-built tutorial project we can dive right in to the meat of the tutorial without the boilerplate.

The sandbox-demo archetype takes the sandbox application and extends it into a full featured application (albeit a contrived one) that demonstrates a number of features of Java EE 6, and gives developers an idea on how to get started developing applications using the Java EE stack. The demo is by no means perfect, it is mostly the bare minimum required to implement the necessary functionality. Again, it provides a good project to launch tutorials from by showing developers how to fix those little problems in the demo application. The demo also fills a gap in demonstrating to new developers how to work with these different technologies and integrate them.

These articles will cover the different archetypes and explain the functionality and features in each. We’ll start by covering the very basics, which is the creation of the project structure and configuration in the basic archetype which is also shared with all of the archetypes.

The jee6-basic-archetype

The basic archetype is a Maven project that is configured and ready to deploy in a Java EE 6 container. It contains the configuration files necessary to start up the Java EE services such as CDI, JPA and JSF as well as the dependencies in the pom.xml file.

In the root directory of the new project, we have the pom.xml file and a readme.txt which contains a description of the project and notes on how to deploy it.
The src/main/resources/ folder contains resources that the application may need. The META-INF sub folder contains the persistence.xml file which defines the JPA datasource name and sets properties for the JPA provider. If you are deploying to JBoss you are all set to go with the DefaultDS datasource, but for Glassfish, you will need to specify the jdbc/__default datasource instead which is commented out in the file, and remove the DefaultDS definition.

The main web content resides in the src\main\webapp folder which is structured as so :

Web folder structure and content

src/main/webapp			  Top level webapp folder
 |			
 |-META-INF			
 |    |-context.xml	 	  Configuration file for tomcat
 |			
 |-resources			  Resources folder for JSF resources
 |  |-css			  CSS folder for stylesheets
 |     |			
 |     |-screen.css	 	  Default stylesheet
 |			
 |-WEB-INF			  Standard WEB-INF folder
 |   |-templates	   	  Templates folder for JSF templates
 |   |    |-template.xhtml     	  Default template file
 |   |			
 |   |-beans.xml		  Indicates that this archive file has CDI beans
 |   |-faces-config.xml		  Configuration file for JSF
 |   |-web.xml			  web.xml file containing JSF configuration
 |			
 |-home.xhtml			  Default home page using the WEB-INF\template\template.xhtml
 |-index.html			  Default file used to redirect to the home.jsf page

The beans.xml,faces-config.xml and the web.xml files have very little in them. The web.xml file provides the definition and mapping for the the faces servlet. The beans.xml is required to signal the container that this archive contains CDI beans and should be processed by the CDI deployer. This file could have other content if you use alternatives, decorators or interceptors.

Servlet Schema Version

The schema version for the web.xml defaults to 2.5 because of problems with Eclipse not recognizing the schema as valid when creating the project. For the most part, everything will work the same, but if it must be version 3.0 or later you can change once the project has been created without any problems.

Pretty much everything in the webapp folder can be used in a new application, and it isn’t that difficult to rename and move elements (templates, page file names etc) to get everything how you want it set up. In general, xml files shouldn’t be moved or renamed, but everything else can be.

If you are starting a new project, your first steps would be to move/rename/edit the template, home.xhtml and screen.css pages to your liking. You would also want to delete the readme.txt file.

The bulk of the content is in the pom.xml file which specifies all the depencies the project uses, most of which have the scope of provided since we anticipate the server providing the dependencies.

All of the archetypes also contain some code for producing an EntityManager in the application using a Stateless EJB implementing a Local interface, and a CDI qualifier to specifying injection points for the entity manager produced.

  • DataRepository.java – Qualifier for the EntityManager instance.
  • DataRepositoryProducer.java – Stateless EJB that produces the EntityManager
  • DataRepositoryProducerLocal.java – Local interface for the stateless EJB

Technically, the Local interface shouldn’t be needed under EJB 3.1 which is part of Java EE 6, however Weld, the reference implementation of CDI has problems with EJBs without a local interface in that it cannot locate them. To see how to use the produced EntityManager, see the next part which covers the minimal archetype that has a small JPA data model.

This about wraps it up for configuration, there is very little added to the core project that you probably won’t need for a JSF/CDI/JPA application making the basic archetype a good choice for a new project where you don’t need the smoke tests to see if everything is setup and working.

Next time we’ll look at the minimal archetype in detail which contains somewhat more code and functionality to test that JSF/CDI/JPA is working as planned.

4 thoughts on “Knappsack Archetypes Part 1

  1. This archetype thing is neat. Two questions:

    1. Why have index.html redirect to home.jsf? Why not just make your welcome file home.jsf?

    2. Why do we need to use a DataRepository qualifier and producer? Why not just inject the EntityManager directly where it is needed?

    1. 1) That’s an interesting point, It used to be that the welcome pages had to be a static resource so you had to redirect to the JSF page. I don’t know whether it is still true or not.
      2) Using a producer allows you to have a conversation scoped entity manager so you re-use the same entity manager on each request in the conversation.
      The qualifier isn’t required but helps in case you later add a second source of data.

      1. When would one use the PersistenceContext annotation then?

        Wouldn’t an entity manager injected with:

        @PersistenceContext(unitName = “pu”, type=PersistenceContextType.EXTENDED)
        private EntityManager em;

        have dependent scope and therefore be tied to the lifecycle of the bean it was injected into? If the bean in which the entity manager was injected had conversation scope it would be the same as using the factory, right? From the @Dependent javadocs it looks like maybe if there were multiple injection sites it wouldn’t get reused though.

        Maybe you’re not using PersistenceContext because you are trying to support plain Servlets (without EJBs)?

        Thanks for sharing your knowledge.

        1. That is exactly it, we want it in Conversation scope so it will be used by the different scoped beans across the conversation. That way, if we grab the same entity in two different beans, they will be same actual entity from the same entity manager which is a good thing.

          We use the Persistence Context annotation to coax the entity manager from the application server. If you have looked at the servlet archetypes, we create it manually in the producer method.

          There may be room for improvement in my implementation, such as using an extended PC within a stateful EJB that is conversation scoped. That would be more in the spirit of how it was meant to work. The PC would live on until the bean was destroyed which in this case would be when the conversation ended.

          Cheers,

          Andy Gibson

          Cheers,

          Andy