GlassFish embedded, JPA, EJB, DataSource and glassfish-resources.xml

In a previous post I wrote about using @DataSourceDefinition to create a JTA data source for JPA in a standalone java application. Another option is to use glassfish-resources.xml to define the data source. The following is a standalone test app that includes glassfish embedded, JPA, EJB, Servlet, and JTA data source defined with glassfish-resources.xml.

As with the previous test app, GlassFish server is running in the same JVM as the test app. And in this example, the test program starts the GlassFish embedded, constructs a scattered web app, deploys it, sends http request, undeploys it, and finally shuts down the server.

WEB-INF/classes/META-INF/persistence.xml :
<?xml version="1.0" encoding="UTF-8"?>
<persistence version="2.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_2_0.xsd">
<persistence-unit name="test_pu" transaction-type="JTA">
<jta-data-source>java:app/jdbc/test</jta-data-source>
<properties>
<property name="eclipselink.ddl-generation" value="create-tables"/>
<property name="eclipselink.logging.level" value="FINE"/>
</properties>
</persistence-unit>
</persistence>
WEB-INF/glassfish-resources.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE resources PUBLIC "-//GlassFish.org//DTD GlassFish Application Server 3.1 Resource Definitions//EN" "http://glassfish.org/dtds/glassfish-resources_1_5.dtd">

<resources>
<jdbc-connection-pool
name="java:app/jdbc/test_pool"
res-type="javax.sql.DataSource"
datasource-classname="com.mysql.jdbc.jdbc2.optional.MysqlDataSource"
pool-resize-quantity="1"
max-pool-size="5"
steady-pool-size="0"
statement-timeout-in-seconds="30" >
<property name="User" value="root"></property>
<property name="Password" value="root"></property>
<property name="portNumber" value="3306"></property>
<property name="dataBaseName" value="test"></property>
<property name="serverName" value="localhost"></property>
</jdbc-connection-pool>
<jdbc-resource pool-name="java:app/jdbc/test_pool" jndi-name="java:app/jdbc/test"></jdbc-resource>
</resources>
WEB-INF/classes/test/Employee:
package test;
import javax.persistence.*;

@Entity
public class Employee implements java.io.Serializable {
private static final long serialVersionUID = 1L;

@Id @GeneratedValue(strategy = GenerationType.AUTO)
private Long id;

@Basic private String name;

public Long getId() {
return id;
}

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

public String getName() {
return name;
}

public void setName(String name) {
this.name = name;
}

@Override public int hashCode() {
int hash = 0;
hash += (id != null ? id.hashCode() : 0);
return hash;
}

@Override public boolean equals(Object object) {
// TODO: Warning - this method won't work in the case the id fields are not set
if (!(object instanceof Employee)) {
return false;
}
Employee other = (Employee) object;
if ((this.id == null && other.id != null) || (this.id != null && !this.id.equals(other.id))) {
return false;
}
return true;
}

@Override public String toString() {
return "Employee id=" + id + ", name=" + name;
}
}
WEB-INF/classes/test/TestBean:
package test;
import javax.ejb.Stateless;
import javax.persistence.*;
import javax.annotation.sql.DataSourceDefinition;

@Stateless
public class TestBean {
@PersistenceContext private EntityManager em;

public void addEmployee(String[] names) {
for(String name : names) {
Employee e = new Employee();
e.setName(name);
em.persist(e);
}
}
}
WEB-INF/classes/test/TestServlet:
package test;
import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;
import javax.annotation.*;
import javax.ejb.*;

@javax.servlet.annotation.WebServlet(urlPatterns = "/*")
public class TestServlet extends HttpServlet {
@EJB private TestBean testBean;

protected void processRequest(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
PrintWriter out = response.getWriter();
String[] names =request.getParameterValues("name");
testBean.addEmployee(names);
out.println("Added employees " + java.util.Arrays.toString(names));
}

@Override protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
processRequest(request, response);
}

@Override protected void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
processRequest(request, response);
}
}
WEB-INF/classes/test/Client:
package test;

import org.glassfish.embeddable.Deployer;
import org.glassfish.embeddable.GlassFish;
import org.glassfish.embeddable.GlassFishProperties;
import org.glassfish.embeddable.GlassFishRuntime;
import org.glassfish.embeddable.archive.ScatteredArchive;

import java.io.*;
import java.net.*;

public class Client {
private static final String warName = "test";
private static final int portNumber = 8080;
private GlassFish glassfish;
private Deployer deployer;

public static void main(String[] args) throws Exception {
Client client = new Client();
client.setUp();
client.test(args);
client.tearDown();
}

protected void setUp() throws Exception {
GlassFishProperties props = new GlassFishProperties();
props.setPort("http-listener", portNumber);
glassfish = GlassFishRuntime.bootstrap().newGlassFish(props);
glassfish.start();
deployer = glassfish.getDeployer();
}

protected void tearDown() throws Exception {
deployer.undeploy(warName);
glassfish.dispose();
}

protected void test(String[] names) throws Exception {
ScatteredArchive scattered = new ScatteredArchive(warName, ScatteredArchive.Type.WAR, new File("./"));
deployer.deploy(scattered.toURI());
URL url = new URL("http://localhost:" + portNumber + "/" + warName + "/?name=Jon&name=Jane");
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
BufferedReader in = new BufferedReader(new InputStreamReader(conn.getInputStream()));
System.out.println("Request url: " + url);
String line = null;
while ((line = in.readLine()) != null) {
System.out.println(line);
}
in.close();
conn.disconnect();
}
}
To compile from project directory:
$ javac -cp "$GLASSFISH_HOME/lib/embedded/glassfish-embedded-static-shell.jar" WEB-INF/classes/test/*java
Start mysqld, and run the app:
cd /usr/local/mysql-5.1.32; sudo bin/mysqld_safe --user root
java -cp "WEB-INF/classes:$GLASSFISH_HOME/lib/embedded/glassfish-embedded-static-shell.jar:$HOME/mysql-connector-java-5.1.5-bin.jar" test.Client
Among very verbose command-line output are these lines:
Request url: http://localhost:8080/test/?name=Jon&name=Jane
Added employees [Jon, Jane]
classLoader = WebappClassLoader (delegate=true; repositories=WEB-INF/classes/)
Verify entities are successfully created by running mysql:
mysql> select * from EMPLOYEE;
+----+------+
| ID | NAME |
+----+------+
| 1 | Jon |
| 2 | Jane |
+----+------+
2 rows in set (0.00 sec)
The test client main class mimics the strucutre of a JUnit test case, and can be easily converted to one if needed.

Followers

Pageviews Last 7 Days