Enterprise Java Technologies Tech Tips
Tips, Techniques, and Sample Code
Welcome to the Enterprise Java Technologies Tech Tips for
May 26, 2007. Here you'll get tips on using enterprise
Java technologies and APIs, such as those in Java Platform,
Enterprise Edition (Java EE).
This issue covers:
* Using Annotations in Web Applications
* How to Get the Best Performance Out of a Java
Persistence Implementation
The Using Annotations in Web Applications tip was developed
using the NetBeans IDE and the Java EE 5 SDK. NetBeans IDE 5.5
with the NetBeans Enterprise Pack 5.5 is available in Java EE 5
SDK Update 2, which you can download from the Java EE Downloads
Page
(http://java.sun.com/javaee/downloads/index.jsp).
The How to Get the Best Performance Out of a JPA Implementation
tip was developed using an open source reference implementation
of Java EE 5 called GlassFish. You can download GlassFish from
the GlassFish Community Downloads page
(http://java.sun.com/javaee/glassfish/getit.jsp).
You can view this issue of the Tech Tips on the Web at
http://java.sun.com/mailers/techtips/enterprise/2007/TechTips_May07.html
You can download the sample archive for the tip Using
Annotations in Web Applications at:
http://java.sun.com/mailers/techtips/enterprise/2007/download/ttmay2007webann.zip.
You can download the sample archive for the tip How to Get the
Best Performance Out of a JPA Implementation at:
http://java.sun.com/mailers/techtips/enterprise/2007/download/ttmay2007JPAper.zip.
Any use of this code and/or information below is subject to the
license terms at
http://developers.sun.com/dispatcher.jsp?uid=6910008.
See the Subscribe/Unsubscribe note at the end of this newsletter
to subscribe to Tech Tips that focus on technologies and products
in other Java platforms.
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
USING ANNOTATIONS IN WEB APPLICATIONS
by Shing Wai Chan
Java EE 5 introduced annotations, a way to simplify the
development and configuration of enterprise applications. The
March 31, 2007 Tech Tip "Using Security Annotations in
Enterprise Beans"
(http://java.sun.com/mailers/techtips/enterprise/2007/TechTips_March07.html)
showed how you can use annotations to simplify the development
of secure applications that use enterprise beans. Some of the
annotations in Java EE 5 are specific to web applications.
Examples of this type of annotation are @Resource, @EJB, and
@WebServiceRef. Other annotations, such as @RunAs and
@DeclareRoles, are related to security. The security-related
annotations were introduced in the "Using Security Annotations
in Enterprise Beans" tip.
Although you can specify annotations in various web application
components, you can't specify an annotation in a JavaServer
Pages (JSP) technology page. However, annotations are supported
in web libraries. This means that you can specify annotations in
tag libraries and servlet filters, among other places. This
gives you a way of securing JSP pages and servlets, provided
that you take one additional action: you need to specify
appropriate security information in the web.xml file for the web
application.
This tip shows you how to construct a secure web application
that includes servlets and JSP pages. By configuring the web.xml
file for the web application, you can protect the servlets and
JSP pages over a Secure Sockets Layer connection. This is
a common security approach in a web production environment.
A sample web application package
(http://java.sun.com/mailers/techtips/enterprise/2007/download/ttmay2007webann.zip)
accompanies the tip. The code examples in the tip are taken from
the source code of the sample (which is included in the package).
The Servlet
Let's begin by examining the servlet for the web application. In
this example, the servlet invokes an enterprise bean (in this
case, a stateless session bean) with a local interface
SlessLocal. The servlet passes a message object as a request
attribute and then forwards it to a JSP page, display.jsp, for
display. Here is the major part of the code for the servlet:
@DeclareRoles({"arole"})
@RunAs("myrole")
public class TestServlet extends HttpServlet {
private @EJB SlessLocal slessLocal;
public void service(
HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
if (req.isUserInRole("arole")) {
String message = slessLocal.hello("World");
req.setAttribute("EJB_MESSAGE", message);
}
RequestDispatcher rd =
req.getRequestDispatcher("display.jsp");
rd.forward(req, resp);
}
}
The @EJB annotation is used to look up an enterprise bean with
the corresponding interface so that the bean can be used by the
servlet. The @DeclareRoles annotation defines the role to be
used by HttpServletRequest.isUserInRole(String role). The
isUserInRole method determines whether the authenticated user is
included in the specified role. In this case, only a user in the
role "arole" will cause the servlet to retrieve the "message"
String and set it as an HttpServletRequest attribute.
The @RunAs annotation specifies that the role "myrole" should be
used to access the enterprise bean method
SlessLocal.hello(String message).
The Enterprise Bean
Here is the major part of the code for the stateless session
bean:
@Stateless
@Local({SlessLocal.class})
public class SlessBean implements SlessLocal {
@RolesAllowed(value={"myrole"})
public String hello(String message) {
return "Hello, " + message + ", " + new Date();
}
}
Notice that the hello method is protected through the use of
the @RolesAllowed annotation. The annotation specifies that only
authenticated users in the role "myrole" can access the hello
method.
The JSP and Tag Library
The JSP page, display.jsp, invokes an action in a JSP tag
library and passes the attribute EJB_MESSAGE as a parameter in
the HttpServletRequest. Here is a snippet of code from the JSP
page:
<%@taglib prefix="di"
uri="http://java.sun.com/techtip/webann/test-taglib"%>
...
...
The tag handler for the tag reads the value of the ejbMessage
parameter and displays it in HTML. It also prints the login
timeout for the DataSource. Here is the pertinent code in the
tag handler:
public class DisplayInfoTagHandler extends SimpleTagSupport {
private @Resource(name="jdbc/__default") DataSource ds;
...
public void doTag() throws JspException, IOException {
try {
JspWriter out = getJspContext().getOut();
int timeout = ds.getLoginTimeout();
if (ejbMessage != null && ejbMessage.length() > 0)
{
out.println(
"
Ejb Message: " + ejbMessage);
}
out.println(
" DataSource login timeout: " + timeout);
...
}
public void setEjbMessage(String ejbMessage) {
this.ejbMessage = ejbMessage;
}
}
The @Resource annotation in the tag handler is used to look up
the DataSource with the JNDI name, "jdbc/__default". This JNDI
name corresponds to the default Derby database. If you want to
access the database connection, you could add ds.getConnection()
to the code in the tag handler.
Notice too that the tag handler defines a setter method for the
parameter ejbMessage.
Securing the Servlet and JSP page
This example takes the approach of protecting the war file
for the application by requiring a username and password and by
using SSL in the transport layer. The username and password is
sent in clear text over the wire. There is no need to modify any
Java code or JSP page in the application. To secure the servlet
and JSP page in the application all you need to do is configure
the web.xml file as follows:
1. Define a security constraint by specifying
a element. This protects
a corresponding URL so that a given role can access it. Note
that you can define one or more HTTP methods that the
security constraint applies to by specifying
elements in the security constraint. If you want the security
constraint element to apply to all HTTP methods, you simply
omit the elements.
2. Indicate that SSL will be used for communication. You do this
in the security constraint by specifying a
element and within it
a element. Set the value of the
element to CONFIDENTIAL.
3. Set the authentication method. You do this by specifying an
element and within it an
element. Set the value of the to BASIC.
Here is a snippet of the web.xml file:
Servlet Application
/*
ttrole
CONFIDENTIAL
BASIC
default
ttrole
In this example, only users of role "ttrole" can access the
servlet and JSP page. Furthermore, only users who are also
of role "arole" will cause the SlessLocal bean to be called.
The Java EE environment uses roles for authorization. However in
many operating system environments, users are associated with
groups. The security-role-mapping provides a link between the
concepts of user roles and principals/groups. In a Java EE 5
application server implementation such as the Sun Java System
Application Server in the Java EE 5 SDK, you define the
security-role-mapping in the sun-application.xml file. Here is
an example:
myrole
myuser
ttrole
ttgroup
arole
ttuser
Running the Sample Code
1. If you haven't already done so, download and install the
NetBeans IDE. NetBeans IDE 5.5 with the NetBeans Enterprise
Pack 5.5 is available in Java EE 5 SDK Update 2, which you
can download from the Java EE Downloads Page
(http://java.sun.com/javaee/downloads/index.jsp).
2. Download the sample package for the tip
(http://java.sun.com/mailers/techtips/enterprise/2007/download/ttmay2007webann.zip)
and extract its contents. You should now see the newly
extracted directory as /webann, where
is the directory where you installed the
sample package. For example, if you extracted the contents to
C:\ on a Windows machine, then your newly created directory
should be at C:\webann
3. Start the NetBeans IDE.
4. Open the webann project. If you see a "Resolve missing server
problem" message, then the application server has not added
to the server list in NetBeans. Select Tools > Server Manager
to add the server to the server list.
5. Start the Sun Java System Application Server in NetBeans.
You can also start the application server by entering the
following command on the command line:
/bin/asadmin start-domain domain1
where is the directory in which you
installed the Sun Java System Application Server.
6. Create a user. You can do this in the Admin Console
(default: http://localhost:4848 ) as follows:
o Navigate the left panel of the Admin Console:
Configuration > Security > Realms > file,
o Click "Manage Users" and then click "New".
o Enter the following information:
User Id: ttuser
Group List: ttgroup
New Password: ttpassword
Confirm New Password: ttpassword
o Click "OK".
After creating the user, create a second user in the same
group by entering the following:
User Id: ttuser2
Group List: ttgroup
New Password: ttpassword
Confirm New Password: ttpassword
7. Build the project as follows:
o Right click the webann node in the Projects window.
o Select "Clean and Build Project".
This builds an ear file, web.ear, and puts it in the
webann/dist directory.
8. Deploy the ear file as follows:
o Right click the webann node in the Projects window.
o Select "Deploy Project".
You can also deploy the ear file through the Admin Console
as follows:
o Navigate the left panel of the Admin Console:
Applications > Enterprise Applications
o Click "Deploy".
o Click the "Browse" button to find the ear file.
o Click OK.
You can also deploy the ear file by entering the following
command on the command line:
asadmin deploy webann.ear
9. Start the application by pointing your browser to
https://:/webann, where is the host name
of your application server, for instance "localhost", and
is your HTTPS port, for instance, 8181.
Depending on your browser, you might see a message stating
that there is a problem with the web site's security
certificate or web site certified by an unknown authority.
That's because this example uses a self-sign certificate.
The browser should offer you the option of continuing to the
web site to start the application.
The application will then prompt you to login. Recall that
you created two users: ttuser and ttuser2. If you login as
ttuser, you should see a response from the application that
looks similar to the following:
Hello, ttuser
Ejb Message: Hello, World, Sat Jun 30 12:04:46 PDT 2007
DataSource login timeout: 0
If you login as ttuser2, then you should see a response
similar to the following:
Hello, ttuser2
DataSource login timeout: 0
The difference in the response is due to the roles for each
user. The user ttuser has roles "ttrole" and "arole". The
user ttuser2 has the role "ttrole", but not the role "arole".
In this application, only users that have the role "arole"
are authorized to invoke the method
SlessLocal.hello(String message), the method that creates the
"Hello, World" message.
When you finish the application, you can undeploy it and remove
the users you created as follows:
1. Undeploy the ear through the Admin Console as follows:
o Navigate the left panel of the Admin Console:
Applications > Enterprise Applications
o Choose "webann" and then click "Undeploy".
2. Remove the user through the Admin Console as follows:
o Navigate the left panel of the Admin Console:
Configuration > Security > Realms > file
o Click "Manage Users".
o Choose "ttuser" and "ttuser2".
o Click "Delete".
About the Author
Shing Wai Chan is a member of the Java EE development team
at Sun Microsystems. He has been a key contributor in Java EE
security for the past few years.
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
HOW TO GET THE BEST PERFORMANCE OUT OF A JAVA PERSISTENCE
IMPLEMENTATION
by Rahul Biswas
The Java Persistence API, or simply Java Persistence,
introduced in the Enterprise JavaBeans (EJB) 3.0 specification
(JSR 220), simplifies the development of Java EE applications
that use data persistence. Earlier Tech Tips, such as
"Converting a POJO to a Persistent Entity"
(http://java.sun.com/developer/EJTechTips/2005/tt1122.html#2),
"Inheritance and the Java Persistence API"
(http://java.sun.com/mailers/techtips/enterprise/2006/TechTips_June06.html#2),
and "Using Java Persistence With JavaServer Faces Technology"
(http://java.sun.com/mailers/techtips/enterprise/2006/TechTips_Nov06.html#1),
covered various aspects of the Java Persistence API. This tip
discusses how to tune the Java Persistence implementation
in GlassFish called Toplink Essentials.
The example included in this tip is based on the customer-cmp
sample bundled with GlassFish. You can download the samples from
the GlassFish Samples page
(http://glassfish-samples.dev.java.net). The tip covers
performance tuning for a Java Persistence implementation used in
different modes: in-container and out-of container. The tip also
uses the Faban framework to demonstrate different performance
tuning parameters.
Before discussing the tuning parameters, let's examine
in-container and out-of container modes and the Faban framework.
Two Modes of Running a Java Persistence Implementation
You can use Java Persistence implementations that are compliant
with JSR-220 in either of two modes: in-container and
out-of-container. This is a marked difference between
earlier enterprise Java Persistence implementations such as
container-managed persistence in EJB 2.1. With EJB 2.1
container-managed persistence a Java Persistence implementation
could only run using in-container mode.
In-container mode means that the Java Persistence implementation
is used inside of an EJB container. EntityManagers, objects
that manage persistence entities, are usually created by the
EJB container. Entity managers are typically JTA entity
managers. In other words, they participate in transactions
controlled by the Java Transaction Architecture (JTA). However,
the Java Persistence implementation must support both JTA entity
managers and resource-local entity managers, that is, entity
managers that participate in transactions not managed by JTA.
In out-of-container mode the Java Persistence implementation is
either standalone or runs inside of a web container. The
application is responsible for creating it's own entity
managers. Transactions are usually resource-local. If the
implementation runs standalone, it does not need to support JTA.
The Faban Driver Framework
Faban is an open-source driver framework. It lets developers
focus on driver logic implementation so that they can quickly
develop performance drivers. Faban takes care of common tasks
such as load-generation, output formatting, and the timing of
operations. For more about the Faban, see the Faban project
page (http://faban.sunsource.net).
Tuning the Sample Application
The customer-cmp sample application interacts with a relational
database to store and display information about customer
subscriptions to periodicals. The database stores information
such as a customer's name and address, as well as the type of
periodical to which the customer is subscribed -- that is,
magazine, journal, or newspaper. Users can submit requests to
the application to display subscription-related information.
This tip focuses on one of the operations supported by the
application: finding a customer by his or her ID.
Changing the Cache Size and Number of Connection Pools
Let's examine the impact that specific tuning parameters have
on the combined throughput of these operations. Specifically,
let's examine the impact of changing the cache size in Toplink
Essentials and resetting the number of connections in the
connection pool in GlassFish for database calls.
The Toplink Essentials implementation has a default cache size
of 1000 per entity. For the purpose of demonstrating the effect
of the cache setting, let's look at the transaction rate using
the default cache size. Then let's change the cache size to 5000
and compare the results.
To set the cache size, you need to update the persistence.xml
file in your project and set the toplink.cache.size.default
property as follows:
In this example, there are 20,0000 customer entities in the
database.
The cache setting applies to both in-container and
out-of-container modes. The connection pool setting, however, is
handled differently depending on whether you use in-container or
out-of-container mode. For In-container mode, the connection
pool setting is done in GlassFish and is controlled by the
data-source configuration. In this mode, you can configure the
connection pool using the GlassFish admin console as shown
below.
For in-container mode, set the number of connections in the
connection pool within the container to the number of request
processing threads configured in an instance of GlassFish (in
this case, 40). This is the maximum number of threads that can
be active at any time and thus the maximum number of connections
ever needed by Toplink Essentials for database calls.
For out-of-container mode, the connection pool setting is done
in the persistence.xml file. The Toplink Essentials
implementation has a default connection pool setting of eight
connections for both read and write connections. Let's run the
application in out-of-container mode for eight users, so set the
connection pool value to eight connections.
Results
Running Toplink Essentials using in-container mode produces
results similar to the following:
Cache Size Transactions/second
1000 (default) 1911.493
5000 3727.253
Running Toplink Essentials using out-of-container mode produces
results similar to the following:
Cache Size/ Transactions/second
Connection Pool
1000/default* 1456.153
5000/8 6510.0
* The default values are:
toplink.jdbc.read-connections.min = 2
toplink.jdbc.read-connections.max = 2
toplink.jdbc.write-connections.max = 10
toplink.jdbc.write-connections.min = 5
Note that when the default values are used, the connection pool
is initialized with the default min setting and can scale to
a maximum specified by the default max setting. By setting
a connection pool value of 8, there are always be eight
connections in the pool.
The system configurations for the tests are as follows:
Sun Fire V880, Solaris 10, 4 CPUs for System under test (SUT).
Sun Fire V880, Solaris 10, 12 CPUs for driver system.
Note that the driver and the SUT are the same system for the
out-of-container test. The Driver system and SUT have
a point-to-point ethernet connection, which means it has
no external network traffic.
Summary
To get the best performance out of your Java Persistence
implementation, it's important to understand the tuning
parameters provided by the implementation.
The cache setting is an important tuning parameter provided by
the Toplink Essentials implementation. Tuning the connection
pool setting provided by GlassFish is also important in getting
the best performance out of any Java Persistence implementation
used in GlassFish.
If you use a Java Persistence implementation outside of the EJB
container, the cache setting and connection pool setting again
play an important role in the performance of the implementation.
However, in this case you set the connection pool value in the
persistence.xml file.
There are other parameters that might impact the performance of
a Java Persistence implementation. One is the statement cache.
This needs to set explicitly for some databases such as an
Oracle database. The statement cache is turned on by default in
the Java DB database bundled with GlassFish.
In addition, your Java Virtual Machine (JVM)* settings can play an
important role in performance tuning. For detailed information
on JVM tuning, see the Java Tuning White Paper
(http://java.sun.com/performance/reference/whitepapers/tuning.html)
In running the application for this tip, the JVM options were
set to the following values:
-server -XX:+AggressiveHeap -Xmx2500m -Xms2500m -Xss128k
-XX:+DisableExplicitGC
* As used in this document, the terms "Java virtual machine" or
"JVM" mean a virtual machine for the Java platform.
For More Information
For more information about Java Persistence, see "The Java
Persistence API - A Simpler Programming Model for Entity
Persistence" (http://java.sun.com/developer/technicalArticles/J2EE/jpa/)
and the Java Persistence API FAQ
(http://java.sun.com/javaee/overview/faq/persistence.jsp).
For more information about Toplink Essentials, see "TopLink
Essentials - The Java Persistence API Implementation at
GlassFish" (https://glassfish.dev.java.net/javaee5/persistence/).
Running the Sample Code
To install and run the sample code that accompanies this tip:
1.If you haven't already done so, download GlassFish from the
GlassFish Community Downloads Page
(http://java.sun.com/javaee/glassfish/getit.jsp), and install
it.
2. Set the following environment variables:
o GLASSFISH_HOME. This should point to where you installed
GlassFish.
o ANT_HOME. This should point to where ant is installed. Ant
is included in the GlassFish bundle that you downloaded.
(In Windows, it's in the lib\ant subdirectory.)
o JAVA_HOME. This should point to the location of JDK 5.0 on
your system.
Add $JAVA_HOME/bin, $ANT_HOME/bin, and $GLASSFISH_HOME/bin to
your PATH environment variable.
3. Download the sample package and extract its contents. You
should now see the newly extracted directory as
/ttmay2007JPAper, where
is the directory in which you installed
the sample package. The samples directory below
ttmay2007JPAper contains the source files and other support
files for the sample.
4. Change to the samples/bp-project directory and edit the
build.properties file as appropriate. For example, if the
admin host is remote, change the value of admin.host from
the default (localhost) to the appropriate remote host. Also,
make sure that the javaee.server.passwordfile location is
correct.
5. Start GlassFish:
$GLASSFISH_HOME/bin/asadmin start-domain domain1
6. Change to the samples/javaee5/enterprise/customer-cmp-ear
directory and enter the following command:
ant start-db
7. Change to the
samples/javaee5/enterprise/customer-cmp-ear/setup directory
and enter the following commands:
ant create-db
ant setup
ant generate-data
ant configure-glassfish
8. To run the benchmark driver in various modes, change to the
samples/javaee5/enterprise/customer-cmp-ear/customer-cmp-driver
directory and enter the following commands:
In-container mode, non-optimized: ant run_inc_default
In-container mode, optimized: ant run_inc_optimized
Out-of-container mode, non-optimized: ant run_ooc_default
Out-of-container mode, optimized: ant run_ooc_optimized
The output of each run is stored in the
samples/javaee5/enterprise/customer-cmp-ear/customer-cmp-driver/output/${runid}
directory, where ${runid} is the id of each run displayed on
the console during the run. To see the results, view the
summary.xml file in that directory.
After the run is finished, you can undo the tuning settings.
Change to the
samples/javaee5/enterprise/customer-cmp-ear/setup directory
and enter the following command:
ant unconfigure_glassfish.
About the Author
Rahul Biswas is a member of the Java Performance Engineering group at Sun.
He is currently involved in the performance improvement of the persistence
implementation in GlassFish.
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
DEVELOPER ASSISTANCE
Need programming advice on Java EE? Try Developer Expert
Assistance
(http://developers.sun.com/services/expertassistance/)
. . . . . . . . . . . . . . . . . . . . . . .
Please read our Terms of Use and Licensing policies:
http://www.sun.com/share/text/termsofuse.html
http://developers.sun.com/dispatcher.jsp?uid=6910008
PRIVACY STATEMENT:
Sun respects your online time and privacy (http://sun.com/privacy).
You have received this based on your e-mail preferences. If you
would prefer not to receive this information, please follow the
steps at the bottom of this message to unsubscribe.
* FEEDBACK
Comments? Send your feedback on the Enterprise Java Technologies
Tech Tips to:
Enterprise_TechTips@sun.com
* SUBSCRIBE/UNSUBSCRIBE
Subscribe to other Java developer Tech Tips:
- Core Java Technologies Tech Tips. Get tips on using core
Java technologies and APIs, such as those in the Java 2
Platform, Standard Edition (J2SE).
- Wireless Developer Tech Tips. Get tips on using wireless
Java technologies and APIs, such as those in the Java 2
Platform, Micro Edition (J2ME).
To subscribe to these and other JDC publications:
- Go to the Sun Developer Network - Subscriptions page,
(https://softwarereg.sun.com/registration/developer/en_US/subscriptions),
choose the newsletters you want to subscribe to and click
"Submit".
- To unsubscribe, go to the Subscriptions page,
(https://softwarereg.sun.com/registration/developer/en_US/subscriptions),
uncheck the appropriate checkbox, and click "Submit".
- To use our one-click unsubscribe facility, see the link at
the end of this email:
- ARCHIVES
You'll find the Enterprise Java Technologies Tech Tips archives at:
http://java.sun.com/developer/EJTechTips/index.html
- COPYRIGHT
Copyright 2007 Sun Microsystems, Inc. All rights reserved.
901 San Antonio Road, Palo Alto, California 94303 USA.
This document is protected by copyright. For more information, see:
http://java.sun.com/developer/copyright.html
Enterprise Java Technologies Tech Tips
May 26, 2007
Trademark Information: http://www.sun.com/suntrademarks/
Java, J2SE, J2EE, J2ME, and all Java-based marks are trademarks
or registered trademarks of Sun Microsystems, Inc. in the
United States and other countries.