Archive for November, 2009

November 30th, 2009
6:04 pm
Eclipse Workspaces – Management/Corruption Recovery

Posted under Eclipse
Tags ,

A useful article on this, and on keeping Eclipse clean is here. Some general points on this are as follows :-

  1. In my experience it does not pay to let workspaces become too large, as metadata corruption can sometimes cause the whole workspace to fail to load and cross project pollution of metadata can happen. It also helps with performance not to have a huge workspace. I keep all related projects for a given application in the same workspace, but not others.
  2. The article describes the use of the -clean command line argument to remove cached OSGi framework and Eclipse run time metadata. I haven’t used it myself, but it is said to be able to fix really obscure bugs/issues caused by metadata corruption.
  3. When creating a new workspace, use File/Export/Preferences to save a preferences file which can be imported into the new workspace. This will allow e.g. your plug in libraries and other preferences to be quickly defined in the new workspace. If you do not do this, you need to either download the libraries again via eclipse’s user library management, or load them one at a time. An xml file is used to define the userlibraries and I did not look into how to store a library repository locally with its own xml definition.
  4. Note that when sharing the libraries across multiple workspaces, you will want to change the default download locatation when downloading them initially – the default is <workspace>\libraries, which would mean that subsequent workspaces would be sharing libraries from inside another one.  This post here details my typical folder structure which places the shared libraries at a level above the workspaces. You will need to modify the download path each time you download a library (in my case this involves just taking out the Workspaces\<workspace>\ levels from the path).

No Comments »

November 30th, 2009
5:45 pm
Forwarding from a servlet to a JSP

Posted under JSP
Tags ,

Useful post gives the code for this here. The code extract is as follows :-

String nextJSP = "/searchResults.jsp";
RequestDispatcher dispatcher = getServletContext().getRequestDispatcher(nextJSP);
dispatcher.forward(request,response);

No Comments »

November 30th, 2009
5:40 pm
Execute Operating System commands in a Java Program

Posted under Java
Tags

An interesting article on this is here. It is very thorough and lists all the common gotchas and workarounds to do the job properly.

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:34 pm
Optimising tree structures in JPA

Posted under JPA
Tags ,

Interesting post by Nick Johnson about how to optimise lazy fetches and avoid loading the whole tree.
http://spatula.net/blog/2007/03/optimizing-message-tree-with-jpa.html

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 30th, 2009
12:59 pm
Eclipse errors on startup

Posted under Eclipse
Tags ,

Sometimes Eclipse fails to start correctly, refusing to open various views. The following error is typical :-

“Eclipse Galileo Could not open the editor: The editor class could not be instantiated.
This usually indicates a missing no-arg constructor or that the editor’s class name was mistyped in plugin.xml.”

There can be a number of causes, but this suggestion may fix it (worked for me) :-http://www.eclipse.org/forums/index.php?t=msg&goto=443229&S=c7e035ee876b3f197920eb538fdca5c6#msg_443229

The fix is to delete the following file :-
.metadata/.plugins/org.eclipse.jdt.core/variablesAndContainers.dat 

The problem is said to be related to a bug in the data tools plugin. It should be be fixed in version 1.7.2 of the plugin.

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 »