Showing posts with label thomas. Show all posts
Showing posts with label thomas. Show all posts

Tuesday, May 22, 2012

CDI Query Alpha 4 Released

There's been a while now since my last post on CDI Query, but that doesn't mean we haven't been busy working on it! Last week I've pushed another Alpha release to Maven Central, and I'm very curious about your feedback!

Summarizing the feature highlights since the last post:
  • Entities: Support for entities defined in orm.xml descriptors, @IdClass and composite primary keys: this should close the gap for all kind of entities.
  • Method expression have gotten some more love: First of all validation. As those expressions are not very stable once it comes to refactorings, they are now validated at extension initialization. Also there's now support for ordering and nested properties.
  • Auditing: Keeping track of entity creation and change dates is often a requirement in enterprise applications. This is supported by simpy annotating your entities temporal properties with @CreatedOn or @ModifiedOn. 
  • Extensions in the Criteria Support API: Allows now selections. There's also been a major cleanup with regards to separation of API and implementation. 
  • Postprocessing of query methods with the QueryResult class. This will encapsulate the result of a method expression or a @Query annotation, and allows to add ordering, paging and other post processing dynamically.
  • The EntityHome API, inspired by the Seam 2 application framework, helps you to easily connect your entities to the UI and implementing CRUD pages with a few lines of code.
There have already jumped a few people on board, providing great feedback, bugfixes and new features! Special thanks to:
  • Jason Porter (bug fixes, Solder upgrade, support for PK related features and feature requests)
  • Marek Smigielski (bug fixes, feature requests)
  • Aaron Walker (API extensions)
  • and various others, providing some food for thought - thanks guys!

So what's next? We're still in Alpha, and some features have been - frankly said - just been hacked in to try them out. So there is need for cleanups. Featurewise there is also a polish of the various APIs required, but a larger part could be improved support for stored procedures, and a Forge plugin (in case you don't know Forge - hurry up and install it!). Or whatever you feel is missing - looking forward to your Issues on GitHub!

Tuesday, November 22, 2011

CDI Query Module First Alpha Released!


It's been some months now since we started exploring CDI extensions as a small exercise. As it turned out, the exercise forged into something usable which we're pushing now in the open as a first Alpha shot.

So I'm happy to announce the availability of the CDI Query Module on Maven Central! The module helps you creating JPA queries with much less boilerplate, and is of course leveraging the CDI extension API as well as Seam Solder. Some of the feature highlights are:

Query By Name

Assuming you have a Person entity which looks probably similar to this:

@Entity
public class Person { 

    ... // primary key etc. skipped

    @Getter @Setter
    private String firstName;
    
    @Getter @Setter
    private String lastName;

}

You can simply create a DAO interface to query for Persons:

@Dao
public interface PersonDao extends EntityDao<Person, Long> {

    Person findByFirstNameAndLastName(String firstName, String lastName);

}

This interface does not need to be implemented. A client can just inject it, call the interface method and in the background, the JPA query is automatically created and executed. To create the query, the method name is analyzed and matching the name to entity properties.

public class PersonAction {

    @Inject
    private PersonDao personDao;
    
    public void lookup() {
        person = personDao.findByFirstNameAndLastName(firstName, lastName);
    }

}

Note that the base interface contains also a couple of other methods which you might also expect from an entity DAO. Ideally, you should not need to inject an EntityManager anymore.

Query by Query Strings and Named Queries

Of course matching property names is not extremely safe to refactorings (some more validation support here is on the roadmap) - if you like to have more control over your JPA queries, you can also annotate the method with the query to execute:

@Dao
public interface PersonDao extends EntityDao<Person, Long> {

    @Query("select p from Person p where p.ssn = ?1")
    Person findBySSN(String ssn);

    @Query(named=Person.BY_FULL_NAME)
    Person findByFullName(String firstName, String lastName);

}

Criteria API Simplifications

If you're not a big fan of query strings but rather prefer using the JPA 2 criteria API, we also allow to simplify this with a small utility API:

public abstract class PersonDao extends AbstractEntityDao<Person, Long> {

    public List<Person> findAdultFamilyMembers(String name, Integer minAge) {
        return criteria()
                    .like(Person_.name, "%" + name + "%")
                    .gtOrEq(Person_.age, minAge)
                    .eq(Person_.validated, Boolean.TRUE)
                    .orderDesc(Person_.age)
                    .createQuery()
                    .getResultList();
    }

}

All the code is hosted and documented on GitHub. Please:

  • Give feedback! If you find this useful or actually not so, we're happy to hear what is still missing.
  • Participate! Forking and creating pull requests are really a breeze on GitHub :-)


Credits:

  • Bartek Majsak for improving the initial code, taking care about quality reports and soon finalizing the stuff on the validation branch ;-) (just kidding, check out Bartek's cool work on the Arquillian Persistence Module!)
  • Grails GORM for inspiring me for this Java implementation
  • The CDI folks for a really great specification
  • Last but not least the Arquillian guys, developing and testing this stuff is pure fun with Arquillian!

Friday, November 11, 2011

JBoss Forge JRebel Plugin - Video Tutorial

It's actually out for quite a while now (and therefore already slighly out of date) but I have hardly found some time to blog about it: If you're using JRebel and JBoss Forge, have a look at this Video tutorial how to use both of them together.



Make sure to watch it in HD and full screen mode. Thanks to Chris "Kubrik" Reimann for putting the tutorial together!

As an addition, Forge now also supports checking out specific versions of a plugin, which is in our case version 1.0.0.Beta1 of the JRebel plugin. We've also added the plugin to the Forge plugin repository index so you can search for it.

By the way, if you're only using one of the tools or (even worse) none of them, this is the perfect opportunity to get a quick hands-on.

Thursday, September 23, 2010

JavaOne 2010

Time is running quickly, and shocked we have realized that this year's JavaOne is already over - high time to share some conference highlights with you! It's the first time that Oracle drove the conference after acquiring Sun, so we were curious whether the spirit we valued so much during the last years is still around. To give you the conclusion already now - it's a yes, but there are some drawbacks.

It's clear that JavaOne is just the "side conference" this year - it had to leave its home in the Moscone center, which is mainly hosting Oracle OpenWorld. With the move, things got slightly smaller - session rooms (which is probably the most annoying aspect), the chill-out zones and exhibition space, ... . But of course it's not the size that matters; it's the content that compensates for it! The quality of the talks, we've seen, has been very good so far, and as usual it's a lot of great ideas, visions and news floating around. Below we give you a quick summary of the latest Java news and session highlights:

Keynotes

On Sunday evening Larry Ellison hosted the opening session of the Oracle OpenWorld. First of all most of the JavaOne attendees were rather surprised, they were not allowed to join in for this keynote. Nevertheless a quick update on this keynote is provided here before moving on with the real Java stuff.

The first presentation was the Oracle Exalogic Elastic Cloud, which is very briefly summarized “The Cloud in a Box”. The Exalogic box provides both hardware and software. Oracle further announced benefits to the customer due to the homogeneous hardware and software, which is also reflected in Oracle's new tag line "Hardware and Software Engineered to Work Together". Exalogic combines up to 30 servers, including storage (hard disk drive and SSD) and a high-speed internal network between the servers in a rack. The Exalogic solution is designed and optimized to run Enterprise Java applications, i.e. the Oracle Fusion Middleware stack, similar to the Oracle Exadata center which runs Oracle DB servers. Oracle Exalogic can be scaled from 1/4 up to 8 racks, whereas according to Larry Ellison two full racks were enough to host all of Facebook.com.

Afterwards the Unbreakable Enterprise Kernel was presented, which will be 100% RedHat compatible. It is Oracle’s answer to the slowly moving RedHat distribution; according to Larry Ellison RedHat is 4 years behind the mainline.

Finally Oracle Fusion Application was unveiled. It is a CRM/ERP/HRMS system which offers the features of products earlier acquired by Oracle such as PeopleSoft and Siebel. The entire code basis has been re-written based on Oracle Fusion Middleware, which had to be enhanced to support all the middleware functionality needed. It took Oracle five years to develop Oracle Fusion Applications and is one of the biggest projects Oracle ever faced.

On Monday and Tuesday the JavaOne Opening Keynote and the General Technical Session were about the Future of Java, which is the right thing to do after the Sun/Oracle merger last year. After finalizing the Java EE 6 Specification in December 2009, this year the focus is moved to the next version of the Java Standard Edition (Java SE). The last update on the Standard Edition was Java SE 6 in 2006. After a five years break we will get two new versions within roughly 18 months, OpenJDK 7 in mid 2011 and OpenJDK 8 in late 2012.

Thomas Kurian, Executive Vice President, Product Development at Oracle at JavaOne 2010 Opening Keynote

Java SE version 7 contains a bunch of smaller language changes and enhancements. Project Coin contributes most of the new language features, such as Diamond Operator for declaration and instantiation of generics, Try-with-Resource block for proper closing of resources implementing the new AutoCloseable interface in the java.lang package, Mutli-Catch and Re-Throw of Exceptions, Switch statements with Strings and String literals using “_” (int a = 0b100_1010_0011;). Additionally JSR 292 is implemented in this release, which supports mainly other languages setting up on top of the JVM, such as Scala and Groovy. The Fork/Join Framework provides better support for modern multi core processors. There are some other updates shipped with this release such as JDBC 4.1, which supports resource management, and more.

Java SE version 8 will bring a new modularization concept, finally no more hassle with the JAR files and the classpath! Project Jigsaw is defining these new features. A module (*.jmod) contains all its classfiles and a declaration of modules it depends on. This declaration is placed in the module-info.java file, which contains the name and the version of the dependencies. Modules need to be installed on the target system before they can be executed. A second set of major improvements will come out of the Project Lambda. These improvements include closures, value classes - no need to write getters and setters, extension methods and eventually reification.

On the tooling side two new versions of Netbeans IDE will be released during 2011 (check the feature list). Project Glassfish also committed to publish two new releases during calendar year 2011 (check the feature list).

JavaFX script will not be further developed by Oracle and is replaced by a set of APIs, which is supposed to make the technology more accessible to all Java developers without the need to learn a new language. Additionally 3D support is added to JavaFX! According to Thomas Kurian there will be direct 3D hardware rendering support using Microsoft DirectX or OpenGL and a HTML5/JavaScript output for web-based clients.

Not surprisingly, hot topics like the lawsuit with Google or the future of the JCP were not discussed.

Session Highlights



In Hyperproductive JSF 2.0, JSF co-spec lead Ed Burns showed a couple of reasons why your project development might run with hand brake pulled. With several demos he showed probably underused new features in JSF 2 like Groovy support for all JSF artifacts that get hot deployed, or the new facelets >ui:debug< tag that gives you information on the component trees or scope variables. He also emphasised the importance of standards or conventions for a team, which is indeed an often overlooked aspect when a new project needs to get out quickly. This was supplemented by another talk on the new JSF 2 composite components, which make it very easy to create reusable components for e.g. your corporate layout and build up a highly productive framework like that.

While Maven founder Jason van Zyl's talk on Maven 3 was not intended to show new Maven features, he gave an overview of how he envisions future enterprise development. This includes tight integration from IDE over SCM to CI, up to a new tool called Proviso which is targeted to standardize enterprise deployment processes. Another interesting aspect was how Sonatype standardized their component model around Maven and Hudson plugins as well as their repository manager to achieve better reuse, which is now all built around JSR-330.

As a company mainly dealing with enterprise development we were of course giving a main focus on all the Java EE 6 talks. Spec lead Roberto Chinnici gave one of them explaining the Java EE programming model. Even though we have been working with the technology for a while now, this gave a nice summary and showed again that you still get that extra little information from JavaOne that makes the conference very useful when you hear things from the mind behind it. Roberto provided a quick overview on managed beans, CDI and several "must knows" when changing to the new programming model.

On the same track was Dan Allen with presenting in depth on CDI and Seam 3. The talk went from all the CDI concepts from typesafe injection with qualifiers over loose coupling with events to the SPI in CDI leading to Seam 3. This is now split in several independent modules where your application can take what it needs. Spinning this thought further - why not break up all the EJB services and make them a portable extension? We might see something like this in Java EE 7. By the way, Dan is not only an excellent author (when are we going to see Seam in Action 2nd edition?), but also a great speaker - make sure to visit one of his talks when you got a chance.

To close the sessions on Java EE, we were deeply impressed by the session on Arquillian. The framework evolved out of working on the RI for CDI (Weld) and takes the idea of the new EE component model to your unit tests. By eliminating the build to create archives for integration tests, the team around Arquillian has managed to decrease complexity and improve speed of the integration test massively - something critical if you want your team to actually use them. The outcome was a generic component testing framework, which we're convinced will significantly improve quality on EE applications. You can programmatically create an archive on the components you want to test, and run the test either in container or as client in a running application server. This is the time when you feel that enterprise engineering is still a young discipline - why has this not been around for longer?

Last but not least, if you have been following our people spotlights you probably know we're big fans of the Java Posse! As in the last 4 years the posse was present also at this year's JavaOne holding a BoF in the Mason street tent, celebrating the 5th anniversary of the Java Posse. While it was less interactive than the last years BoFs, we got a great show with special guest "Loose" Bruce Kerr giving a live performance of the Posse song, funky costumes and interesting insights on the future of Java - well kind of. Go and download the recordings - although this time I guess it's too bad this is not a video podcast!

As usual we enjoyed being here - CU again next year!

Friday, July 30, 2010

Using Seam 2 with JPA 2

It’s a difficult time to architect new Java web applications. Seam 2 is a proven and well working application stack, but we will hardly see many new versions on the Seam 2 train. Java EE 6 is in general an excellent option, but if your customer’s choice of application server does not yet support it, it is not reasonable. Also there is still some time left for Seam 3 prime time, which builds on top of Java EE 6.

Facing this kind of choice recently, I looked into possible migration paths between the two variants. One thing I have seen often on Seam 2 applications is that people really like the Hibernate criteria API and therefore use Hibernate directly. While Hibernate is an excellent ORM framework, it’s preferrable to use the JPA API when moving to Java EE 6. So - why not use Seam 2 with JPA 2, which finally features an even better (typesafe) criteria API?

It turns out to be a quite easy setup (once you get classloading right), with some small extra modifications. I’ve been using Maven, Seam 2.2 and Hibernate 3.5.4 on JBoss 4.2.3. Lets start with preparing the server. You need to remove the old Hibernate and JPA classes and add the new persistence provider with some dependencies (of course this will be different on other servers):

To be removed from server/lib:


Add to server/lib:


Next lets create a sample Seam project. I’m using the CTP Maven archetype for Seam. In the POM file, remove the references to the Hibernate and old JPA libraries and add the new JPA 2 libraries:

<!-- Remove all embedded dependencies
<dependency>
<groupId>org.jboss.seam.embedded</groupId>
<artifactId>...</artifactId>
</dependency -->

<dependency>
<groupId>org.hibernate.javax.persistence</groupId>
<artifactId>hibernate-jpa-2.0-api</artifactId>
<version>1.0.0.Final</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-core</artifactId>
<version>3.5.4-Final</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-jpamodelgen</artifactId>
<version>1.0.0.Final</version>
<scope>provided</scope>
</dependency>

Note: If you’ve been using embedded JBoss for your integration tests, this will probably not work without exchanging the JARS there too. I’ve been moving away from this approach as it turned out to be a common reason for headache on our nightly builds as well as running tests in Eclipse. I’m very excited to see Arquillian evolving on this topic!

JPA 2 integrates with JSR 303 bean validation, which is the successor of Hibernate Validator. Unfortunately Seam 2 has references to Hibernate Validator 3, where JPA needs version 4. Adding the validator legacy JAR fixes this problem. As bean validation is now part of Java EE 6, we can add it to the server classpath as shown above, as well as to our POM:

<dependency>
<artifactId>validation-api</artifactId>
<groupId>javax.validation</groupId>
<version>1.0.0.GA</version>
<scope>provided</scope>
</dependency>

Now it’s time to move to some code. You can jump straight in your persistence config files and bring the schema up to version 2:

<persistence xmlns="http://java.sun.com/xml/ns/persistence"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd"
version="2.0"> ...

<entity-mappings xmlns="http://java.sun.com/xml/ns/persistence/orm"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/persistence/orm http://java.sun.com/xml/ns/persistence/orm_2_0.xsd"
version="2.0"> ...

Seam proxies entity managers to implement features like EL replacements in JPQL queries. This proxy does not implement methods new in JPA 2 and will therefore fail. You can write your own proxy very easy:

public class Jpa2EntityManagerProxy implements EntityManager {

private EntityManager delegate;

public Jpa2EntityManagerProxy(EntityManager entityManager) {
this.delegate = entityManager;
}

@Override
public Object getDelegate() {
return PersistenceProvider.instance()
.proxyDelegate(delegate.getDelegate());
}

@Override
public void persist(Object entity) {
delegate.persist(entity);
}
...
}

Add the special Seam functionality as needed. In order to use the proxy with Seam, you’ll have to overwrite the HibernatePersistenceProvider Seam component:

@Name("org.jboss.seam.persistence.persistenceProvider")
@Scope(ScopeType.STATELESS)
@BypassInterceptors
// The original component is precedence FRAMEWORK
@Install(precedence = Install.APPLICATION,
classDependencies={"org.hibernate.Session",
"javax.persistence.EntityManager"})
public class HibernateJpa2PersistenceProvider extends HibernatePersistenceProvider {

@Override
public EntityManager proxyEntityManager(EntityManager entityManager) {
return new Jpa2EntityManagerProxy(entityManager);
}

}

If you use Hibernate Search, have a look at the superclass implementation - you might want to instantiate a FullTextEntityManager directly (as you have it in your classpath - but note that this has not been tested here).

Both implementations are on our Google Code repository, and you can integrate them directly over the following Maven dependency:

<dependency>
<groupId>com.ctp.seam</groupId>
<artifactId>seam-jpa2</artifactId>
<version>1.0.0</version>
</dependency>


You’re now ready to code JPA 2 queries! We’ve already included the meta model generator utility, so let’s activate it for the build:

<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>build-helper-maven-plugin</artifactId>
<executions>
<execution>
<id>add-source</id>
<phase>validate</phase>
<goals>
<goal>add-source</goal>
</goals>
<configuration>
<sources>
<source>${basedir}/src/main/hot</source>
<source>${basedir}/target/metamodel</source>
</sources>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.bsc.maven</groupId>
<artifactId>maven-processor-plugin</artifactId>
<version>1.3.1</version>
<executions>
<execution>
<id>process</id>
<goals>
<goal>process</goal>
</goals>
<phase>generate-sources</phase>
<configuration>
<outputDirectory>${basedir}/target/metamodel</outputDirectory>
<processors>
<processor>
org.hibernate.jpamodelgen.JPAMetaModelEntityProcessor
</processor>
</processors>
</configuration>
</execution>
</executions>
</plugin>


In order to use the processor plugin, you also need the following Maven repositories in your POM:

<pluginRepository>
<id>annotation-processing-repository</id>
<name>Annotation Processing Repository</name>
<url>http://maven-annotation-plugin.googlecode.com/svn/trunk/mavenrepo</url>
</pluginRepository>
<pluginRepository>
<id>jfrog-repository</id>
<name>JFrog Releases Repository</name>
<url>http://repo.jfrog.org/artifactory/plugins-releases</url>
</pluginRepository>

Run the build, update the project config to include the new source folder - and finally we’re ready for some sample code:

@Name("userDao")
@AutoCreate
public class UserDao {

@In
private EntityManager entityManager;

private ParameterExpression<String> param;
private CriteriaQuery<User> query;

@Create
public void init() {
CriteriaBuilder cb = entityManager.getCriteriaBuilder();
query = cb.createQuery(User.class);
param = cb.parameter(String.class);
Root<User> user = query.from(User.class);
query.select(user)
.where(cb.equal(user.get(User_.username), param));
}

public User lookupUser(String username) {
return entityManager.createQuery(query)
.setParameter(param, username)
.getSingleResult();
}
}

This is now quite close to Java EE 6 code - all we will have to do is exchange some annotations:

@Stateful
public class UserDao {

@PersistenceContext
private EntityManager entityManager; ...

@Inject
public void init() { ...
}

Enjoy!

Wednesday, April 28, 2010

JBoss Seam Maven Archetype Video Tutorial

While the release of Seam 3 is getting closer, you might still want to do quick prototyping based on a Seam 2 project. Of course this is easiest done with either seam-gen, or if you're like me a Maven user, with an Archetype.

Chris has prepared a video tutorial on how to get started with our Maven WAR archetype (featuring hot deploy, TestNG with embedded JBoss and either RichFaces or ICEFaces inclusion) based on one of my previous articles. Check it out here (best seen in HD [UPDATE: sorry, missed the HD embed]):



Enjoy!

Friday, October 30, 2009

Unit Testing EJBs and JPA with Embeddable GlassFish

Java EE 6 has been a topic here at CTP for quite a while now. During summer I had the pleasure of conducting an internship which was targeted to explore the possibilities of the upcoming standard, namely EJB 3.1, JPA 2.0, JAX-RS, JSF 2.0 and JCDI on top of GlassFish v3 - and it turned out surprisingly productive, although all implementations were far from being in a release state!

Only one thing we failed to run in a stable way: The new EJB 3.1 container API refused to run our unit tests. The main problem was JPA support - persistence units got not recognized and EJBs usually failed with a NullPointerException calling the EntityManager.

Alexis and Adam recently blogged about this specific feature, and of course I had to get back and try it out myself! Indeed, starting up a container and looking up EJBs works fine. But to test your Entities there are still a few tweaks you might want to apply.

Start with creating a Maven project and add the embeddable GlassFish dependency. I'm also using TestNG instead of JUnit, as it has a nice @BeforeSuite annotation which allows starting the container only once before running your tests.

<dependency>
<groupId>org.glassfish.extras</groupId>
<artifactId>glassfish-embedded-all</artifactId>
<version>3.0-b69</version>
<scope>provided</scope>
</dependency>

<dependency>
<groupId>org.testng</groupId>
<artifactId>testng</artifactId>
<version>5.9</version>
<scope>test</scope>
<classifier>jdk15</classifier>
</dependency>

As described in Alexis' blog, you can start your EJBContainer with a reference to your GlassFish domain. This will allow you to start up data sources you most probably need to properly test your JPA code.

The disadvantage here is that you either depend on a hardcoded location or a system property which each of your team members have to set. Or, in case of your continuous integration system, you might not want to have a GlassFish installation at all.

Fortunately you can create a mini GlassFish domain with only a few files. The image below shows the files you need and how I placed them in my Maven module:



You can take your existing domain.xml containing your data sources and place it in here - you can reference it now relatively to your module location. Your unit tests then start with:

private static Context ctx;
private static EJBContainer container;

@BeforeSuite
public static void createContainer() {
Map<String, Object> properties = new HashMap<String, Object>();
properties.put(EJBContainer.MODULES, new File("target/classes");
properties.put("org.glassfish.ejb.embedded.glassfish.installation.root",
"./src/test/glassfish");
container = EJBContainer.createEJBContainer(properties);
ctx = container.getContext();
}

This will run your unit tests against your development database. In case you want to run them in a local database, you can simple replace the connection pool config in your domain.xml, e.g. with a local Derby installation:

<jdbc-connection-pool datasource-classname="org.apache.derby.jdbc.EmbeddedDataSource"
res-type="javax.sql.DataSource" name="[your DS name]" ping="true">
<property name="ConnectionAttributes" value="create=true" />
<property name="DatabaseName" value="./target/unit-test" />
<property name="Password" value="" />
<property name="User" value="" />
</jdbc-connection-pool>

This creates the database in your target folder and requires adding Derby to your Maven POM:

<dependency>
<groupId>org.apache.derby</groupId>
<artifactId>derby</artifactId>
<version>10.5.3.0_1</version>
<scope>test</scope>
</dependency>

Unfortunately this setup might not match with the configuration in your persistence.xml and generate invalid SQL for your test database. You can either solve this with Maven filters in different profiles, or alternatively create a staging directory for your EJBContainer. I'm using the Apache Commons IO tools here for convenience:

...
private static final String MODULE_NAME = "embedded";
private static final String TARGET_DIR = "target/" + MODULE_NAME;

@BeforeSuite
public static void createContainer() throws Exception {
File target = prepareModuleDirectory();
Map<String, Object> properties = new HashMap<String, Object>();
properties.put(EJBContainer.MODULES, target);
properties.put("org.glassfish.ejb.embedded.glassfish.installation.root",
"./src/test/glassfish");
...
}

private static File prepareModuleDirectory() throws IOException {
File result = new File(TARGET_DIR);
FileUtils.copyDirectory(new File("target/classes"), result);
FileUtils.copyFile(new File("target/test-classes/META-INF/persistence.xml"),
new File(TARGET_DIR + "/META-INF/persistence.xml"));
return result;
}

You can use the @AfterSuite annotation to clean up the temporary folder. Note that with this setup, the EJB lookups change:

protected <T> T lookupBy(Class<T> type) throws NamingException {
return (T) ctx.lookup("java:global/" + MODULE_NAME + "/"
+ type.getSimpleName());
}

Wednesday, July 1, 2009

JBoss Seam Archetype - now with ICEfaces

Last week I visited Jazoon - and had a great opportunity to see several impressive demos of ICEfaces! Of course I had to immediately get my hands on it, and started to integrate ICEfaces in the JBoss Seam Maven archetype (as described in my previous post).

You can give it a spin by starting a shell and running Maven with the Archetype plugin:

>mvn archetype:generate -DarchetypeCatalog=http://tinyurl.com/jbsarch -DajaxLibrary=icefaces
[INFO] Scanning for projects...
[INFO] Searching repository for plugin with prefix: 'archetype'.
...
Choose archetype:
1: http://tinyurl.com/jbsarch -> jboss-seam-archetype (Archetype for JBoss Seam Projects)
Choose a number: (1): 1
Define value for serverDir: : [your JBoss 5 server location]
Define value for groupId: : [your groupId]
Define value for artifactId: : [your artifactId]
Define value for version: 1.0-SNAPSHOT: : [your version]
Define value for package: : [your package]
Confirm properties configuration:
serverType: jboss5
ajaxLibrary: icefaces
...
Y: : y
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESSFUL
[INFO] ------------------------------------------------------------------------
...


Make sure you don't misspell "icefaces", this will otherwise screw up the application. No input validation in Maven Archetype yet, but I started looking into it ;-)

Again, change to the project directory and build the project:

>mvn package

Now this also executes a sample unit test (fingers crossed it works this time ;-) - thanks to Oscar for the feedback!

Have fun with it! Anybody mind contributing a decent layout template?

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)!

Friday, May 29, 2009

JBoss Seam Hot Deploy with Maven - EAR Projects

As requested on some comments on my previous posts (initial post and update), the Seam Hotdeploy Maven plugin now works also with EAR projects.

Some more details on how to configure your project can be found in our Google Code Wiki. The plugin now defines a new packaging type for Seam WAR modules - the only possibility to override the war:war goal in the package phase.

If you're interested in how to override the default lifecycle Maven goal, you can check out the plugin source - something I haven't been able to google easily. Or, maybe wait for a dedicated blog post - stay tuned!

Something you should definitely checkout with the Hot Deploy plugin is the Maven CLI plugin. See the great post from Dan here, or the integration in the sample POM.

As usual, feedback and contributions are very welcome!

Friday, May 8, 2009

CTP Java Pencast #1

Welcome to the first pencast!
Switch on audio to fully enjoy the show!
Be aware that this has been recorded in one single shot and without any post-processing...



Shownotes:
  • JavaME enabled pen by Livescribe
  • Customer Technology Stack: JSF 1.2, JBoss Seam 2.1 (with jBPM), Hibernate 3, WebLogic Server 10.3 or JBoss Application Server 5
  • Java EE5 : JSF 1.2, EJB 3.0, JPA 1.0, Glassfish v2
  • Java EE6 : JSF 2.0, EJB 3.1, JPA 2.0, Glassfish v3
So come back to visit us for checking details on the discussed web technology stacks!

Thursday, April 16, 2009

JBoss Seam on Google App Engine - First Steps

[UPDATE] The latest Morjarra release 1.2_13 as well as the latest Appengine SDK 1.2.2 seem to fix a couple of problems described below. My task backlog is actually growing :-) but I hope I find some time to look again how things work with these new versions.

I spent the last three weeks in a repetition course of the Swiss army - far away from any Java code. Naturally my fingers started to itch while reading the announcement of Google that their App Engine now supports Java! So I grabbed my MacBook to enjoy the sun, Java coding and Eastern holidays.

As I usually write web applications with JBoss Seam, I decided to give the framework a try in the Google cloud - preparing for a bumpy road as Seam founds on standards which are mostly listed as either not or not known to be working. The following article describes the (bad) tweaks I had to do to get something basic running - I guess if you start doing serious development, you might hit more walls.

First, install the Eclipse Plugin for App Engine and create a new project. I'll base my descriptions on this initial setup. Switch on sessions in appengine-web.xml:
<sessions-enabled>true</sessions-enabled>

Setting up JSF 1.2

Download the latest Mojarra 1.2 release [1.2_12] and put it in the WEB-INF/lib directory. You can configure the Faces servlet in web.xml as usual
<servlet>
<servlet-name>Faces Servlet</servlet-name>
<servlet-class>javax.faces.webapp.FacesServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>Faces Servlet</servlet-name>
<url-pattern>*.seam</url-pattern>
</servlet-mapping>

Starting Jetty with only this will fail due to some incompatibilities of Jetty and Mojarra. As with Seam we will need JBoss EL anyway, we can configure Mojarra to use the JBoss EL ExpressionFactory. Add the JBoss EL JAR to WEB-INF/lib and the following XML to your web.xml:
<context-param>
<param-name>com.sun.faces.expressionFactory</param-name>
<param-value>org.jboss.el.ExpressionFactoryImpl</param-value>
</context-param>

Now it's already patch time. Jetty in the Google environment seems to have a bug in its Servlet API implementation, missing the ServletContext.getContextPath() method (new in version 2.5). Also, Mojarra tries to be clever about initialization work and uses Threads in the ConfigManager - the App Engine SecurityManager will let the whole thing blow up. Something similar happens in the JBoss ReferenceCache class. All patched classes can be found here. Drop the Java code in your source folder, Jettys classloader will pick it up.

This will at least make the whole thing start up. I also added facelets (JAR file, view handler in faces-config.xml and view suffix in web.xml).

Unfortunately, using RichFaces components is an absolute no go on App Engine. RichFaces is full of references to AWT or JAI classes, which Google blocks completely. If anybody wants to try ICEFaces - good luck!

Adding Seam

Now it's time to add all the Seam stuff. Quite a couple of JARs to put into the application. I basically used Seam 2.1.1.GA and libraries from JBoss 4.2.3.GA. The complete list of what should go into WEB-INF/lib is shown in the screenshot below.



JTA is not even on the list of APIs Google gives a recommendation, so let's fall back on Java SE behavior. Configure components.xml with:
<transaction:entity-transaction entity-manager="#{entityManager}"/>


Although we cannot use Hibernate as persistence provider, Seam has a couple of dependencies to it (e.g. when using Hibernate Validators). As soon as we have it in the classpath, Seam activates its HibernatePersistenceProvider component. This will behave pretty bad, and for simplicity we just override this component:
@Name("org.jboss.seam.persistence.persistenceProvider")
@Scope(ScopeType.STATELESS)
@BypassInterceptors
@Install(precedence = Install.APPLICATION,
classDependencies={"org.hibernate.Session", "javax.persistence.EntityManager"})
public class OverrideHibernatePersistenceProvider extends PersistenceProvider {
}

Now also add a persistence provider as described in the Google docs and disable DataNucleus checking for multiple PersistenceContextFactory instantiations with this property in appengine-web.xml.
<property name="appengine.orm.disable.duplicate.emf.exception" value="true"/>


As before, also Seam needs a couple of patches. Main reasons for those are references to javax.naming.NamingException (which is not white listed, credits to Toby for the hint) and session/conversation components not implementing Serializable correctly. The last point is probably something not hitting Seam or your application the last time.

Identity

As a next step I tried to add some users to the application. Seam's Identity module builds around the javax.security.auth.Subject and Principal classes. Even though those classes are white listed, the SecurityManager blocks any attempt to add a Principal to a Subject. Well, how useful is that... As a quick fallback I integrated the Google Accounts API:
@Name("org.jboss.seam.security.identity")
@Scope(SESSION)
@Install(precedence = Install.APPLICATION)
@BypassInterceptors
@Startup
public class AppEngineIdentity extends Identity {

private static final long serialVersionUID = -9111123179634646677L;

public static final String ROLE_USER = "user";
public static final String ROLE_ADMIN = "admin";

private transient UserService userService;

@Create
@Override
public void create() {
userService = UserServiceFactory.getUserService();
}

@Override
public boolean isLoggedIn() {
return getUserService().isUserLoggedIn();
}

@Override
public Principal getPrincipal() {
if (isLoggedIn())
return new SimplePrincipal(getUserService().getCurrentUser().getNickname());
return null;
}

@Override
public void checkRole(String role) {
if (!isLoggedIn())
throw new NotLoggedInException();
if ((ROLE_ADMIN.equals(role) && !getUserService().isUserAdmin()) || !ROLE_USER.equals(role))
throw new AuthorizationException(String.format(
"Authorization check failed for role [%s]", role));
}

@Override
public boolean hasRole(String role) {
if (!isLoggedIn())
return false;
return ((ROLE_ADMIN.equals(role) && getUserService().isUserAdmin()) || ROLE_USER.equals(role));
}

@Override
public String getUsername() {
if (isLoggedIn())
return getUserService().getCurrentUser().getNickname();
return null;
}

public String createLoginURL(String destination) {
return getUserService().createLoginURL(destination);
}

public String createLogoutURL(String destination) {
return getUserService().createLogoutURL(destination);
}

public User getUser() {
if (isLoggedIn())
return getUserService().getCurrentUser();
return null;
}

private UserService getUserService() {
if (userService == null)
userService = UserServiceFactory.getUserService();
return userService;
}

}

Both create... methods can be used in the UI for generating login/logout URLs. Destination defines the URL the user gets redirected after successful login/logout. Also make sure that the identity configuration is removed from components.xml

Wrap up

Running this setup should give you a base for a very simple Seam app like in the screenshot below.



This first step has not been doing any persistence work, and my first tries with DataNucleus were not as straight forward as I had expected from a JPA implementation. Hope Google will catch up here with something more mature. Also, even the simple setup required a couple of nasty tweaks on the frameworks. Another big hurdle here are the runtime differences from production to local environment. For some serious work on App Engine, it's so far more recommendable to look into GWT.

Anyway, if you found this useful - looking forward to hear from your next steps in the cloud.

Friday, March 20, 2009

JBoss Seam Hot Deploy with Maven - Update

I just published an updated version of the Seam Hotdeploy Maven Plugin (see my previous post here). For a detailed description on how to use it, have a look at the Google Code Wiki. I also updated the sample Maven POM featuring JBoss Seam 2.1.1.GA.

The new version should be easier to configure and play nicer with e.g. the Eclipse Maven plugin (I'm not using NetBeans/IntelliJ too often, but I hope this works also fine there). The new Eclipse builder configuration looks like shown in the image below:



Note: The Eclipse Maven plugin using its embedded Maven had somehow problems with the extended lifecycle of the Hotdeploy Plugin. Using an external Maven installation (2.0.10) felt not only faster but was also not having problems with it.

Saturday, December 6, 2008

Using JBoss Seam Hot Deployment with a Maven Build

[UPDATE: The new plugin version is documented here]

As you might have read in previous posts, one of our favorite web application stacks consists of JBoss Seam. While combining this with our favorite tooling suite consisting of Eclipse and Maven, we had to realize that Seam has a much longer tradition with Ant, and Maven support is only slowly moving in. Today I want to share some ideas on how to tackle the combination issues.


While JBoss Tools provides a nice code hot deployment feature when working with Seam on JBoss, things can get a little hairy when using a Maven build with the project. Seam uses a special classloader and relies on monitoring the WEB-INF/dev folder for changed classes - where Maven is completely unaware of this and uses the standard WEB-INF/classes folder to deploy all classes in the project. More than once I've seen the situation where JBoss Tools and Maven got in each others way, ending with JBoss rejecting to restart the application due to "duplicate components". The reason was that Eclipse hot deployed classes to WEB-INF/dev where Seam expects them, but Maven being completely unaware of it packaging all classes in the common WEB-INF/classes folder.

In order to avoid trouble and also to allow using hot deployment from a command line build, I experimented with several approaches to achieve hot deployment with Maven. The main challenges here are:
  • Distinguishing compiler output: The Maven compiler plugin by default compiles everything in the same output folder. We need to be able to distinguish between hot and regular deployable code.
  • Publish updated resources to JBoss, including domain model classes, seam components as well as XHTML pages.
  • Make sure Seam unit tests still compile.
The solution I came up with was to write a new Maven plugin which extends the Maven compiler plugin with a new hotdeploy:compile goal and the following functionalities (source code as well as a simple Maven 2 repository is available in our Google Code account):
  • Hook into the compile phase and compile the source code to a dedicated directory. The source code location is configurable as well as the output directory.
  • Remove outdated hot deployable class files from the JBoss deployment. This is necessary for the Seam classloader to pick up the changes, only updating the file is not enough.
The plugin configuration is straight forward as it's based on the regular compiler plugin and is shown in the XML snippet below. Note that it is recommended to create a profile for this build setup as both your continuous build as well as your operations team might not care too much about using hot deployment.
<plugin>
<groupId>com.ctp.seam.maven</groupId>
<artifactId>maven-hotdeploy-plugin</artifactId>
<version>0.1.0</version>
<configuration>
<source>${java.source.version}</source>
<target>${java.source.version}</target>
<hotdeployOutputDirectory>${directory.hotdeployables}</hotdeployOutputDirectory>
<includes>
<include>**/session/**</include>
</includes>
<deployDirectory>
${directory.deploy.jboss}/${build.finalName}.${project.packaging}
</deployDirectory>
</configuration>
<executions>
<execution>
<phase>compile</phase>
<goals>
<goal>compile</goal>
</goals>
</execution>
</executions>
</plugin>

The main additions to a regular compiler plugin setup are:
  • This variant uses the common /src/main/java source folder and uses in- and excludes to distinguish the hot deployable sources. Alternatively you can set the sourceDirectory configuration value pointing to a dedicated source folder (similar as JBoss Tools does the setup for you). Don't forget that this requires then the Build Helper Maven plugin to add source folders to your regular build.
  • The deployDirectory is a reference to your exploded application directory inside the JBoss deploy folder. This is needed in order to remove outdated hot deployable classes.
  • You can specify the hotdeployOutputDirectory directory where the code should be compiled to. Note that this defaults to the value shown in the example - feel free to skip this part. The plugin will compile into this folder after appending a WEB-INF/dev to the path.
The rest of the setup we can do by simply reconfiguring existing plugins. Note the Google Code Wiki contains a complete sample POM ready for you to start your own Seam webapp. The details on the configuration are:
  • Reconfiguring the WAR plugin so the webappDirectory points inside our JBoss deploy folder. Maven uses this folder to assemble the WAR file, which perfectly corresponds to an exploded deployment. Additionally we define our hot deployment compilation folder as a webResource, which will copy our compilation exactly to the WEB-INF/dev folder in the exploded deployment.

<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<configuration>
<webResources>
<resource>
<directory>${directory.hotdeployables}</directory>
<filtering>false</filtering>
</resource>
</webResources>
<webappDirectory>
${directory.deploy.jboss}/${build.finalName}.${project.packaging}
</webappDirectory>
</configuration>
</plugin>

  • Similarly, we have to add our output folder to the test classpath. This is simplest done by adding it as a resource folder, which will copy the classes to the target/test-classes directory before the test classes are compiled:
<testResources>
<testResource>
<directory>${directory.hotdeployables}/WEB-INF/dev</directory>
<filtering>false</filtering>
</testResource>
...
</testResources>

If you want to run a similar luxury setup as you get from JBoss Tools, you can add a Maven builder to your project. Simply go to the Eclipse Project properties and click "New" on the "Builders" properties. The new Maven build should look like the following:



Make sure that the following conditions apply to your Eclipse setup:
  • The JRE you have configured is actually a JDK - otherwise the builder will fail. Once you see that the builder does not fail, you can also switch off the console allocation in the "Common" tab.

  • Also take care that you always build with your specific hot deploy profile - otherwise make sure to clean before using the build again.

  • Assert that Eclipse uses a dedicated output folder and not the Maven target/classes.

Unfortunately when activating the builder Eclipse might prompt you when editing files and (depending on the speed of your machine) hang for a second or two after saving a file. Still, this is much better than waiting a minute for your JBoss server to restart.

Happy coding!

Friday, October 24, 2008

Giving EJB 3.1 a Test Drive

Although not yet final, project GlassFish features already an alpha implementation of EJB 3.1. TheServerSide posted a nice series of articles on what you can expect to come - but honestly, wouldn't it be much more fun to actually get some hands dirty? Here's a quick description on how you can give it a spin. We will demonstrate the following new features:
  • Singleton Beans
  • Simplified EJB packaging
  • Simplified EJB without Interfaces
  • Unified JNDI naming
Start with downloading the latest release of GlassFish v3. The Windows installer guides you through the installation. Use the default settings except for the authentification - choose a username and a password (this used to default to "admin/adminadmin"). At the end you will be prompted by the Updatetool - start it and install the Add-Ons shown in the image below:


Beside the EJB Container we'll also install the new JAX-RS REST API to access the EJB. The JAX-RS JSR has just recently gone final, and is definitely also worth a look. Once the installation is done, we'll switch to the IDE to code our beans. I'm using Eclipse with the Maven 2 plugin to get started quickly.

Choose New Maven Project and select the maven-archetype-webapp archetype as shown in the screenshot below. We're naming our project "ejbtestdrive" - note the name as it will be used a couple of times in the further process. Finish the create wizard and add the src/main/java folder as a source folder in Eclipse after creating it.


To resolve our dependencies, lets first configure the Maven repositories to download the EJB 3.1 as well as the JAX-RS API. Add the following lines to your pom.xml:
<repositories>
<repository>
<id>glassfish</id>
<name>Glassfish Repository</name>
<url>http://download.java.net/maven/glassfish</url>
</repository>
<repository>
<id>java.net</id>
<name>java.net Repository</name>
<url>http://download.java.net/maven/2</url>
</repository>
</repositories>

Which allows us to download following dependencies:
<dependencies>
<dependency>
<groupId>javax.ejb</groupId>
<artifactId>ejb-api-3.1-alpha</artifactId>
<version>10.0-SNAPSHOT</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>com.sun.jersey</groupId>
<artifactId>jersey-server</artifactId>
<version>1.0</version>
<scope>provided</scope>
</dependency>
</dependencies>

Almost done with the Maven setup. We'll just add the GlassFish Maven plugin to our build and set the compiler to deal with Java 6 (Java 5 should be fine too):
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>1.6</source>
<target>1.6</target>
</configuration>
</plugin>
<plugin>
<groupId>org.glassfish.maven.plugin</groupId>
<artifactId>maven-glassfish-plugin</artifactId>
<version>2.1</version>
<configuration>
<glassfishDirectory>${glassfish.home}</glassfishDirectory>
<domain>
<name>domain1</name>
<adminPort>4848</adminPort>
</domain>
<user>${domain.username}</user>
<adminPassword>${domain.password}</adminPassword>
<components>
<component>
<name>${project.artifactId}</name>
<artifact>${project.build.directory}/${project.build.finalName}.${project.packaging}</artifact>
</component>
</components>
<autoCreate>true</autoCreate>
<debug>true</debug>
<echo>true</echo>
</configuration>
</plugin>
</plugins>
</build>

The referenced properties should be defined in a Maven profile, but for simplicity we'll just add them now to our POM (just replace the values with your installation location and your username/password):
<properties>
<glassfish.home>E:\work\servers\glassfish\glassfishv3-prelude\glassfish</glassfish.home>
<domain.username>admin</domain.username>
<domain.password>adminadmin</domain.password>
</properties>

You're now ready to run the WAR file on GlassFish. Just run
mvn package glassfish:deploy

to start GlassFish and get your WAR file deployed (Note: If the Maven plugin complains about asadmin not be a Win32 application, just remove the UNIX script so the .bat will be taken).

Finally, time to write some code! Go back to Eclipse and create a package. Our EJB is going to be a (surprise surprise) HelloWorld bean. Create a new class which looks like the following:
package com.ctp.ejb;

import java.util.LinkedHashSet;
import java.util.Set;

import javax.ejb.Singleton;

/**
* The friendly first EJB 3.1 bean.
* @author [you!]
*/
@Singleton
public class HelloWorldBean {

private Set<String> names = new LinkedHashSet<String>();

public String hello(String name) {
names.add(name);
return "Hello " + names;
}
}
In case Eclipse complains about the compiler compliance, just set the Java project facet in the project's properties to something > 1.4. You've now created one of the new Singleton EJBs. The bean is going to remember everybody who said "hello" and give back a friendly greeting. Note that there is no local or remote interface at all! Also using a global state in a bean is something nasty to achieve before EJB 3.1. Run
mvn package glassfish:redeploy

to deploy your bean - noteably in just a simple WAR file! Did you notice how fast this deploys?

Now it's time to access our bean over JAX-RS. Create another class which looks like this:
package com.ctp.ejb;

import javax.naming.InitialContext;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;

/**
* A RESTful bean being hopefully quite busy!
* @author [you!]
*/
@Path("/hello/{username}")
public class HelloWorld {

@GET
@Produces("text/plain")
public String hello(@PathParam("username") String name) throws Exception {
HelloWorldBean hello = (HelloWorldBean)
new InitialContext().lookup("java:global/ejbtestdrive/HelloWorldBean");
return hello.hello(name);
}
}

Simple enough, right? This is taking requests under /hello/... with a username, looking up the bean in JNDI and call it's hello method. Did you notice the format of the JNDI lookup? Yes, this is finally standardized, making your applications much more portable! In case you named your application differently, make sure the names match between global/ and /HelloWorldBean.
Further details on the JAX-RS functionalities can be found here.

As a last step, we need to add the Jersey servlet to our web.xml. Modify it to match this snippet:
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://java.sun.com/xml/ns/javaee"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
version="2.5">
<display-name>embeddable</display-name>
<servlet>
<servlet-name>Jersey Web Application</servlet-name>
<servlet-class>com.sun.jersey.spi.container.servlet.ServletContainer</servlet-class>
<init-param>
<param-name>com.sun.jersey.config.property.packages</param-name>
<param-value>com.ctp</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>Jersey Web Application</servlet-name>
<url-pattern>/*</url-pattern>
</servlet-mapping>
</web-app>

Check that your package name matches in the Servlets init param. Now package and redeploy - and we're ready to go! Just go to http://localhost:8080/ejbtestdrive/hello/[your name] to see you greeted by your new EJB! Experiment with different names and browser sessions and see the global state preserved.

Hope you enjoyed this little test drive. Let us know on how you're using EJB 3.1 and what your experience is with it!

Wednesday, September 24, 2008

Top 10 Java Technologies Update: JCR Part 2

As promised in the Top 10 Technologies post, here are more details regarding JCR and the way we use it in projects.

In the other post, I have written about the requirements we usually encounter in projects when it comes to dealing with content in web applications. Not only functional requirements but also non-functional requirements such as "content is stored at different places and must be made available at a single point" were most probably the reasons for Day Software (located in Switzerland) to bring that extra layer to life and started leading the JSR-170.
Instead of rebuilding all that from scratch, Cambridge Technology Partners has chosen many times to propose and implement a JSR-170 based solution.

Being in contact with Day directly, we carefully track the evolution of JCR, currently mainly in the JSR-283 area where the JCR 2.0 standard is about to reach its final state (currently in Public Review Ballot phase).

Since JSR-170 started, it is a hot topic in different places:
a) at conferences like JavaOne in 2006,
b) on the feature lists of product vendors (JSR-170 compliance),
c) used internally in open source products like Drools BRMS for managing business rules, Apache Sling for universal resource storage and Mule Galaxy for SOA governance management and last but not least
d) CTP had many projects in the Enterprise Content Management area where we used JSR-170 bridges (e.g. "SPI to JSR-170 bridge" in the BEA WebLogic Portal where SPI is the BEA custom content interface to their Virtual Content Repository in the portal), we used JCR products directly in projects (mostly Alfresco but also Jackrabbit which is the reference implementation both being good enough for small companies, Vamosa as content migration tool where customers wanted to automate content migration from a legacy content repository to a JCR (and yes, vice-versa also :-). To make the list complete, on projects we never had the chance to use Day's Content Repository Extreme (CRX), eXo JCR (part of the eXo platform), Mirage or Jeceira (part of the Jackrabbit alternative Magnolia).

As said earlier, the official successor JSR-283 is on its way and addresses enhancements in the areas of federation, remoting, client/server protocol mappings and extensions to content modeling capabilities just to name a few. I'm sure we'll compile an extra post on this topic... so check back later.

Friday, September 19, 2008

Top 10 Java Technologies at Cambridge Technology Partners

In the second part of our "Top 10" series, we dive into the actual technologies we use in our projects.
  • Enterprise JavaBeans (EJB) 3:
    Already declared as dead, Java EE has managed to jump back on the train with EJB 3. It incorporates many best practices like convention over configuration, dependency injection and usage of annotations, simplifying development a lot compared to its predecessor.

    Although the spec for EE 5 has been out for quite a while, adoption at our customers has taken a while - but now starts getting momentum. I've seen some very nice "Aha!" moments while demonstrating what the new platform has to offer to developers. The combination of POJOs, annotations and Java standard makes setting up projects and unit tests very easy and a powerful mix for development.

    EJB 3.1 looks also promising in terms of further simplifications (and fixing some holes left in the APIs) - we're looking forward to help our customers taking this turn as well!

  • Java Persistence API (JPA) and Hibernate:
    As a de facto standard for object persistence, Hibernate has been used in our projects for years now. While working with other persistence technologies like Beehive DB Controls, iBatis or even Entity Beans due to legacy code, Hibernate has proven most efficient once the domain model got a little complexer.

    With the new Java Persistence API coming in Java EE 5, Hibernate gets even easier to integrate and use into an enterprise application. We're still missing some Hibernate features like a criteria API in JPA, but JPA 2.0 is about to fix this. Besides easier integration, JPA makes applications also more portable - there are also a couple of other JPA implementations available: Oracle TopLink, openJPA (or its big brother Kodo) or Apache Cayenne to name the best known. Being part of the EE standard, it's not a surprise that integrating JPA with EJB (or vice versa) works great!

    Mentioning JPA 2.0, let's see how EclipseLink (nominated as reference implementation) compares to Hibernate!

  • JavaServer Faces (JSF):
    MVC frameworks seem to be around like sand on the sea. From old school Struts over Wicket to Google GWT (or other fancy new AJAX frameworks) - it's hard to decide for "the right one" on projects. My recommendation usually goes to using JSF (with Facelets). Investing in a standard is in general a good thing.

    In case of JSF:
    - It has proven to be extensibe. There are a couple of very nice AJAX component libraries around, like JBoss RichFaces, Woodstock or ICEfaces. And also, JBoss Seam adds a few killer features to JSF, just to name stateful navigation or transactional backing components here.
    - It is programmable with a declarative view definition in XHTML and an expression language. Facelets adds an extremely powerful templating to JSF, which I found much easier to use than frameworks like Tiles or SiteMesh.
    - Growing IDE support (Eclipse WTP, JBoss Tools, NetBeans and the latest IntelliJ to name some) featuring WYSIWYG editors or (for me much more useful) XHTML and EL code completion.

    By the way, Java EE 6 features JSF 2.0, including enhancements for component developers as well as standardazing on Facelets!

  • JBoss Seam:
    In my humble opinion, one of the most innovative frameworks over the last years. As already mentioned in a previous post, the stack around Seam works for me extremely well and efficient to develop web applications.

    Getting back on my previous statement on investing in standards - I'm looking forward to WebBeans (I hope JSR-299 makes it into Java EE 6), combining Seam with typesafe dependency injection of Google Guice! Looking back at my first servlet based web application during CS studies, things have become amazingly elegant to develop!

  • Spring Framework:
    Both EJB 3 and Spring in the same list? Yes, Spring is also a great piece of technology in use at many of our customers. It has not been the first open source dependency injection container (just to mention e.g. Pico) but was the first "enterprise ready" implementation out there making me extremely happy to work with after sweating on an EJB 2 project.

    Third party products (e.g. CRMs) which do not support Java EE 5 application server versions are sometimes limiting constraints for upgrading, which make usage of Spring a great alternative to customers which are still bound to EJB 2. Even if you don't deploy a Spring runtime, it offers great support for your unit tests - like using SimpleNamingContextBuilder to mock an InitialContext!

    The latest 2.5 release of Spring makes also (finally) use of annotations to inject bean dependencies, which is a great improvement over the previous "XML salad". Adam Bien has written a nice post on XML vs. annotations in EJB 3, which covers with my experiences and can be similarly handled in Spring.

  • JAX-WS:
    While we've gone through a couple of web service technology stacks, the JAX-WS standard has been for us the most convincing on to work with (did I already mention we generally like standards? ;-). Its reference implementation Metro has made its way into major application servers like Oracle WebLogic, JBoss, GlassFish (and probably others), allowing us to easily take best practices from customer to customer.

    If you're rather out for something simpler than a full SOAP stack, also have a look at JAX-RS, the standard for RESTful web services. Its reference implementation Jersey is on its way to version 1.0, but already now ready for some really cool use cases (try it out with e.g. JFreeChart to create dynamic charts in web applications)!


  • TestNG:
    While writing unit tests for years with JUnit, I've made the experience that some limitations of the framework have somehow led to ugly test code - clunky test method signatures with no arguments, no mechanism to define dependencies between tests and no built-in mechanism to run test methods with different test data.

    In a real world enterprise project, testing just the "unit" is not always enough. With Spring for example, we can run the whole container and execute test cases on it - this is definitely much faster than deploying to the container. TestNG has shown to be more useful than JUnit in this context. Also several large open source projects have decided for TestNG, to name JBoss (by the way: congrats for passing the EE 5 TCK!) or GlassFish.

  • jBPM and Drools:
    Probably not the most advanced BPM on the market, but at least in the open source space jBPM is the leading engine we've been working with so far. Now part of JBoss middleware suite, jBPM together with the Drools rule engine form a powerful couple when shaping SOA applications. But also running without jBPM, Drools has shown to be a great engine to externalise business rules in a very clean and maintainable way (which would otherwise probably have ended up in some ugly if-else jungle or rather complex decorator pattern classes).

  • Java Content Repository (JCR):
    It is extremely common for applications to store various pieces of information, most of the time in relational databases. While they do a great job when working with regular data types (e.g. int, string), we think they are not very efficient when dealing with binary data (unstructured), for example images or documents (structure binaries). On top of that, many features are not covered by pure DB products out of the box:
    Usually, such requirements we encounter on projects are proper management of documents, versioning, enhanced meta data tagging, handling of structured as well as unstructured content, proper handling of dependencies between content nodes (known as referencial integrity), flexibility with regards to node attribute extensions and inheritance, administration delegation, and many more.

    In such cases where an extra layer is needed on top of a database, JCR and JSR-170 quickly come into the picture of our solution proposals for our customers.

    More details will follow in a few days regarding JCR at CTP.

  • Scala:
    Honestly, we haven't had Scala in a customer project yet. Still it seems to be the most interesting newcomer in the "scripting on the JVM" category, offering static typing and a couple of interesting language constructs (to build e.g. DSLs). Unfortunately the learning curve is a little steeper than with other scripting languages, so a deeper analysis on where we can leverage this at our customers will have to wait until my next "beach time".