Blog Archives

December 18th, 2009
7:45 pm
Installing the Glassfish Eclipse Plugin

Posted under Eclipse
Tags , ,

The process is a workaround for this eclipse bug, which seems to have been around for some time.

  1. In Eclipse, enter Help/Add new software
  2. Click the Add button to add a new update site, and enter the url https://ajax.dev.java.net/eclipse (I have also used http://ajax.dev.java.net/eclipse instead as suggested by other forums, but some users state that this does not work).
  3. Wait for the screen to populate (this may take some time), then select “Glassfish Java EE 5 and Java EE 6 support” and hit next
  4. Proceed with the installation as directed by the wizard.

No Comments »

December 18th, 2009
4:52 pm
Eclipse Glassfish Plugin loses sync with Glassfish start/stop state

Posted under Eclipse
Tags , , ,

This appears to be an issue if you start Glassfish (2.1.1) outside of Eclipse (3.5.1) – Eclipse does not then always sync with it properly. It may try to start it when it is already started and fail, then fail to publish/run projects correctly.
There is an old bug logged on this here. It claims to have been resolved, but the resolution does not appear to be seamless – it appears that Eclipse cannot fully integrate with an externally started Glassfish.

I expect this to be sorted with Glassfish V3 as this is fully OSGI compliant.
In the meantime, the answer seems to be to allow Eclipse to fully control Glassfish, i.e. start and stop it itself, and to not start Glassfish externally when using Eclipse.

No Comments »

December 18th, 2009
11:33 am
Java Dev setup – Eclipse/Eclipselink/ICEfaces/Glassfish/Tomcat

Posted under Java
Tags , , , , ,

  1. Decide on component versions to be used by building a cross compatibility matrix. Generally you will want to install the latest production builds of all components consistent with full cross compatibility. Also to be considered are the various tool bundles available, which can simplify installation and configuration by allowing multiple tools to be installed from a single kit. However, many of the bundles overlap, so this needs to be taken into account (in addition to the compatibility matrix)  so that you do not end up installing multiple versions of the same tool – for example, Java EE can come with the JDK or with Eclipse. In my case, I am using an Eclipse bundle which includes Java EE.
  2. Download and install the chosen Java SE JDK.
  3. Download and install Glassfish (Eclipse has a plugin for, and therefore a dependency on, Glassfish so we do the latter first).
  4. Download and install Eclipse. My bundle included Java EE 5 and Eclipselink and all the web tools.
  5. Install the Glassfish Plugin for Eclipse.
  6. Download ICEfaces (e.g. v1.8.x). This just needs unzipping to any desired target folder (e.g. E:\ICEfaces-1.8.x). The distribution contains full documentation for getting started, running tutorials, and development.
  7. Download and Install the Eclipse ICEfaces plugin.
  8. Download Tomcat if required. You may just want to use Glassfish as your servlet container, but in my case some development projects will use JSF/ICEfaces/Tomcat without Java EE. I have in the past used the windows service installer version, which is a self installing .exe and installs/runs Tomcat as a service. However note that this does not work under Windows 64-bit if you are using a 32 bit JVM. See here for a manual install process from the zip kit to give you all the functionality of the windows installer version, including run as a service, configuration utility, and system tray monitor/utility.

No Comments »

December 4th, 2009
4:30 pm
OSGi

Posted under Java
Tags , ,

OSGI is an acronym for the Open Services Gateway Initiative, an open standards organisation formed to promote the specification of a Java based services platform that can be remotely managed. The Acronym is now obsolete, and instead the organisation is called the OSGi Alliance.

Eclipse is an OSGi compliant platform, and uses OSGi to manage its services and plugins. An OSGi plugin is quickly recognisable by the fact that its library jars are broken down to a fine grained level to allow flexible deployment, and have long names consisting of a package prefix and version number information. A typical example of an OSGi style jar is this core Java persistence jar :-

org.eclipse.persistence.core_1.1.3.v20091002-r5404.jar

Glassfish V3 is also OSGi compliant, but Glassfish V2.1 and earlier are not.

An overview and details of the OSGi concept and specification may be found on Wikipedia here.

No Comments »

December 1st, 2009
11:38 am
EJB referencing/JNDI mapping examples in JSF/Glassfish

Posted under Glassfish
Tags , , ,

Update

I have posted some further notes on this here. The notes are in raw form from an earlier investigative email – much of it is covered here, but some points and links are not, and I do not have the time or inclination at present to rework everything into a single post!

The following examples show typical scenarios which have been tested as working :-

1/ Local EJB Interface injected into JSF managed bean via @EJB

Note that when implementing a dual interface as here, you can extend a single underlying interface. In this case, SimpleBeanLocal and SimpleBeanRemote both extend SimpleBean. However, when you do this, the implementation code must explicitly implemement both SimpleBeanLocal and SimpleBeanRemote as in this example. Implementing the superinterface SimpleBean on its own will not work. This is also explained in this post.

JSF managed bean code

@EJB()
private SimpleBean simpleBean;

 

EJB Implementation Code

@Stateless()
public class SimpleBeanImpl implements SimpleBeanLocal, SimpleBeanRemote {

...class code here...

}

 

 

2/ Local EJB Interface looked up in JSF managed bean directly via JNDI 

JSF managed bean code

try {
  InitialContext ctx = new InitialContext();

  /* Note that the JNDI name consists of the Java EE Environment Naming Context (ENC) -
    "java:comp/env", followed by "/", followed by the <ejb-ref-name> used in web.xml.
    The extra /Local is just to make the name different to the remote example.
    Any name can be used providing web.xml matches, and multiple slashes can be present.
  */

  simpleBean = (SimpleBean) ctx.lookup("java:comp/env/ejb/JPAGlassFishIce/Local/SimpleBean");     
  userList = simpleBean.fetchUsers();
} catch (NamingException e1) {
  e1.printStackTrace();
}

 

web.xml

<!-- We define a reference for the bean here.
     If we were using @EJB this would do it for us,
     but in this case we are using an explicit JNDI lookup.
-->
<ejb-local-ref>
    <ejb-ref-name>ejb/JPAGlassFishIce/Local/SimpleBean</ejb-ref-name>
    <ejb-ref-type>Session</ejb-ref-type>
    <local-home></local-home>
    <local>uk.co.salientsoft.jpaglassfishice.domain.SimpleBeanLocal</local>
</ejb-local-ref>

 

EJB Implementation Code

@Stateless()
public class SimpleBeanImpl implements SimpleBeanLocal, SimpleBeanRemote {

...class code here...

}

 

 

3/ Remote EJB Interface injected into JSF managed bean via @EJB

JSF managed bean code

@EJB(name="ejb/JPAGlassFishIce/SimpleBean", beanInterface=SimpleBeanRemote.class)
private SimpleBean simpleBean;

 

EJB Implementation Code

@Stateless(mappedName="ejb/JPAGlassFishIceEJB/SimpleBean")
public class SimpleBeanImpl implements SimpleBeanLocal, SimpleBeanRemote {

...class code here...

}

 

 

4/ Remote EJB Interface looked up in JSF managed bean directly via JNDI 

JSF managed bean code

try {
  InitialContext ctx = new InitialContext();

  /* Note that the JNDI name here matches the mappedName given in the
     @Stateless annotation in the EJB implementation code.
     mappedName is only relevant for remote interfaces.
     It is not used for a local interface.
  */

  simpleBean = (SimpleBean) ctx.lookup=("ejb/JPAGlassFishIceEJB/SimpleBean");     
  userList = simpleBean.fetchUsers();
} catch (NamingException e1) {
  e1.printStackTrace();
}

 

EJB Implementation Code

@Stateless(mappedName="ejb/JPAGlassFishIceEJB/SimpleBean")
public class SimpleBeanImpl implements SimpleBeanLocal, SimpleBeanRemote {

...class code here...

}

No Comments »

November 30th, 2009
5:28 pm
Accessing Local and Remote EJBs in Glassfish

Posted under Glassfish
Tags , , ,

This Glassfish article  is a must read reference on the naming and JNDI minefield when looking up local and remote EJBs.
There is also a very  informative Refcardz card on this topic. Refcardz can be downloaded as PDFs if  you register.
In my experience, there is a lot of misinformation around the internet on this which can be time consuming to weed out.

I’ve posted some examples of local and remote EJB access via both injection and JNDI here.

Here are some key points I worked through and learned :-

  1. Despite a number of blog posts to the contrary, EJBs can be injected via @EJB into JSF managed beans, POJOs called from managed beans, and servlets provided the JSF/servlets are running in the EJB container, e.g. if Glassfish is used both as servlet and EJB container.
  2. When injecting local EJBs, using the defaults on @EJB and matching defaults e.g. on @Stateless will work and the bean will inject.
  3. When injecting remote EJBs via @EJB, use the mappedName argument to specify the JNDI name of the remote bean. It is also essential to specify the class of the remote EJB interface in the beanInterface argument to @EJB. Failure to do this will result in NamingExceptions, which can give the misleading impression that it is the JNDI name that is wrong.
  4. If @EJB is not used, then <ejb-local-ref> may be used in web.xml to define a reference to the bean. If @EJB is used then this is handled automatically. The above Glassfish article details how the various fields in @EJB and <ejb-local-ref> are related.
  5. In addition to @EJB and direct JNDI lookups, EJBs can be injected via JSF using a custom EL resolver which performs the JNDI lookups and injections performed in faces-config.xml.  An interesting example of a custom EL resolver to do this is here. However, for injecting EJBs,  @EJB requires no extra code. It is also possible to inject EJBs via Spring, into beans managed by a Spring container. However these have not been pursued as @EJB is the easiest way. It would be overkill to use a Spring container purely for EJB injection/service location.

No Comments »

November 30th, 2009
1:40 pm
JPA Web Tutorials

Posted under JPA
Tags , , , , , , , ,

Update 08/09/2022

Another interesting and helpful post on primary key generation may be found on Baeldung here.

Original Post

There are a number listed on eclipse.org, oracle.com, and Sun.com. The eclipse ones are often not all complete but still useful.

  1. A general list of Eclipse tutorials is here
  2. Eclipse/JPA/Tomcat web tutorial
  3. Eclipselink/JPA/JSF web tutorial (looks incomplete and is missing the source code).
  4. Eclipselink/JPA/Glassfish V2 Web Tutorial – also a work in progress.
  5. Oracle – Build a Web Application (JSF) Using JPA
  6. Oracle – Example: Web Application (JSF) Using JPA (another article using the same code example as the previous one)
  7. The Sun Java ee 5 tutorial contains a JPA example.

No Comments »

November 30th, 2009
1:11 pm
JPA Tutorial /EJB3/Glassfish/Derby

Posted under JPA
Tags , , ,

This one is from Web Age Solutions and is a good basic tutorial building on their earlier “simple session bean” one:-
http://www.webagesolutions.com/knowledgebase/javakb/jkb006/index.html

No Comments »

November 25th, 2009
5:53 pm
Eclipse/JPA outside container/Glassfish example

Posted under JPA
Tags , , ,

JPA Eclipse + GlassFish + Oracle XE – Outside EJB Container

Introduction

This example details the configuration of JPA running in Eclipse, using EclipseLink and GlassFish 2.1 and Oracle XE.
Eclipselink therefore overrides the built in TopLink Essentials JPA in GlassFish 2.1.

 

Installation

  1. Install the latest Java JDK 1.6 release
  2. Install the Eclipse Galilieo Java EE package (includes EclipseLink)
  3. Install GlassFish 2.1
  4. Install the GlassFish Eclipse Plugin (see web notes about downloading/installing this)
  5. Download and install Oracle XE

 

 Database Creation

In the Oracle XE database home page, click on Administration, then Manage Database Users, create database user. For testing purposes, you can give the user all roles and privileges, however you would not do this in a production environment. Note that in Oracle, creating a database user also creates an empty database schema, as the two terms are synonymous. A single Oracle XE database installation can have any number of schemas (users), all as distinct logical databases in the same database instance (container).

 

 Connection Pool / JDB Resource Creation

Open the GlassFish administration web page (by default this is at http://localhost:4848) and log in (default is admin/adminadmin). Open Resources, JDBC, and click on Connection Pools – the text, not the adjacent arrow. This will display the connection pools in the RHS pane. Click on New. Name the pool JPATestPool. Select a resource type of javax.sql.datasource, and select Oracle as the database vendor. Click Next, then in the additional properties, set the following values :-

Property Name

Value

User Your XE database username
Password Your XE database password
URL jdbc:oracle:thin:@localhost:1521:xe

 
Click Save to save the new connection pool.

Click on JDBC Resources in the left hand pane (again, the wording not the arrow), and click new to create a new resource. Select the conncetion pool just created in the dropdown list. For the JNDI name, enter jdbc/JPATestPool and click OK to save. Note that the JNDI name given must match the name given in the <non-jta-data-source> element value in persistence.xml.

 

Project Creation

  1. Create a new JPA project with the wizard. Select “GlassFish v2.1 Java EE 5” as the target runtime.
  2. Select either Default, Utility, or minimal for the configuration – this determines which facets are added to the project. Facets can be added later via the “Project Facets” page in the project properties.
    All of the above configurations worked.
  3. Following this, a connectivity driver (for Oracle in this case) needs adding to Eclipse and then to the project as follows :-
    Download ojdbc14.jar from Oracle.com here :-
    http://www.oracle.com/technology/software/tech/java/sqlj_jdbc/htdocs/jdbc_10201.html
  4. Copy the file to the glassfish\lib folder under the GlassFish installation directory and Restart GlassFish.
    N.B. the jar file must be placed in this location
  5. Click on Window, preferences, and select Data Management, Connectivity, Driver Definitions in the left pane.
  6. Click Add, and assuming Oracle XE is in use, select “Oracle Thin Driver” for Oracle 10.
  7. Click on the Jar List tab. ojdbc14.jar should be listed. Browse for the above location where the actual jar was placed (<GlassFish_Home>\glassfish\lib) and select the jar from there.
    The properties tab allows defaults to be set up for database connectivity, but these values will be added in GlassFish when the data source is created.
  8.  Select Java Build Path in the project properties for the project you created above. Pick the libraries tab, and click Add Library. Click “Add Library” and select “Connectivity Driver Definitions” from the list. Select “Oracle thin Driver” from the drop down. If it is not present (i.e. because you did not create it correctly as above), you can click the button/icon to the right of the drop down and add the connectivity driver to Eclipse from there. Once done, you select it in the drop down then click finish to add it to the project.

 

 Creating the Source Code

Create the following java classes in Eclipse by right clicking the “src” folder of the project and selecting New,  Class. For the package name, enter uk.co.salientsoft.jpatest.domain. For the UserInfo class (which is the persisted class), the combined package and classname must match the value given in the <class> element in persistence.xml.

Class: JPATest

package uk.co.salientsoft.jpatest.domain;
import javax.persistence.*;
public class JPATest {

 private static final String PERSISTENCE_UNIT_NAME = "JPATest";
 private EntityManagerFactory factory;
 
 public static void main(String[] args) {
  JPATest jpaTest = new JPATest();
  jpaTest.addEntries();
 }

 public JPATest() {
  factory = Persistence.createEntityManagerFactory(PERSISTENCE_UNIT_NAME);
 }
 
 public void addEntries() {
  EntityManager em = factory.createEntityManager();

  // Begin a new local transaction so that we can persist a new entity
  em.getTransaction().begin();

  // Read the existing entries
  Query q = em.createQuery("select u from UserInfo u");

  // Do we have entries?
  boolean createNewEntries = (q.getResultList().size() == 0);

  // No, so lets create new entries
  if (createNewEntries) {

   UserInfo userInfo;   
   
   userInfo = new UserInfo();
   userInfo.setUserName("Bilbo.Baggins");
   em.persist(userInfo);
   userInfo = new UserInfo();
   userInfo.setUserName("Frodo.Baggins");
   em.persist(userInfo);        
  }

  // Commit the transaction, which will cause the entity to
  // be stored in the database
  em.getTransaction().commit();
  
  // It is always good practice to close the EntityManager so that
  // resources are conserved.
  em.close();
 } 
}

Class: UserInfo

package uk.co.salientsoft.jpatest.domain;
import java.io.Serializable;
import javax.persistence.*;

/**
 * Entity implementation class for Entity: UserInfo
 *
 */
@Entity
public class UserInfo implements Serializable {
 
 @Id
 @GeneratedValue(strategy=GenerationType.AUTO)
 private long userID;
 private String userName;
 private static final long serialVersionUID = 1L; 
 public UserInfo() {
  super();
 }
 
 public long getUserID() {
   return this.userID;
 }

 public void setUserID(long userID) {
  this.userID = userID;
 }
   
 public String getUserName() {
   return this.userName;
 }

 public void setUserName(String userName) {
  this.userName = userName;
 }
}
 

Persistence.xml

<?xml version="1.0" encoding="UTF-8"?>
<persistence version="1.0"
 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_1_0.xsd">
 <persistence-unit name="JPATest" transaction-type="RESOURCE_LOCAL">
  <provider>org.eclipse.persistence.jpa.PersistenceProvider</provider>
  <non-jta-data-source>jdbc/JPATestPool</non-jta-data-source>
  <class>uk.co.salientsoft.jpatest.domain.UserInfo</class>
  <properties>
   <property name="eclipselink.target-server" value="None" />
   <property name="eclipselink.logging.level" value="FINEST" />
   <property name="eclipselink.session-name" value="JPATestSession" />

   <!-- EclipseLink should create the database schema automatically -->
   <property name="eclipselink.ddl-generation" value="drop-and-create-tables" />
   <property name="eclipselink.ddl-generation.output-mode" value="database" />

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

 

Notes  on Persistence.xml

 <persistence-unit name="JPATest" transaction-type="RESOURCE_LOCAL">

The persistence unit defines a related grouping of classes, metadata etc. which are being persisted .

 NOTE – ensure that the value matches the one passed to createEntityManagerFactory in the code, or the call causes a stack trace citing no persistence provider found – all the available persistence providers are tried and listed and they all return null. They are all tried to see if they support the given persistence unit  (i.e. are they listed as the provider for that persistence unit in persistence.xml) hence the error.

 Transaction-type needs to be ”RESOURCE_LOCAL” if jpa is used outside the EJB container, in which case the datasource is defined as a <non-jta-data-source>. Note that the datasource in this case is still defined in GlassFish.

The alternative for jpa usage inside the conainer , e.g. from a session bean, would be to defined transaction-type as “JTA” and the datasource as a <jta-data-source>.

<property name="eclipselink.target-server" value="None" />

 

Note  that with JPA inside the container, the above property would have the following value :-

<property name="eclipselink.target-server" value="SunAS9" />

 

When set to “SunAS9”, you must use a JTA data source and JTA transaction type or you get an error. When you use “None” you can use <non-jta-data-source> and “RESOURCE_LOCAL”, but note that you can still refer to the data source defined in GlassFish, or you can define one explicitly in persistence.xml. You could define one explicitly in persistence.xml as follows :-

 <property name="eclipselink.jdbc.url" value="jdbc:oracle:thin:@localhost:1521:xe"/>
 <property name="eclipselink.jdbc.user" value="jpatest"/>
 <property name="eclipselink.jdbc.password" value="jpatest"/>
 <property name="eclipselink.jdbc.driver" value="oracle.jdbc.OracleDriver"/>

 

The mechanism used to drop and create the tables automatically (“drop-and-create-tables” value) is jpa provider dependant (and may not always be available). When it is used with EclipseLink as above, a stack trace with a number of errors is dumped when it tries to drop non existant tables etc., and due to other issues. If you check in Oracle XE and can see the tables and the data, the errors can be ignored. The drop and create only needs to be done once to create the tables. You can remove this property from persistence.xml to prevent the tables being dropped and created each time. Note that this can also be done directly from Eclipse via the project context menu, as detailed here.
 

Running the application

  1. In Eclipse, select Window, Show View, Servers. If GlassFish is not listed, right click the server window and select New Server. Then Select GlassFish 2.1 Java EE 5. Click Next, and browse for the <GlassFish_Home>\glassfish directory (leave the JRE as the default).
  2. Right click the server in the servers view, then select start to start it if it is not running.
  3. Right click on JPATest.java and select Run as, then Java application.
  4. The application should then run and populate the database. Log in to the XE database home page as the user/schema you created, and click on the object browser.
  5. Click on the UserInfo table and you should see the rows which were created.

No Comments »