Spring and Hibernate in GlassFish
Few days back, Matt Raible complained in his blog that
Spring and Hibernate do not work in GlassFish. Being the GlassFish
architect, he sparkled my interest ;-) Since I am always in for a good
technical challenge, I decided to prove him wrong :
Part 1 : Spring
Here I am going to demonstrate the following :
- how to get the
Spring binaries
- how to install them in the application
- demonstrate how the Spring tutorial can work with the GlassFish/Spring
combination.
First of all, go to the Spring
website and download the latest version 1.2.6, I chose the fat download
with all bunch of dependency jar files you will probably never need but
at least, you are sure to have what you need.
Now, as I mentioned, I decided to try to run the Tutorial application
which is also found on the Spring website. This is the
link
to the original tutorial, find below the updated instructions targeted to
GlassFish, you will still need to reference the original article as I
don't repeat everything...
Also, because I am not a big fan of
complicated build scripts and being naturally lazy, I decided to use
Netbeans 5.0 as my development tool. You can adapt the tutorial scripts to
work with GlassFish if you prefer command line interfaces. Also, GlassFish
has a plug in for Eclipse so you should be able to easily translate this
effort for Eclipse (and maybe post the instructions as a comment...)
Next
thing to do, go get yourself the
NetBeans
5.0 RC2 and install it. Once you have done that, go get the latest
GlassFish build, here I am using
Build35.
Install it in say $home/glassfish :
simplified instructions to
install glassfish :
jar -Xmx256m -jar glassfish<>.jar
cd glassfish
ant -f setup.xml
Now reading
from the Spring tutorial
steps,
all you need to make your Spring app work are three files located in the
unzipped distribution we downloaded earlier
-
dist/spring.jar
-
lib/jakarta-commons/commons-logging.jar
-
lib/log4j/log4j-1.2.9.jar
To simplify things, I will make Spring available to the entire application
server installation, which mean that all domains will have access to it
and applications will not be required to bundle these jars inside their
war files.
To do that, just copy the above three files in your
glassfish installation lib directory ($home/glassfish/lib) and you are
done ! I will explain later how you can actually restrict this to a
particular domain or even a particular application.
So now you can
start NetBeans 5.0 and add the Glassfish server to it :Tools Menu, Server
Manager, Add Server

Once
you have added the server to NetBeans, you can actually start GlassFish.
Now
let's build our first Spring application ! The Spring Tutorial steps1 to 4
is just about building a simple WebApplication with a .jsp file. In
NetBeans, it is very easy to do that in a couple of clicks :
-
From the file menu, choose "New Project"
-
Choose Web Category
-
Choose Web Application, Click Next
-
Call you new project springapp, ensure that "Sun Java System
Application Server" is the targeted server
-
Click Finish
Select Web Pages, right-click and add a new JSP hello.jsp with this
content :
<html>
<head><title>Example :: Spring Application</title></head>
<body>
<h1>Example - Spring Application</h1>
<p>This is my test.</p>
</body>
</html>
Now you have your project opened, From the Run Menu, select "Run Main
Project" you should see your browser showing you a "Hello World" type of
page if you browse index.jsp (given by Netbeans for free) or hello.jsp
At
this point you are done with step 1 to 5 of the Spring Tutorial,
without
typing a line of code or script...
On to Step 6, add the following
<servlet>
<servlet-name>springapp</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>springapp</servlet-name>
<url-pattern>*.htm</url-pattern>
</servlet-mapping>
to your WEB-INF/web.xml, you can either use the nice UI or you can select
XML category on top of your editor to have direct access to the XML
content.

Step
7, add you springapp-servlet.xml to the WEB-INF directory
Step 8,
add the SpringappController java class to the "Source Packages" category
of your project.
Now your IDE should look like this

Something
interesting here : With red underlining, NetBeans is telling you that the
first two imports are illegal and that's because NetBeans does not know
anything about the Spring Framework. Let's fix that :
-
Tools menu, select Library Manager
-
Add a new Library, call it "Spring"
-
Add the 3 Jars we copied to $home/glassfish/lib
Done with adding the new Library, now change your project properties to
add the new Spring library...
-
Right click on your "springapp"
-
Select Librairies, Add Library
-
Select Spring Library from the list
Now when netBeans is done scanning the new jar, those red lines under the
import statements should disappear...
Time to rebuild and deploy to
check we are right on course with Step 11.
Step 12 : create a view
From
the "Web Pages" sub element of your springapp project, select "new" and in
the wizard, select "other" and "empty file", call this new file "hello.jsp"
<html>
<head><title>Example :: Spring Application</title></head>
<body>
<h1>Hello - Spring Application</h1>
<p>Greetings.</p>
</body>
</html>
Change the controller to now handle this new view :
import org.springframework.web.servlet.mvc.Controller;
import org.springframework.web.servlet.ModelAndView;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
public class SpringappController implements Controller {
/** Logger for this class and subclasses */
protected final Log logger = LogFactory.getLog(getClass());
public ModelAndView handleRequest(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
logger.info("SpringappController - returning hello view");
return new ModelAndView("hello.jsp");
}
}
Run the project and you should get something like this when browsing
http://localhost:8080/springapp/hello.htm

On
to Step 13, there is a mistake in the Spring Framework tutorial, It
specifies that you need to change the include.jsp like this
<%@ page session="false"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jstl/core" %>
<%@ taglib prefix="fmt" uri="http://java.sun.com/jstl/fmt" %>
In fact, it should be
<%@ page session="false"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ taglib prefix="fmt" uri="http://java.sun.com/jstl/fmt" %>
Otherwise you can basically continue until step 16 and get the same
results...
Ok, I think I have made my point : Spring runs
unmodified in the unmodified GlassFish freshly downloaded from our web
site.
Part 2 : Hibernate
For hibernate, things are a little more complicated depending on what
youwant to do :
-
Use Hibernate APIs from a EJB Session bean, this is working since Sun
Java System Application Server 8.1 and well documented here
This
integration is however far from complete as far as the
TransactionManager is concerned
-
Use Hibernate as an EJB3 Persistence Provider :
This is not easy to
make it work but doable, I have been working with Emanuel Bernard
(ah.. the french connection, always easier) to get this done and he
will be updating his wiki page
with steps. The reason why this is not easily working is that both
products are in active development and the windows for integration are
not always overlapping. This will get resolved in the next day or so
and I will publish a new blog. Today, what you have to do is described
in another Hibernate wiki.
So running Hibernate in GlassFish is today difficult, granted but we are
working hard to change this and you should hear soon when the integration
will be completed. Now remember that we have a persistence provider in
GlassFish (TopLink) which will allow you to start working with Spring+EJB3
Persistence. You may not have the persistence provider you want today but
Emmanuel and I will ensure that we will provide a easy solution very soon.
You can also follow Sahoo's
blog
for updated information.
Conclusion
Well, in all honesty, Matt had asked for some help on the glassfish forum
and he did not get a satisfying answer which probably led him to believe
that it just does not work but I hope I have dismissed all
misunderstandings, we support Spring and Hibernate, we will work closely
with all willing Open Source communities to integrate each others
technologies. Finally, I hope that we will get more and more folks excited
about GlassFish.
Post Script-um :
In his
attempt
to run Spring in the GlassFish application server, Matt got into trouble
with the SecurityManager. What he did was probably to cobundle the Spring
archives within his war files. I know some folks love to do that, but
honestly this is not the right way of integrating framework libraries in
any application server. My approach described above made the framework
available to all the deployed applications. If you want to restrict its
availability to a particular domain, just copy the 3 jars files in your
domain/lib directory (like$user/glassfish/domains/domain1/lib) and edit
your server.policy to not get into the same issue than Tom :
grant
codeBase "file:${com.sun.aas.installRoot}/domains/domain1/lib/spring.jar" {
permission java.security.AllPermission;
};
Same
solution (with a different path) can be applied for jar files that are
bundled within your war file, this is actually documented
here.