Mule+Servlet+JPA
From Resin 3.0
Mule and Resin using the Mule Servlet provider and JPA (Amber)
Mule can be run within Resin and use objects created by it as components. This allows Mule to take advantage of Resin IoC and Amber, Caucho's implementation of JPA. This example shows how to use all of these technologies together.
You'll need a running database in order to run this example. We use MySQL here, but any database with a JDBC driver should work.
(The following has been tested with Resin 3.1.5 and Mule 1.4.3)
- Download Resin from http://www.caucho.com/download
- Unzip Resin into
/usr/local/share/resin
- Download the MySQL JDBC driver from http://www.mysql.com/products/connector/j/
- Copy the MySQL JDBC driver jar to
/usr/local/share/resin/lib
- Create the Mule webapp directory structure:
mkdir -p /usr/local/share/resin/webapps/mule/WEB-INF/lib/
mkdir -p /usr/local/share/resin/webapps/mule/WEB-INF/classes/example/
mkdir -p /usr/local/share/resin/webapps/mule/WEB-INF/classes/META-INF/
- Download Mule from http://mule.mulesource.org/display/MULE/Download
- Unzip Mule
- Copy all the jars included the Mule lib/ directory to
/usr/local/share/resin/webapps/mule/WEB-INF/lib/
- Initialize the database by executing the following SQL statements:
CREATE DATABASE MuleJPA; CREATE TABLE MuleJPA.basic_courses (id INTEGER PRIMARY KEY auto_increment, course VARCHAR(250), teacher VARCHAR(250)); INSERT INTO MuleJPA.basic_courses VALUES('1', 'Potions', 'Severus Snape'); INSERT INTO MuleJPA.basic_courses VALUES('2', 'Transfiguration', 'Minerva McGonagall');
- Create the configuration file
/usr/local/share/resin/webapps/mule/WEB-INF/resin-web.xml
<?xml version="1.0" encoding="UTF-8"?> <web-app xmlns="http://caucho.com/ns/resin"> <!-- Make the database accessible to Amber --> <database> <jndi-name>jdbc/resin</jndi-name> <driver type="org.gjt.mm.mysql.Driver"> <url>jdbc:mysql://localhost:3306/MuleJPA</url> <user>root</user> <password/> </driver> </database> <!-- Tell Amber which database to use --> <ejb-server data-source="jdbc/resin"/> <!-- Create the bean reference for the Mule component --> <bean class="example.CourseComponent" name="courseComponent"/> <!-- Tell Mule where to find its configuration --> <context-param> <param-name>org.mule.config</param-name> <param-value>/WEB-INF/course-config.xml</param-value> </context-param> <!-- The listener that starts Mule. The MuleResinContextListener extends Mule's own MuleXmlBuilderContextListener, but allows Mule to find Resin's beans. --> <listener> <listener-class>com.caucho.mule.MuleResinContextListener</listener-class> </listener> <!-- Set up a servlet that Mule can use for input --> <servlet servlet-name="mule-servlet" servlet-class="org.mule.providers.http.servlet.MuleReceiverServlet"/> <servlet-mapping url-pattern="/*" servlet-name="mule-servlet"/> </web-app>
- Create the JPA configuration file for Amber
/usr/local/share/resin/webapps/mule/WEB-INF/classes/META-INF/persistence.xml
<?xml version="1.0" encoding="UTF-8"?> <persistence xmlns="http://java.sun.com/xml/ns/persistence" version="1.0"> <persistence-unit name="example"> <class>example.CourseBean</class> <exclude-unlisted-classes/> </persistence-unit> </persistence>
- Create the configuration file for Resin IoC (WebBeans)
/usr/local/share/resin/webapps/mule/WEB-INF/classes/META-INF/web-beans.xml
<?xml version="1.0" encoding="UTF-8"?> <web-beans xmlns="http://caucho.com/ns/resin"> <!-- - The web-beans.xml marks a class root for WebBeans to search for - @Component beans. Since the example doesn't need to override any - defaults, there's no additional configuration necessary. --> </web-beans>
- Create the configuration file for Mule
/usr/local/share/resin/webapps/mule/WEB-INF/course-config.xml
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE mule-configuration PUBLIC "-//MuleSource //DTD mule-configuration XML V1.0//EN" "http://mule.mulesource.org/dtds/mule-configuration.dtd"> <mule-configuration id="Course_Service" version="1.0"> <connector name="servletConnector" className="org.mule.providers.http.servlet.ServletConnector"> <properties> <property name="servletUrl" value="course"/> </properties> </connector> <model name="courseModel"> <!-- Mule will ask Resin IoC to find "courseComponent" --> <mule-descriptor name="CourseUMO" implementation="courseComponent"> <inbound-router> <endpoint synchronous="true" address="servlet://course"/> </inbound-router> <outbound-router> <router className="org.mule.routing.outbound.OutboundPassThroughRouter"> <endpoint address="stream://System.out"/> </router> </outbound-router> </mule-descriptor> </model> </mule-configuration>
- Create a JPA persisted data bean file
/usr/local/share/resin/webapps/mule/WEB-INF/classes/example/CourseBean.java
package example; import javax.persistence.*; @Entity@Table(name="basic_courses") public class CourseBean { private int _id; private String _course; private String _teacher; @Id@Column(name="id") @GeneratedValue public int getId() { return _id; } public void setId(int id) { _id = id; } @Basic public String getCourse() { return _course; } public void setCourse(String course) { _course = course; } @Basic public String getTeacher() { return _teacher; } public void setTeacher(String teacher) { _teacher = teacher; } }
- Create the Mule component
/usr/local/share/resin/webapps/cxf/WEB-INF/classes/example/CourseComponent.java
package example; import java.io.*; import javax.servlet.*; import javax.servlet.http.*; import javax.persistence.*; import org.mule.umo.lifecycle.Callable; import org.mule.umo.UMOEventContext; public class CourseComponent implements Callable { // Resin IoC will inject this @PersistenceContext(name="example") private EntityManager _manager; public Object onCall(UMOEventContext context) { StringBuilder sb = new StringBuilder(); CourseBean []course = new CourseBean[2]; course[0] = _manager.find(CourseBean.class, new Integer(1)); course[1] = _manager.find(CourseBean.class, new Integer(2)); sb.append("Course Details\n\n"); for (int i = 0; i < course.length; i++) { sb.append("course: " + course[i].getCourse() + "\n"); sb.append("teacher: " + course[i].getTeacher() + "\n\n"); } return sb.toString(); } }
- Start Resin with
java -jar /usr/local/share/resin/lib/resin.jar
- Look at http://localhost:8080/mule/course
It should showCourse Details course: Potions teacher: Severus Snape course: Transfiguration teacher: Minerva McGonagall
The same output should appear on the terminal where you ran Resin!
Compare this example to http://www.caucho.com/resin/examples/amber-basic/index.xtp