<dependencyManagement> <dependencies> <dependency> <groupId>org.glassfish.jersey</groupId> <artifactId>jersey-bom</artifactId> <version>2.19</version> <type>pom</type> <scope>import</scope> </dependency> </dependencies> </dependencyManagement> <dependencies> <dependency> <groupId>javax.servlet</groupId> <artifactId>javax.servlet-api</artifactId> <version>3.1.0</version> <scope>provided</scope> </dependency> <dependency> <groupId>org.glassfish.jersey.containers</groupId> <artifactId>jersey-container-servlet</artifactId> </dependency> <dependency> <groupId>com.google.inject</groupId> <artifactId>guice</artifactId> <version>4.0</version> </dependency> <dependency> <groupId>com.google.inject.extensions</groupId> <artifactId>guice-servlet</artifactId> <version>4.0</version> </dependency> <dependency> <groupId>com.squarespace.jersey2-guice</groupId> <artifactId>jersey2-guice</artifactId> <version>0.10</version> </dependency> </dependencies>
Lean example of Tomcat 8 + Guice 4 + Jersey 2.19
TweetPosted on Wednesday Aug 05, 2015 at 02:36PM in Technology
Jersey is the RI of JAX-RS. in this entry, I introduce you how to use Jersey 2.19 with Guice 4 on Tomcat 8. it looks like there are some issues exist as follows but thanks to https://github.com/Squarespace/jersey2-guice , I’ve succeeded to use them anyway.
The entire project which based on Maven can be obtained from My GitHub repository.
Dependencies
web.xml
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd" version="3.1"> <servlet> <servlet-name>Jersey Web Application</servlet-name> <servlet-class>org.glassfish.jersey.servlet.ServletContainer</servlet-class> <init-param> <param-name>jersey.config.server.provider.packages</param-name> <param-value>guice.tomcat.jersey</param-value> </init-param> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>Jersey Web Application</servlet-name> <url-pattern>/webapi/*</url-pattern> </servlet-mapping> <listener> <listener-class>guice.tomcat.MyJerseyGuiceServletContextListener</listener-class> </listener> <filter> <filter-name>guiceFilter</filter-name> <filter-class>com.google.inject.servlet.GuiceFilter</filter-class> </filter> <filter-mapping> <filter-name>guiceFilter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> </web-app>
MyJerseyGuiceServletContextListener.java
In this example, we use the servlet context listener named JerseyGuiceServletContextListener
which comes from jersey2-guice
artifact as parent class.
public class MyJerseyGuiceServletContextListener extends JerseyGuiceServletContextListener { @Override protected List<? extends Module> modules() { return Collections.singletonList(new ServletModule() { @Override protected void configureServlets() { bind(MyService.class).to(MyServiceImpl.class); } }); } }
Service class
We use very simple pair of an interface and implementation that creates a simple greeting message, which used in a past entry so omitted for simplicity.
MyResource.java
This is an simple implementation of JAX-RS resource class. placed under guice.tomcat.jersey
package. the preceding service class named MyService
will be injected by @javax.inject.Inject
annotation.
@Path("myresource") public class MyResource { @Inject private MyService myService; @GET @Produces(MediaType.TEXT_PLAIN) public String getIt() { return myService.hello("Jersey"); } }
Test run
$ curl http://localhost:8080/webapi/myresource Hello, Jersey
Lean example of Tomcat 8 + Guice 4 + EclipseLink 2.6.0
TweetPosted on Tuesday Aug 04, 2015 at 07:26PM in Technology
I wrote a Lean example of Tomcat 8 + Guice 4 in previous entry. this time, I’ll try JPA(EclipseLink) integration with automatic transaction management.
The entire project which based on Maven can be obtained from My GitHub repository.
Prerequisites
For database connection, we’ll use a DataSource which is defined on Tomcat server. to define a Embedded Derby DataSource, This entry would help.
Dependencies
<dependencies> <dependency> <groupId>javax.servlet</groupId> <artifactId>javax.servlet-api</artifactId> <version>3.1.0</version> <scope>provided</scope> </dependency> <dependency> <groupId>org.eclipse.persistence</groupId> <artifactId>eclipselink</artifactId> <version>2.6.0</version> </dependency> <dependency> <groupId>com.google.inject</groupId> <artifactId>guice</artifactId> <version>4.0</version> </dependency> <dependency> <groupId>com.google.inject.extensions</groupId> <artifactId>guice-servlet</artifactId> <version>4.0</version> </dependency> <dependency> <groupId>com.google.inject.extensions</groupId> <artifactId>guice-persist</artifactId> <version>4.0</version> </dependency> </dependencies>
web.xml
No changes against previous entry except addition of resource-ref
element.
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd" version="3.1"> <!-- taken from https://github.com/google/guice/wiki/Servlets --> <listener> <listener-class>guice.tomcat.MyGuiceServletConfig</listener-class> </listener> <filter> <filter-name>guiceFilter</filter-name> <filter-class>com.google.inject.servlet.GuiceFilter</filter-class> </filter> <filter-mapping> <filter-name>guiceFilter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> <resource-ref> <res-ref-name>jdbc/derby</res-ref-name> <res-type>javax.sql.DataSource</res-type> <res-auth>Container</res-auth> </resource-ref> </web-app>
META-INF/persistence.xml
If you don’t want to use a DataSource on Tomcat, specify the connection information in javax.persistence.jdbc.*
properties instead of non-jta-data-source
.
<?xml version="1.0" encoding="UTF-8"?> <persistence version="2.1" xmlns="http://xmlns.jcp.org/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/persistence http://xmlns.jcp.org/xml/ns/persistence/persistence_2_1.xsd"> <persistence-unit name="myJpaUnit" transaction-type="RESOURCE_LOCAL"> <provider>org.eclipse.persistence.jpa.PersistenceProvider</provider> <non-jta-data-source>java:comp/env/jdbc/derby</non-jta-data-source> <class>guice.tomcat.MyEntity</class> <properties> <property name="eclipselink.ddl-generation" value="drop-and-create-tables"/> <property name="eclipselink.logging.level" value="FINE"/> <property name="eclipselink.logging.level.sql" value="FINE"/> </properties> </persistence-unit> </persistence>
MyGuiceServletConfig.java
The last two statements will take care of JPA integration.
public class MyGuiceServletConfig extends GuiceServletContextListener { @Override protected Injector getInjector() { return Guice.createInjector(new ServletModule() { @Override protected void configureServlets() { serve("/*").with(MyServlet.class); bind(MyService.class).to(MyServiceImpl.class); install(new JpaPersistModule("myJpaUnit")); filter("/*").through(PersistFilter.class); } }); } }
MyEntity.java
This is a very simple JPA entity which keeps only generated id
and ts
(a timestamp).
@Entity @NamedQuery(name = "MyEntity.findAll", query = "SELECT e FROM MyEntity e ORDER BY e.id DESC") public class MyEntity implements Serializable { @Id @GeneratedValue private Long id; @Column(nullable = false) @Temporal(TemporalType.TIMESTAMP) private Date ts; ... accessors are omitted
Service class
MyService.java
public interface MyService { void save(MyEntity e); List<MyEntity> findAll(); }
MyServiceImpl.java
Note that you need to annotate a method with @com.google.inject.persist.Transactional
if you need a transaction on it.
public class MyServiceImpl implements MyService { // Transactions doesn't start if EntityManager is directly injected via @Inject. // I have no idea why... // According to https://github.com/google/guice/wiki/JPA, // "Note that if you make MyService a @Singleton, then you should inject Provider<EntityManager> instead." @Inject private Provider<EntityManager> emp; @Override // @javax.transaction.Transactional is not supported yet. https://github.com/google/guice/issues/797 @com.google.inject.persist.Transactional public void save(MyEntity e) { EntityManager em = emp.get(); em.persist(e); } @Override public List<MyEntity> findAll() { return emp.get().createNamedQuery("MyEntity.findAll", MyEntity.class).getResultList(); } }
MyServlet.java
This servlet saves a MyEntity
with current timestamp, then fetches all of rows and returns them to the client on every request.
@javax.inject.Singleton public class MyServlet extends HttpServlet { @javax.inject.Inject private MyService myService; @Override public void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { MyEntity myEntity = new MyEntity(); myEntity.setTs(new Date()); myService.save(myEntity); PrintWriter writer = resp.getWriter(); writer.write("<html><body><ul>"); for(MyEntity e : myService.findAll()){ writer.write("<li>"); writer.write(e.toString()); writer.write("</li>"); } writer.write("</ul></body></html>"); } }
Test run
A row will be saved on every request as follows:
Tags: eclipselink guice jpa tomcat
Lean example of Tomcat 8 + Guice 4
TweetPosted on Monday Aug 03, 2015 at 06:56PM in Technology
I prefer Java EE stack usually, but I need to learn a Tomcat based stack for some reasons these days. in this entry, I introduce you a very simple example of Tomcat 8 + Guice 4 app which uses GuiceFilter
and GuiceServletContextListener
so that bring Guice to a Servlet based web application.
The entire project which based on Maven can be obtained from My GitHub repository.
Dependencies
<dependency> <groupId>javax.servlet</groupId> <artifactId>javax.servlet-api</artifactId> <version>3.1.0</version> <scope>provided</scope> </dependency> <dependency> <groupId>com.google.inject</groupId> <artifactId>guice</artifactId> <version>4.0</version> </dependency> <dependency> <groupId>com.google.inject.extensions</groupId> <artifactId>guice-servlet</artifactId> <version>4.0</version> </dependency>
web.xml
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd" version="3.1"> <listener> <listener-class>guice.tomcat.MyGuiceServletConfig</listener-class> </listener> <filter> <filter-name>guiceFilter</filter-name> <filter-class>com.google.inject.servlet.GuiceFilter</filter-class> </filter> <filter-mapping> <filter-name>guiceFilter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> </web-app>
MyGuiceServletConfig.java
We need to declare servlet mappings and the mappings between interfaces and implementations here.
public class MyGuiceServletConfig extends GuiceServletContextListener { @Override protected Injector getInjector() { return Guice.createInjector(new ServletModule() { @Override protected void configureServlets() { serve("/*").with(MyServlet.class); bind(MyService.class).to(MyServiceImpl.class); } }); } }
Service class
We use a pair of a very simple implementation of a service class. it simply creates a greetings which uses an argument.
MyService.java
public interface MyService { String hello(String name); }
MyServiceImpl.java
public class MyServiceImpl implements MyService { @Override public String hello(String name) { return "Hello, " + name; } }
MyServlet.java
Note that we use @javax.inject.Singleton
and @javax.inject.Inject
annotations, that are standardized JSR API.
@javax.inject.Singleton public class MyServlet extends HttpServlet { @javax.inject.Inject private MyService myService; @Override public void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { resp.getWriter().write(myService.hello("Guice")); } }
Test run
After deployment, send a request to check the response:
$ curl http://localhost:8080 Hello, Guice
Other things/functions need to be studied
-
Transaction management
-
CDI Producer equivalent
-
AOP
-
Automatic implementation scanning/binding
Purchased book list in O'Reilly's 60% off sale
TweetPosted on Thursday May 07, 2015 at 05:34PM in Technology
Total: $170.38 USD
-
SQL and Relational Theory, 2nd Edition
-
CSS Secrets
-
Professional Java EE Design Patterns
-
Java Performance: The Definitive Guide
-
Java 8 Lambdas
-
Java Cookbook, 3rd Edition
-
Learning Java, 4th Edition
-
RESTful Java with JAX-RS 2.0, 2nd Edition
-
Continuous Enterprise Development in Java
-
Head First Servlets and JSP, 2nd Edition
-
Head First HTML and CSS, 2nd Edition
Configuring Apache James to use PostgreSQL as the backend
TweetPosted on Sunday Apr 19, 2015 at 09:37PM in Technology
UPDATE: I’m running into a strange problem of using PostgreSQL as backend with Thunderbird. I recommend to use an other database as the backend at the moment. http://www.mail-archive.com/server-user%40james.apache.org/msg14715.html
UPDATE2: I created a patch to solve the issue and it seems fine. for detail and download the patch see: https://issues.apache.org/jira/browse/MAILBOX-228
I have been used Apache James with Embedded Derby, but its CPU/IO consumption is increasing day by day. I’m not sure where is the bottleneck but I decided to move to PostgreSQL as its backend anyway.
-
Put JDBC driver (I used
postgresql-9.3-1100.jdbc41.jar
) into$JAMES_HOME/conf/lib
-
Create
james-database.properties
from template, and put it into$JAMES_HOME/conf
as followsdatabase.driverClassName=org.postgresql.Driver database.url=jdbc:postgresql://127.0.0.1:5432/james database.username=james database.password=*** vendorAdapter.database=POSTGRESQL openjpa.streaming=true
-
Restart James instance
-
Create domains, addresses and aliases:
./james-cli.sh -h localhost -p 9999 adddomain example.org ./james-cli.sh -h localhost -p 9999 adduser kyle@example.org *** ./james-cli.sh -p 9999 -h localhost addaddressmapping postmaster example.org kyle@example.org
Note
This guide claims that setting standard_conforming_strings=off
is needed, but I guess this issue may address this problem, so I don’t use this setting at the moment. my James installation is shipped with openjpa-2.2.1.jar
and the issue was fixed in 2.2.0
.