Friday May 16, 2008
Riddles with EJB 3.1
EJB 3.1 aims to further simplify EJB programming model, introducing a series of new features like no-interface local view, .war file packaging, singleton bean, cron-like schedule-based timer, asynchronous invocation, etc. Some of them have already been implemented by GlassFish V3. Ken's blog has more details on many proposed new features in EJB 3.1. Mahesh from GlassFish EJB container team gave a preview of EJB 3.1 container in GlassFish v3 TP2. In this post, I will share a riddles webapp to showcase the use of certain EJB 3.1 features and how they interact with web-tier components like Servlet, JSP, and JSTL.
1, Download GlassFish V3 Technology Preview 2 (TP2) at GlassFish download page. See the installation instructions for installation steps, and the Quick Start Guide to get up and running quickly.
For NetBeans 6.1 users, this can be completely automated with GlassFish V3 plugin (see ludo's blog). Eclipse plugin for GlassFish V3 TP2 is also available (see Arun's blog).
2. Install EJB container on top of V3 TP2 by running <glassfish_home>/bin/updatetool. Follow on-screen instructions, and choose to install glassfishv3-ejb from Available Add-ons.
3. Start V3 TP2 by running <glassfish_home>/bin/asadmin start-domain, or from within NetBeans or Eclipse.
4. Create a webapp named riddles. The exact steps vary depending on IDE, but it simply contains:
The stateless bean class RiddleBean is annotated with @Stateless but implements no interfaces. All public methods (only getRiddle method in this case) in the bean class and its superclasses are exposed as business methods. @PostConstruct method is invoked after the bean instance is created and before any business method invocation. It initializes riddle data in classpath with class.getResourceAsStream().
@Stateless
public class RiddleBean {
public Riddle getRiddle() {
String data = riddleData[rand.nextInt(riddleData.length)];
return new Riddle(data);
}
@PostConstruct
private void postConstruct() {
//read riddle data with getResourceAsStream
}
RiddleServlet acts as the client of RiddleBean EJB, a reference of which is injected into RiddleServlet. With no-interface local view, the client references EJB with its bean class type. But the client must still obtain the reference either through injection or lookup, not new operator.
The servlet does not create any response; it merely sets the injected bean reference into application scope so that it is available for JSP pages. The purpose is to demonstrate the use of @EJB injection. Alternatively, this servlet can be replaced with a context listener or filter, or totally removed by declaring <ejb-ref> in web.xml.
public class RiddleServlet extends HttpServlet {
@EJB private RiddleBean riddleBean;
protected void processRequest(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
getServletContext().setAttribute("riddleBean", riddleBean);
getServletContext().getRequestDispatcher("/riddle.jsp"
.forward(request, response);
}
riddle.jsp shows how easy it is to invoke EJB methods with JSP expression language (EL) , without using any java code. The expression ${riddleBean.riddle} has the same effect as calling riddleBean.getRiddle(). The return vaue, a value object of type Riddle, is stored as riddle in page scope.
<c:set var="riddle" value="${riddleBean.riddle}" scope="page" />
... ...
<p><h4>Q: ${riddle.question}</h4></p>
<p><h4>A: ${riddle.answer}</h4></p>
In your project, EJB source files reside in the same place as servlet and other web component classes. With .war packaging, EJB classes can be packaged under WEB-INF/classes or inside a jar file under WEB-INF/lib, just like any other .war classes. It's no different than an ordinary .war, with no EJB interfaces (not even local business interface), no ejb-jar.xml, no ejb-jar, and no EAR. This is the content of the war file after building the project:
WEB-INF/classes/riddle/Riddle.class
WEB-INF/classes/riddle/RiddleBean.class
WEB-INF/classes/riddle/RiddleServlet.class
WEB-INF/web.xml
riddle.jsp
As for the riddle data file riddles.txt, you can package it inside the .war as WEB-INF/classes/riddles.txt. Or you can jar it up as riddles.jar and copy riddles.jar to $GLASSFISH_HOME/domains/domain1/lib. Any jars in this directory will be made available to all apps in domain1. In GlassFish V2, I used to directly copy classes and resources to domain1/lib/classes without the wrapper jar, but this doesn't seem to be supported yet. riddles.txt must follow certain format to be parsed properly (A: Q: %):
FORTUNE PROVIDES QUESTIONS FOR THE GREAT ANSWERS:
A: To be or not to be.
Q: What is the square root of 4b^2?
%
In my Ubuntu machine, I just use /usr/share/games/fortunes/riddles file. riddles.war with sample riddles can be downloaded here.
5. Deploy riddles.war using autodeploy or asadmin deploy:
cp riddles.war $GLASSFISH_HOME/domains/domain1/autodeployor
$GLASSFISH_HOME/bin/asadmin deploy riddles.war
Optionally, verify that the .war is deployed with
$GLASSFISH_HOME/bin/asadmin list-components
6. Play riddles with EJB 3.1 at http://localhost:8080/riddles/

Posted at 05:43PM May 16, 2008 by chengfang in Glassfish | Comments[0]
Friday March 28, 2008
An inbound UDP from 129.33.82.52
This morning, my Symantec client firewall popped up this warning:
A remote system is attempting to access Microsoft Generic Host Porcess for Win32 Services on your computer.
Program: svchost.exe
Path: C:\WINDOWS\system32\
Protocol: UDP (Inbound)
Remote Address: 129.33.82.52 : 1421

Symantec recommended to permit always. Just to be safe, I clicked Block Once. Then there came another UDP from a different host/port in the same subnet: 129.33.82.51 : 1211. After clicking Block Once again, another UDP from 129.33.82.50 : 1211.
Whois search (http://cqcounter.com/whois/) result for these hosts:
IP Address : 129.33.82.52 [ testws001.boulder.mebs.ihost.com ]
ISP : IBM
Organization : IBM
Location :US, United States
City : Durham, NC 27709
Latitude : 35°91'38" North
Longitude : 78°84'89" West
Last evening, I was trying to download Thinkpad upgrades from ibm website in another machine. That might have been the cause for these UDP requests. After blocking them, I haven't seen any side-effects yet. So I think it's safe to do so.
Posted at 10:01AM Mar 28, 2008 by chengfang in Other | Comments[0]
Tuesday March 25, 2008
JavaEE 5 API Javadoc in Chinese Now Available
J2EE and JavaEE API Chinese javadocs has been one of the most requested feature. Now it's available, according to Glassfish Aquarium_zh.
You can go directly to http://doc.java.sun.com/DocWeb/, select JavaEE 5 SDK from the list at upper-left, select Chinese (Simplified) at upper-right. JavaEE API classes are then listed on the left. You can browser alphabetically, or find by class name (e.g., EJBContext, ServletContext).
If you only see English method signatures, just click the little orange Show All button at upper right to display all Chinese docs that are collapsed by default.
Posted at 02:44PM Mar 25, 2008 by chengfang in Glassfish | Comments[2]