Tuesday, August 22, 2006

Great Grails Step-by-Step Tutorial



Some weeks ago I bumped against Grails. Grails is an open source web application framework inspired by Ruby on Rails. With Grails you can easily and quickly build/generate a web application using Groovy and (any) Java Technology.

In the near future I will post some of my Grails experiences here. But today I found a great Grails tutorial, written by Jason Rudolph, I really wanted to refer to: Grails + EJB Domain Models Step-by-Step.

Friday, June 2, 2006

EJBQL query support added in JasperReports



My patch to support EJBQL queries inside JasperReports templates is included in the latest JasperReports 1.2.3 release. You can use any Java Persistence API implementation (part of JSR-220) like GlassFish/Toplink Essentials or Hibernate Entity Manager to provide data to your reports.

An example of using EJBQL in JasperReports templates is provided in the JasperReports project distribution, located in \demo\samples\ejbql. The example uses the Toplink Essentials Java Persistence API implementation from GlassFish. All necessary libraries to run the example are included in the JasperReports project distribution.

Running the example
Open a Command box and and navigate to JR_HOME\demo\samples\ejbql. Then run ant javac to compile the Java sources, ant compile to compile the JasperReports template files, ant fill to fill the compiled report design with data, and ant view to launch the report viewer to preview the report.

C:\Java Libs>cd jasperreports-1.2.3\demo\samples\ejbql

C:\Java Libs\jasperreports-1.2.3\demo\samples\ejbql>ant javacBuildfile:

build.xml

javac:

[mkdir] Created dir: C:\Java Libs\jasperreports-1.2.3\demo\samples\ejbql\build\classes

[javac] Compiling 5 source files to C:\Java Libs\jasperreports-1.2.3\demo\samples\ejbql\build\classes

[javac] Note: C:\Java Libs\jasperreports-1.2.3\demo\samples\ejbql\EjbqlApp.java uses unchecked or unsafe operations.

[javac] Note: Recompile with -Xlint:unchecked for details.

[copy] Copying 1 file to C:\Java Libs\jasperreports-1.2.3\demo\samples\ejbql\build\classes

[copy] Copying 1 file to C:\Java Libs\jasperreports-1.2.3\demo\samples\ejbql\build

BUILD SUCCESSFUL

Total time: 2 seconds

C:\Java Libs\jasperreports-1.2.3\demo\samples\ejbql>ant compileBuildfile:

build.xml

compile:

[jrc] Compiling 3 report design files.

[jrc] File : C:\Java Libs\jasperreports-1.2.3\demo\samples\ejbql\JRMDbVariaSubreport.jrxml ... OK.

[jrc] File : C:\Java Libs\jasperreports-1.2.3\demo\samples\ejbql\JRMDbCastSubreport.jrxml ... OK.

[jrc] File : C:\Java Libs\jasperreports-1.2.3\demo\samples\ejbql\JRMDbReport.jrxml ... OK.

BUILD SUCCESSFUL

Total time: 3 seconds

C:\Java Libs\jasperreports-1.2.3\demo\samples\ejbql>ant fillBuildfile:

build.xml

fill:

[java] [TopLink Info]: 2006.06.02 08:55:20.906--ServerSession(30533424)--TopLink, version: Oracle TopLink Essentials - 2006.4 (Build 060412)

[java] [TopLink Info]: 2006.06.02 08:55:21.281--ServerSession(30533424)--file:/C:/Java%20Libs/jasperreports-1.2.3/demo/samples/ejbql/build/classes-pu1 login successful

[java] Filling time : 2125

[java] [TopLink Info]: 2006.06.02 08:55:23.015--ServerSession(30533424)--file:/C:/Java%20Libs/jasperreports-1.2.3/demo/samples/ejbql/build/classes-pu1 logout successful

BUILD SUCCESSFUL

Total time: 4 seconds

C:\Java Libs\jasperreports-1.2.3\demo\samples\ejbql>ant viewBuildfile:

build.xml

view:

BUILD SUCCESSFULTotal time: 4 seconds


Understanding the code
The ant fill target does the filling of the report by quering the HSQDB using the Java Persistence API. In the JRMDbReport.jrxml report template the following queryString was defined:

<queryString language="ejbql">

<![CDATA[

SELECT m

FROM Movie m

WHERE m.releaseDate BETWEEN $P{DateFrom} AND $P{DateTo}

ORDER BY $P!{OrderClause}]]>

</queryString>



By setting the language="ejbql" attribute, the JasperReports engine will use the Java Persistence API to retrieve the data. When filling the report an EnitiyManager instance need to be provided to the JasperReports engine. This is done in the main \demo\samples\ejbql\EjbqlApp.java class:



EntityManagerFactory emf = Persistence.createEntityManagerFactory("pu1", new HashMap());

EntityManager em = emf.createEntityManager();

Map parameters = new HashMap();

parameters.put(JRJpaQueryExecuterFactory.PARAMETER_JPA_ENTITY_MANAGER, em);

JasperFillManager.fillReportToFile(fileName, parameters);



Note that this is only the part of the code to provide the EntityManager. Take a look at the \demo\samples\ejbql\EjbqlApp.java class for the complete code of the example.

The actual connection information to connect to the database is stored in the \demo\samples\ejbql\META-INF\persistence.xml:



<persistence xmlns="http://java.sun.com/xml/ns/persistence" version="1.0">

<persistence-unit name="pu1">

<!-- Provider class name is required in Java SE -->

<provider>oracle.toplink.essentials.ejb.cmp3.EntityManagerFactoryProvider</provider>

<!-- All persistence classes must be listed -->

<class>Person</class>

<class>Movie</class>

<class>Cast</class>

<class>Varia</class>

<properties>

<!-- Provider-specific connection properties -->

<property name="toplink.jdbc.driver" value="org.hsqldb.jdbcDriver"/>

<property name="toplink.jdbc.url" value="jdbc:hsqldb:db"/>

<property name="toplink.jdbc.user" value="sa"/>

<property name="toplink.jdbc.password" value=""/>

<!-- Provider-specific settings -->

<property name="toplink.logging.level" value="DEBUG"/>

<property name="toplink.platform.class.name" value="oracle.toplink.essentials.platform.database.HSQLPlatform"/>

</properties> </persistence-unit></persistence>


To read more about the EJBQL support in JasperReports, for example how to specify Query Hints, take a look at the JasperReports API documentation of the JRJpaQueryExecuter class.

Thursday, May 25, 2006

Using Facelets in NetBeans 5.5 (beta)



Although NetBeans 5.5 beta has no direct support for Facelets (yet?), you can successfully develop JSF Facelets applications with it, and take advantage of NetBeans' Java EE 5 platform support and other cool things.

In this this tutorial I will create a new Web Application in NetBeans 5.5 beta, based on the NumberGuess example included in the Facelets distribution. This tutorial assumes that you have basic JSF, Facelets and NetBeans knowledge. Before starting make sure you have the following in place:


The NumberGuess example is a simple application consisting of a couple of JSF pages and navigation rules and a single JSF managed bean. Follow the steps below to set up the NumberGuess project in NetBeans and deploy and run it from within the IDE.



  1. Register the Facelets library in NetBeans (Tools --> Library Manager). Create a New Library containing the jsf-facelets.jar from the Facelets distribution.

  2. Create a new Web Application project. Choose as Project Name numberguess (make sure the context path is also set to numberguess) and select the Java EE 5 server you installed as Server. Select Java Server Faces in the Frameworks step. Click Finish to create the project.

  3. NetBeans will automatically create an index.jsp and welcomeJSF.jsp. Delete both files as we will not be using JSP pages, but xhtml formatted JSF pages.

  4. Add the Facelets library to your project (Project Properties --> Libraries --> Add Library).

  5. Copy the tutorial directory (containing the managed bean class) from \facelets-1.1.4\demo\numberguess\src\ to your projects \src\java\ directory. NetBeans will refresh your project content automatically.

  6. Also copy all files from \facelets-1.1.4\demo\numberguess\web\ to your projects \web\ directory. Do NOT copy the \WEB-INF\ directory.

  7. Open your projects web.xml and add the folowing:
    <context-param>

    <param-name>javax.faces.DEFAULT_SUFFIX</param-name>

    <param-value>.xhtml</param-value>

    </context-param>

    Next, change the the Faces Servlet url pattern from /faces/* to *.jsf (next time you can do this when creating the project).

    Also completely remove the welcome file list configuration which was pointing to the deleted index.jsp file.

  8. Open your projects faces-config.xml and add the folowing:
    <application>

    <view-handler>

    com.sun.facelets.FaceletViewHandler

    </view-handler>

    </application>





    <!-- our NumberBean we created before -->

    <managed-bean>

    <managed-bean-name>NumberBean</managed-bean-name>

    <managed-bean-class>tutorial.NumberBean</managed-bean-class>

    <managed-bean-scope>session</managed-bean-scope>

    <managed-property>

    <property-name>min</property-name>

    <value>1</value>

    </managed-property>

    <managed-property>

    <property-name>max</property-name>

    <value>10</value>

    </managed-property>

    </managed-bean>

    <!-- going from guess.xhtml to response.xhtml -->

    <navigation-rule>

    <from-view-id>/guess.xhtml</from-view-id>

    <navigation-case>

    <from-outcome>success</from-outcome>

    <to-view-id>/response.xhtml</to-view-id>

    </navigation-case>

    </navigation-rule>

    <!-- going from response.xhtml to guess.xhtml -->

    <navigation-rule>

    <from-view-id>/response.xhtml</from-view-id>

    <navigation-case>

    <from-outcome>success</from-outcome>

    <to-view-id>/guess.xhtml</to-view-id>

    </navigation-case>

    </navigation-rule>



    The most important part is to configure the FaceletViewHandler to use Facelets as view technology. The other parts are just 'normal' JSF managed beans and navigation rules which you would also need without using Facelets.

  9. Deploy and Run your project.

Tuesday, April 18, 2006

Java Persistence API kickstart example



The new Java Persistence API (JSR 220) - the API for management of persistence and object/relational mapping - is comming your way! Finally persistence gets standardised. The Java Persistence API, or simply JPA, is required to be supported by any Java EE 5 implementation (as part of EJB 3.0), but can also be used in stand-alone Java SE.

I've set up a simple kickstart example which can be used as starting point to persist objects and run EJBQL queries. Start experimenting yourself today! You can add your own Java objects to the example and use them to persist or retrieve data.

To keep things simple we will use the stand-alone JPA implementation of GlassFish, Toplink Essentials, in Java SE (JDK 5 required) and as database we use an embedded HSQLDB database.


  1. Let's get started by downloading the GlassFish JPA implementation from: https://glassfish.dev.java.net/downloads/persistence/JavaPersistence.html (for this example I used build 44). You need to install/unpackage the downloaded jar as described on the download page: java -jar filename.jar. A directory will be created containing the needed jar files. Next, download HSQLDB from: http://www.hsqldb.org.

  2. Create a project environment (e.g. using Eclipse) and make sure toplink-essentials.jar, toplink-essentials-agent.jar and hsqldb.jar are on the classpath.

  3. Next, create your first entity class:
    import javax.persistence.Entity;import javax.persistence.Id;



    @Entity

    public class Cat {



    private String id;

    private String name;

    private char sex;

    private float weight;



    public Cat() {

    }



    public Cat(String id, String name, char sex, float weight) {

    this.id = id;

    this.name = name;

    this.sex = sex;

    this.weight = weight;

    }



    @Id

    public String getId() {

    return id;

    }



    public void setId(String id) {

    this.id = id;

    }



    public String getName() {

    return name;

    }



    public void setName(String name) {

    this.name = name;

    }



    public char getSex() {

    return sex;

    }



    public void setSex(char sex) {

    this.sex = sex;

    }



    public float getWeight() {

    return weight;

    }



    public void setWeight(float weight) {

    this.weight = weight;

    }

    }


  4. Create a META-INF directory on your classpath and add the file persistence.xml:
    <persistence xmlns="http://java.sun.com/xml/ns/persistence" version="1.0">

    <persistence-unit name="example">

    <!-- Provider class name is required in Java SE -->

    <provider>oracle.toplink.essentials.ejb.cmp3.EntityManagerFactoryProvider</provider>

    <!-- All persistence classes must be listed -->

    <class>Cat</class>

    <properties>

    <!-- Provider-specific connection properties -->

    <property name="toplink.jdbc.driver" value="org.hsqldb.jdbcDriver"/>

    <property name="toplink.jdbc.url" value="jdbc:hsqldb:mem:."/>

    <property name="toplink.jdbc.user" value="sa"/>

    <property name="toplink.jdbc.password" value=""/>

    <!-- Provider-specific settings -->

    <property name="toplink.ddl-generation" value="create-tables"/>

    <!-- other values are: drop-and-create-tablesnone -->

    <property name="toplink.logging.level" value="DEBUG"/>

    <property name="toplink.platform.class.name" value="oracle.toplink.essentials.platform.database.HSQLPlatform"/>

    </properties>

    </persistence-unit>

    </persistence>

    Because we are running HSQLDB in memory and have set ddl-generation to "create-tables" we don't have to install a database and even don't have to create the Cat table. Toplink Essentials will create the table automatically.

  5. Create a simple Example class in which we will use the Java Persistence API:
    import java.util.List;

    import javax.persistence.EntityManager;

    import javax.persistence.EntityManagerFactory;

    import javax.persistence.Persistence;



    public class Example {



    public static void main(String[] args) {



    EntityManagerFactory emf = Persistence.createEntityManagerFactory("example");

    EntityManager em = emf.createEntityManager();

    try {

    em.getTransaction().begin();



    Cat princess = new Cat("1", "Princess", 'F', 7.4f);

    Cat blackie = new Cat("2", "Blackie", 'M', 7.6f);



    em.persist(princess);

    em.persist(blackie);



    em.getTransaction().commit();



    List<Cat> cats = em.createQuery("SELECT c FROM Cat c").getResultList();

    for (Cat c : cats) {

    System.out.println(c.getName());

    }

    } catch(Exception ex) {

    em.getTransaction().rollback();

    } finally {

    em.close();

    }

    }

    }

    First we persist 2 Cat instances and later we retrieve them back againg using an EJBQL query.

  6. Now run the Example class. The result should be something like below. This means you are successfully using the Java Persistence API!
    [TopLink Info]: 2006.04.18 08:54:44.734--ServerSession(9800632)--TopLink, version: Oracle TopLink Essentials - 2006.4 (Build 060412)

    [TopLink Info]: 2006.04.18 08:54:45.093--ServerSession(9800632)--file:/C:/Projects/workspace/jpa_example-example login successful

    Princess

    Blackie


Next steps: create your own Java objects, list them in the persistence.xml and start expirementing with them by persisting them and retrieving them using EJBQL queries. Note that when you run the example new tables are created automatically for your new Java objects.

Saturday, April 8, 2006

Using other query languages in JasperReports



In version 1.2.0 of JasperReports - The most popular open source reporting engine in the world - support for other query languages, including HQL and XPath, is added.

This means you can use HQL directly in report templates! The report engine will create a HibernateSessionFactory which uses your Hibernate configuration and mappings to connect to the database, build the SQL statement and return the mapped Java objects. Example of HQL queryString in report template:

<queryString language="hql">
<![CDATA[
from Cat cat
where cat.weight > ($P{CatWeight})]]>
</queryString>

Notice the language="hql" which indicates the report engine to use HQL instead of plain JDBC SQL. JasperReports introduced the JRQueryExecuterFactory and JRQueryExecuter interfaces to incorporate new/additional query languages easily by - just - implementing them. Currently there are query language implementations for JDBC, Hibernate and Xpath.

As the Java Persistence API, part of EJB 3.0/JEE 5.0, is becoming the standard I decided to create a patch to add support for JPA/EJBQL in JasperReports. The code is already submitted to the JasperReports team and I hope it will be included soon in a future release.

When released I will add a step-by-step example on using EJBQL queries in report templates.

Thursday, April 6, 2006



I've just successfully deployed the demo webapp of JasperReports - The most popular open source reporting engine in the world - on the latest GlassFish build (b42).

  1. Download the latest GlassFish build from https://glassfish.dev.java.net/public/downloadsindex.html.
  2. See the Instructions to unbundle and configure GlassFish and the GlassFish Quick Start Guide to get GlassFish up and running.
  3. Make sure GlassFish is running by checking http://localhost:8080.
  4. Download JasperReports (jasperreports-1.2.0-project.zip) from http://sourceforge.net/project/showfiles.php?group_id=36382&package_id=28579.
  5. Unzip the downloaded JasperReports archive.
  6. Navigate to the the JasperReports demo webapp source directory.
    cd jasperreports-1.2.0\demo\samples\webapp
  7. Run the ant command and specify the war target.
    ant war
    When the build is finished the jasper-webapp.war should be in the \webapp directory.
  8. Copy jasper-webapp.war to GlassFish install-dir/domains/domain1/autodeploy. The JasperReports demo webapp will be deployed automatically.
  9. Goto the JasperReports demo webapp running on http://localhost:8080/jasper-webapp/. If you get a 404 wait a couple of seconds and refresh; probably the application was not yet deployed. Eventually you should see the JasperReports Web Application Sample.
  10. In the leftside menu click the compile link and compile the report template either using the JSP or Servlet Example.
  11. Now the report template is compiled you can execute the report itself with the PDF and HTML output links in the leftside menu. Both PDF and HTML output should work!

In a next entry I will explain how to use Java Persistence API EJBQL queries directly in report templates. This by using the new JasperReports 1.2.0 extendible JRQueryExectureFactory feature.

Wednesday, April 5, 2006

Welcome to my new weblog

Welcome to my brand new weblog about Java, open source and other interesting things.