RSS Entries RSS
RSS Subscribe by Email

Archive for Java

Hibernate with JPA Annotations and Guice

In this tutorial, I use the H2 database, which you can utilize by downloading the jar or you can replace with your own DB.

First off, you need to create a persistence.xml in a folder named META-INF at the root of your classpath. For example, if you’re using Maven you can create src/main/java/META-INF/persistence.xml. It lists all the classes you want Hibernate to persist and any other Hibernate properties you might want to specify. I also define Hibernate properties later on in the tutorial when creating the EntityManagerFactory.

<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">
  <persistence-unit name="db-manager">
    <class>com.benmccann.db.ExamplePersistedClass</class>
    <properties>
      <!-- Disable the second-level cache  -->
      <property name="hibernate.cache.provider_class" value="org.hibernate.cache.NoCacheProvider"/>

      <!-- Default is false for backwards compatibility.  Should be used on all new projects -->
      <property name="hibernate.id.new_generator_mappings" value="true"/>
    </properties>
  </persistence-unit>
</persistence>

We listed the class com.benmccann.db.ExamplePersistedClass as being the only persisted class, so now we’ll go ahead and create it. Note that you need a no-argument constructor. Fields in your bean will be persisted unless annotated with @Transient. More info about persisted classes is available in the Hibernate documentation.

package com.benmccann.db;

import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;

@Entity
public class ExamplePersistedClass {

  @Id
  @GeneratedValue
  private Long id;

  private String otherField;

  public ExamplePersistedClass() {}

  public void setId(Long id) {
    this.id = id;
  }

  public Long getId() {
    return id;
  }

  public void setOtherField(String otherField) {
    this.otherField = otherField;
  }

  public String getOtherField() {
    return otherField;
  }

}

And we’ll create a DAO for it:

package com.benmccann.db;

import javax.persistence.EntityManager;

public class ExamplePersistedClassDao {

  protected EntityManager entityManager;

  @Inject
  public ExamplePersistedClassDao(EntityManager entityManager) {
    this.entityManager = entityManager;
  }

  public void saveInNewTransaction(ExamplePersistedClass object) {
    entityManager.getTransaction().begin();
    save(object);
    entityManager.getTransaction().commit();
  }

  public void save(ExamplePersistedClass object) {
    entityManager.persist(object);
  }

  public ExamplePersistedClass getByOtherField(String otherField) {
    return (ExamplePersistedClass) entityManager
        .createQuery("select e from ExamplePersistedClass e where e.otherField=:otherField")
        .setParameter("otherField", otherField)
        .getSingleResult();
  }

}

And finally, we’ll create a Guice module to define the injection. Note that EntityManagerFactory is thread-safe while EntityManager is not. I use ThreadLocal storage here in order to have one entity manager per thread. When creating the EntityManagerFactory notice that I use the same “db-manager” string that is defined in the persistence.xml file. Also, I defined most of my Hibernate properties here rather than in the persistence.xml file to demonstrate how you can alter the values of these properties. For example, when writing tests it could be very helpful to override the connection string to point to a local test database.

package com.benmccann.db;

import java.util.HashMap;
import java.util.Map;

import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.Persistence;

import com.google.inject.AbstractModule;
import com.google.inject.Provides;
import com.google.inject.Singleton;

/**
 * @author Ben McCann (benmccann.com)
 */
public class DbModule extends AbstractModule {

  private static final ThreadLocal ENTITY_MANAGER_CACHE
      = new ThreadLocal();

  public void configure() {
  }

  @Provides @Singleton
  public EntityManagerFactory provideEntityManagerFactory() {
    Map properties = new HashMap();
    properties.put("hibernate.connection.driver_class", "org.h2.Driver");
    properties.put("hibernate.connection.url", "jdbc:h2:test");
    properties.put("hibernate.connection.username", "sa");
    properties.put("hibernate.connection.password", "");
    properties.put("hibernate.connection.pool_size", "1");
    properties.put("hibernate.dialect", "org.hibernate.dialect.H2Dialect");
    properties.put("hibernate.hbm2ddl.auto", "create");
    return Persistence.createEntityManagerFactory("db-manager", properties);
  }

  @Provides
  public EntityManager provideEntityManager(EntityManagerFactory entityManagerFactory) {
    EntityManager entityManager = ENTITY_MANAGER_CACHE.get();
    if (entityManager == null) {
      ENTITY_MANAGER_CACHE.set(entityManager = entityManagerFactory.createEntityManager());
    }
    return entityManager;
  }

}

Now we can run our code:

package com.benmccann.db;

import java.sql.SQLException;
import java.util.Date;

import org.junit.Assert;
import org.junit.Test;

import com.google.inject.Guice;
import com.google.inject.Injector;
import com.benmccann.db.DbModule;
import com.benmccann.db.ExamplePersistedClass;
import com.benmccann.db.ExamplePersistedClassDao;

public class H2DBTest {

  @Test
  public void testDb() throws SQLException {
    Injector injector = Guice.createInjector(new DbModule());
    ExamplePersistedClassDao examplePersistedClassDao = injector.getInstance(ExamplePersistedClassDao.class);   

    ExamplePersistedClass example = new ExamplePersistedClass();
    example.setOtherField("hello world");
    examplePersistedClassDao .saveInNewTransaction(quote);

    ExamplePersistedClass retrieved = examplePersistedClassDao.getByOtherField("hello world");

    Assert.assertEquals(example.getId(), retrieved.getId());
    Assert.assertEquals(example.getOtherField(), retrieved.getOtherField());
  }

}

Comments

Using Struts 2 on Google App Engine

Google App Engine (GAE) has some great benefits such as scalability and the fact that it’s free to start.  When using Struts 2 with Google App Engine there a few things to keep in mind.

The first is that it runs inside a security sandbox that is more restrictive than your typical Java environment.  This means that OGNL, the expression language that Struts 2 uses, will not work correctly out of the box.  You can fix this by adding a listener as described in this article.  An example listener can be found here and is used in this web.xml file.

The second problem is that Google App Engine has some special URLs that it uses.  If you try to visit them, Struts 2 will attempt to process the request as if it’s a Struts 2 Action and will bomb out when the Action can’t be found.  You can add an exclusion filter to your struts.xml to counteract this problem:

<constant name="struts.action.excludePattern" value="/_ah/.*"/>



Comments

Case Study: Usable and Unusable APIs

It was the best of times, it was the worst of times…

It was the age of wisdom, it was the season of light.  A great library called dom4j was written with its users in mind.  It included a quick start guide and a cookbook for people that actually wanted to get things done.  Converting a document to a String took 15 characters: document.asXML().  But there were too many competing XML parsing implementations, so a standard was created.  And sadly, dom4j has not been updated to adhere to that standard.

It was the age of foolishness, it was the epoch of incredulity.  15 characters to turn a document into a string?  That is far too few.  What will we tell our managers when they ask how many lines of code we have written?  We have a better way and it is called Xerces:

import java.io.StringWriter;

import javax.xml.transform.Result;
import javax.xml.transform.Source;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerConfigurationException;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;

import org.w3c.dom.Node;

public final class XmlUtil {

  private static final TransformerFactory factory = TransformerFactory.newInstance();

  public static String toString(Node node) {
    if (node == null) {
      return null;
    }
    try {
      Source source = new DOMSource(node);
      StringWriter stringWriter = new StringWriter();
      Result result = new StreamResult(stringWriter);
      Transformer transformer = factory.newTransformer();
      transformer.transform(source, result);
      return stringWriter.getBuffer().toString();
    } catch (TransformerConfigurationException e) {
      e.printStackTrace();
    } catch (TransformerException e) {
      e.printStackTrace();
    }
    return null;
  }

}

Comments (6)

Sample log4j.properties file

I always find the hardest part of getting started with log4j is creating a log4j.properties file. For that reason, I’ve posted an example below. This file configures log4j to log any messages of level info or higher to the console except for classes under the com.dappit.Dapper.parser or org.w3c.tidy packages.

#------------------------------------------------------------------------------
#
#  The following properties set the logging levels and log appender.  The
#  log4j.rootCategory variable defines the default log level and one or more
#  appenders.  For the console, use 'S'.  For the daily rolling file, use 'R'.
#  For an HTML formatted log, use 'H'.
#
#  To override the default (rootCategory) log level, define a property of the
#  form (see below for available values):
#
#        log4j.logger. =
#
#    Available logger names:
#      TODO
#
#    Possible Log Levels:
#      FATAL, ERROR, WARN, INFO, DEBUG
#
#------------------------------------------------------------------------------
log4j.rootCategory=INFO, S

log4j.logger.com.dappit.Dapper.parser=ERROR
log4j.logger.org.w3c.tidy=FATAL

#------------------------------------------------------------------------------
#
#  The following properties configure the console (stdout) appender.
#  See http://logging.apache.org/log4j/docs/api/index.html for details.
#
#------------------------------------------------------------------------------
log4j.appender.S = org.apache.log4j.ConsoleAppender
log4j.appender.S.layout = org.apache.log4j.PatternLayout
log4j.appender.S.layout.ConversionPattern = %d{yyyy-MM-dd HH:mm:ss} %c{1} [%p] %m%n

#------------------------------------------------------------------------------
#
#  The following properties configure the Daily Rolling File appender.
#  See http://logging.apache.org/log4j/docs/api/index.html for details.
#
#------------------------------------------------------------------------------
log4j.appender.R = org.apache.log4j.DailyRollingFileAppender
log4j.appender.R.File = logs/bensApps.log
log4j.appender.R.Append = true
log4j.appender.R.DatePattern = '.'yyy-MM-dd
log4j.appender.R.layout = org.apache.log4j.PatternLayout
log4j.appender.R.layout.ConversionPattern = %d{yyyy-MM-dd HH:mm:ss} %c{1} [%p] %m%n

#------------------------------------------------------------------------------
#
#  The following properties configure the Rolling File appender in HTML.
#  See http://logging.apache.org/log4j/docs/api/index.html for details.
#
#------------------------------------------------------------------------------
log4j.appender.H = org.apache.log4j.RollingFileAppender
log4j.appender.H.File = logs/bensApps.html
log4j.appender.H.MaxFileSize = 100KB
log4j.appender.H.Append = false
log4j.appender.H.layout = org.apache.log4j.HTMLLayout

Comments (7)

Printing a Stack Trace anywhere in Java

You don’t need to catch an Exception in order to print a stack trace in Java.  Sometimes they can be helpful for debugging and logging purposes.  Here’s an example of how to print a stack trace at any moment:

new Exception().printStackTrace();

If you want more control over the output, you can build some code off the following:

  System.out.println("Printing stack trace:");
  StackTraceElement[] elements = Thread.currentThread().getStackTrace();
  for (int i = 1; i < elements.length; i++) {
    StackTraceElement s = elements[i];
    System.out.println("\tat " + s.getClassName() + "." + s.getMethodName()
        + "(" + s.getFileName() + ":" + s.getLineNumber() + ")");
  }

Comments (3)

Maven on Eclipse Tutorial

Install Java and Maven

First off, make sure you have a Java JDK installed and that your JAVA_HOME environment variable points to it. You can check by typing “echo %JAVA_HOME%” in Windows or “echo $JAVA_HOME” in Linux. You’ll next want to download and install Maven by following the directions on their website.  Once Maven is installed, you’ll want to create a settings.xml file in your .m2 directory, which is located at ~/.m2 in Linux or C:\Documents and Settings\%USER%\.m2 on Windows.  You can do this by copying the settings.xml file from the directory where Maven in installed to you .m2 directory.

Install m2eclipse

You’ll want to make sure your Eclipse installation is pointing at your JDK.  You can check by going to Window > Preferences > Java > Installed JREs.  You’ll also want to set the -vm flag in your eclipse.ini file which is located at the root of your Eclipse installation.  Here’s what my file looks like:

-showsplash
org.eclipse.platform
--launcher.XXMaxPermSize
256M
-framework
plugins\org.eclipse.osgi_3.4.0.v20080605-1900.jar
-vm
C:\Program Files\Java\jdk1.6.0_11\bin\javaw.exe
-vmargs
-Dosgi.requiredJavaVersion=1.5
-Xms40m
-Xmx512m

Finally, you get to install m2eclipse by opening up Eclipse and selecting Help > Software Updates… > Available Software > Add Site…  Then enter http://m2eclipse.sonatype.org/sites/m2e, check the newly added boxes, and press Install.

Create Your First Maven Project

Now for the fun.  You can create a Maven project in Eclipse by selecting New > Project… > Maven > Maven Project.  Check “Create a simple project” on the first screen and hit Next.  Enter the Group Id, Artifact Id, and Name.  For example, “com.benmccann.robot”, “window-robot”, “Window Robot”.  Now, at long last, you can do some actual programming.

Add Dependencies

It won’t be long before you’ll want to add dependancies.  Open the Maven Indexes View by selecting Window > Show View > Other… > Maven > Maven Indexes.  You’ll want to make sure you have the Maven Central Repository, so right-click the view and choose “Add Index”.  Enter http://repo1.maven.org/maven2/ for the Repository URL and hit Retrieve to fill in the Repository Id of central.  Now you can right-click the project and choose Maven > Add Dependancy.  We’ll add jUnit since you’ll probably want it anyway.  Type junit and you should see it populated into the box below.  Use the dropdown at the bottom to set a scope of “test” and hit OK.

Comments (3)

Using the GWT ClickListener on an Element

GWT uses what it calls a ClickListener instead of the standard HTML onclick attribute.  The normal way to use a GWT CLickListener would be as follows:

focusWidget.addClickListener(new ClickListener() {
  public void onClick(Widget sender) {
    // do something here
  }
});

Unfortunately, this seems not to work on an HTML Element.  Luckily, you can use JSNI to write some native JavaScript and get around the problem:

/**
 * Example of adding an onlick attribute to an element.
 */
public native void addClickListener(Element element) /*-{
  element.onclick = function() {
    // do something here
    return false;
  };
}-*/;

Just be careful about what your onclick is doing in order to avoid possible memory leaks.

Comments (1)

Struts 2 AJAX Tutorial – Dojo Autocompleter Example

This tutorial was written for Struts 2.1.2. A lot has changed in newer versions. The Dojo Plugin is no longer officially supported by the Struts 2 team. Also, please see Muhammad’s comment in the comment section if you’re using the latest version of Struts 2.  You may want to check out Google Closure if you’re looking for a good JS library.

Struts 2 comes with a Dojo Toolkit plugin which makes developing an AJAX application easier than ever.  In addition, the AJAX plugin I would most recommend is the Struts 2 JSON plugin.  In this example, we will use the two side-by-side to create an autocompleter.  In order to use the Ajax support provided in Struts 2, I would recommend Struts 2.1.2 or later.  Include struts2-dojo-plugin-2.1.2.jar and jsonplugin-0.30.jar in your WEB-INF/lib directory.

First, we will create the action for the field that we wish to autocomplete:

package com.lumidant.tutorial.struts2.action;

import java.util.HashMap;
import java.util.Map;

import com.opensymphony.xwork2.ActionSupport;
import com.lumidant.tutorial.struts.dao.*;

public class AutocompleteField extends ActionSupport {

    private String city;
    private Map<String,String> json;

    public String execute() throws Exception() {
        return SUCCESS;
    }

    public String getCities() throws Exception() {
        json = new HashMap<String,String>();

        if(city != null && city.length() > 0) {
            CityDao dao = new CityDao();
            List<City> cities = dao.getCitiesStartingWith(city);
            for(City city : cities) {
                json.put(city.getId(), city.getName() + ", " + city.getState().getAbbreviation());
            }
        }

        return SUCCESS;
    }

    public void setCity(String city) {
        this.city = city;
    }

    public Map<String,String> getJson() {
        return json;
    }

}

The getCities method in our action acts on the input String city that we’re given and creates a Map of cities starting with that text.  The key of our Map is going to be the hidden option value while the value of our Map is going to be our option text.

Next, we will modify our struts.xml configuration file to utilize the JSON plugin by extending json-default:

<package name="example" extends="json-default">
  <action name="AutocompleteField" class="com.lumidant.tutorial.struts2.action.AutocompleteField">
    <result type="json><param name="root">json</param></result>
  </action>
</package>

The root parameter that we specify is the name of the variable from our Action that we want to have converted and serialized to a JSON output.

If instead of serializing a Java object to JSON you wish to create the JSON string directly yourself, you can instead use a result type of “stream”:

<action name="jsondata" class="com.lumidant.tutorial.struts2.action.JsonDataAction">
  <result type="stream">
    <param name="contentType">application/json</param>
  </result>
</action>

And finally, we get to create our .jsp view:

<%@ taglib prefix="s" uri="/struts-tags" %>
<%@ taglib prefix="sx" uri="/struts-dojo-tags" %>

<html>
  <head>
    <sx:head />
  </head>
  <body>
    <s:url id="cityList" action="AutocompleteField" method="getCities" />
    <sx:autocompleter name="city" theme="ajax" href="%{cityList}" size="24" />
  </body>
</html>

For any of the Dojo plug-in features that you use, you will need to include the <sx:head /> tag, which includes the relevant JavaScript tags into your page’s head tag.  Then you can see that the autocompleter’s name attribute aligns with the city field in our Action and the url’s method attribute aligns with our Action’s getCities method.  Now, when you visit your new page and start typing in the text box, you should see the field autocompleting.  There are some other cool built-in Dojo tags that you should look at as well like the datetimepicker, which provides a really nice calendar.

Comments (27)

Struts 2 Tutorial – Validation and Error Handling

Validation is an important part of any web framework because it is one of the most painfully repetitive things to have to continually recreate.  In Struts 2, validation is handled by creating an Action-validation.xml file.  So, if we have an AddUser Action then we would create an AddUser-validation.xml file:

<!DOCTYPE validators PUBLIC "-//OpenSymphony Group//XWork Validator 1.0.2//EN"
    "http://www.opensymphony.com/xwork/xwork-validator-1.0.2.dtd">

<validators>
  <field name="userId">
    <field-validator type="requiredstring">
      <message>Username is required</message>
    </field-validator>
  </field>
</validators>

It is important that you have both a getter and setter for the field you are validating.  For example, AddUser would need both of the following method signatures for validation to work properly: “public String getUserId()” and “public void setUserId(String userId)”.  You can get more information about the other types of validators from the Struts 2 documentation.

You can also control error handling from your Action class.  For example, let’s say that the user picks a username which is already registered.  We wouldn’t be able to determine this with validation alone, but would need to check the database in our Action class.  So when we determine that we can call “addActionError(String message)” from our class.  Then when we want to print any errors out on our page, we simply use the tag:

<s:actionerror />

Comments (1)

Struts 2 Tutorial – Struts Configuration

The struts.xml file defines the relationship between actions and .jsp views, the inclusion of interceptors, and possible result types.  It’s essential that you be able to handle at least basic configuration changes, so we’ll demonstrate the most important and frequently used below.

Packages: Extension, Namespaces, and More

For more complex applications, you will likely want to split the configuration between multiple packages.  In Struts 2.0.x, the the default package is struts-default.  Most of the time, extending this package is a pretty good place to start from.

<package name="example" extends="struts-default">
  <interceptors>
    <interceptor name="authorization" class="com.lumidant.tutorial.struts2.interceptor.AuthorizationInterceptor">

    <interceptor-stack name="authStack">
      <interceptor-ref name="authorization" />
      <interceptor-ref name="defaultStack" />
    </interceptor-stack>
  </interceptors>

  <global-results>
    <result name="error">/WEB-INF/pages/error.jsp</result>
  </global-results>

</package>

In the package above, we did not define any action mappings, but rather we defined some more general properties that we can share between other packages.   We can now extend the package we just defined when creating new packages.  This package and any that extend it will have all Action.ERROR results go to error.jsp.  We also defined a new interceptor and interceptor stack that our actions and packages can make use of.  In this example, you could imagine that we would have two other packages extending this one.  One package would contain pages that any user could visit.  The other package could contain pages requiring the user to be logged in, so we would set the default-interceptor-ref to “authStack” as shown below:

<package name="admin" namespace="/admin" extends="example">
  <default-interceptor-ref name="authStack"/>

  <action name="DeleteSomething_*" method="{1}" class="com.lumidant.tutorial.struts2.action.DeleteSomething">
    <result name="input">/WEB-INF/pages/deleteSomething.jsp</result>
    <result>/WEB-INF/pages/deleteSuccessful.jsp</result>
  </action>
</package>

We also introduced additional new topics in this example.  Firstly, you’ll see that we created a namespace.  That means that all the actions in this package will be accessed through a spearate URL.  In this example it is an “/admin” URL.  Also, you’ll see that we put the “*” wildcard in the action name.  What this is doing is taking what was located in the * and replacing the “{1}” with that string.  Since the “{1}” is located in the method attribute, we will be calling a method on our action.  So let’s say the user accesses /admin/DeleteSomething_input.action.  Then the input method of the DeleteSomething.java action will be called.  Assuming we did not define our own input method, then we will inherit the input method from ActionSupport, which will take us to the result named “input”, which in this example is the deleteSomething.jsp page.

Better URL Structure

By adding the following a child of the struts tag, you no longer need to append .action to your URLs.

<constant name="struts.action.extension" value="action,,"/>

Action Chaining

<action name="LogIn_*" method="{1}" class="com.lumidant.tutorial.struts2.action.LogIn">
  <result type="chain">ShowHomepage</result>
</action>

What happens when we don’t want to show a .jsp page as the result of our action, but instead want to continue on directly to another action?  We simply use the result type “chain” to forward to another action.

Redirect After Post

<action name="SubmitOrder_*" method="{1}" class="com.lumidant.tutorial.struts2.action.SubmitOrder">
  <result name="redirect" type="redirect-action">
    <param name="actionName">DisplayOrder</param>
    <param name="namespace">/user</param>
  </result>
</action>

Very often, after an action is taken, we want to redirect the user to a separate action.  For example, let’s say the user submits an order.  If we leave the URL in their browser as SubmitOrder.action and they hit refresh, then the order could be submitted a second time.  So after they submit an order, it’s probably better if we redirect them to another action, such as one displaying the order they just placed with a thank you message.

Comments (3)