<?xml version="1.0"?>
<rss version="2.0">
<channel>
  <title>The Kitchen in the Zoo - spring tag</title>
  <link>http://blog.maxant.co.uk:80/pebble/tags/spring/</link>
  <description>&lt;small&gt;A blog where Ant writes about anything he finds interesting! &lt;a href=&#039;http://www.linkedin.com/in/maxant&#039;&gt;&lt;font color=&#039;white&#039;&gt;Who is Ant?&lt;/font&gt;&lt;/a&gt;      &lt;a href=&#039;/pebble/pages/copyright.html&#039;&gt;&lt;font color=&#039;white&#039;&gt;Copyright 2005-2012 Ant Kutschera&lt;/font&gt;&lt;/a&gt;&lt;/small&gt;</description>
  <language>en</language>
  <copyright>Ant Kutschera</copyright>
  <lastBuildDate>Thu, 10 May 2012 20:07:00 GMT</lastBuildDate>
  <generator>Pebble (http://pebble.sourceforge.net)</generator>
  <docs>http://backend.userland.com/rss</docs>
  
  
  <item>
    <title>GlassFish 3 In 30 Minutes</title>
    <link>http://blog.maxant.co.uk:80/pebble/2010/05/08/1273354800000.html</link>
    
      
        <description>
          &lt;p&gt;The aim: Set up a simple Java EE 6 project on GlassFish v3 in no time at all. The project must include: email, JMS, JPA, web and EJB (session bean, message driven bean and a timer bean). It must also include security and transactions.&lt;br /&gt;
&lt;br /&gt;
Sounds like a lot, but thanks to Java Enterprise Edition version 6, setting up a project like this and configuring all the resources in the Application Server are really easy! I chose GlassFish because its open source, has a useful little Admin Console and I&#039;ve never developed with it before.&lt;br /&gt;
&lt;br /&gt;
Before I started I downloaded Java SE 6 (update 20), Mysql Server, the Mysql JDBC Driver and the GlassFish Tools Bundle for Eclipse, which is a WTP Version of Eclipse 3.5.1 with some specific bundles for developing and deploying on GlassFish.&lt;br /&gt;
&lt;br /&gt;
The process I wanted to implement was simple: a user goes to a website, clicks a link to a secure page and logs in, after which a message is persisted to the database and an asynchronous email gets sent. The user is shown a confirmation. In the background theres also a task which reads new messages from the database and updates them so they are not processed a second time.&lt;br /&gt;
&lt;br /&gt;
The design was to use a servlet for calling a stateless session EJB, which persists a message using JPA and sends a JMS message to a message driven bean for asynchronous processing. The MDB sends an email. A timer EJB processes and updates any messages it finds in the database. Additionally I set a requirement to use only the newest technologies in Java EE 6, my servlet and beans were configured using annotations. The following sequence diagram shows the rough design:&lt;br /&gt;
&lt;br /&gt;
&lt;a href=&#034;/pebble/files/GFV3In20Mins/glassfish3In15Minutes.gif&#034;&gt;&lt;img width=&#034;500&#034; border=&#034;0&#034; src=&#034;/pebble/files/GFV3In20Mins/glassfish3In15Minutes.gif&#034; alt=&#034;click to zoom&#034; title=&#034;click to zoom&#034; /&gt;&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
The first challenge was to configure my resources in GlassFish. I started the preinstalled server instance which is shipped with this special Eclipse and opened the admin console at localhost (got the port number from the log console).&lt;br /&gt;
&lt;br /&gt;
Without deploying any apps, I configured the following:&lt;br /&gt;
&lt;br /&gt;
1) JDBC Connection Pools, which contain the connection details to the database - one for data, one for a security realm. When creating them, I used default settings apart from:&lt;br /&gt;
&lt;br /&gt;
Pool for Data:&lt;br /&gt;
&lt;br /&gt;
&lt;code&gt; &amp;nbsp;&amp;nbsp;&amp;lt;jdbc-connection-pool datasource-classname=&amp;quot;com.mysql.jdbc.jdbc2.optional.MysqlXADataSource&amp;quot; res-type=&amp;quot;javax.sql.XADataSource&amp;quot; name=&amp;quot;testPool&amp;quot; ping=&amp;quot;true&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;property name=&amp;quot;URL&amp;quot; value=&amp;quot;jdbc:mysql://localhost:3306/test&amp;quot; /&amp;gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;property name=&amp;quot;Url&amp;quot; value=&amp;quot;jdbc:mysql://localhost:3306/test&amp;quot; /&amp;gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;property name=&amp;quot;User&amp;quot; value=&amp;quot;root&amp;quot; /&amp;gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;property name=&amp;quot;Password&amp;quot; value=&amp;quot;password&amp;quot; /&amp;gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;.&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;.&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;lt;jdbc-connection-pool&amp;gt;&lt;/code&gt;&lt;br /&gt;
&lt;br /&gt;
Pool for Security Realm:&lt;br /&gt;
&lt;br /&gt;
&lt;code&gt; &amp;nbsp;&amp;nbsp;&amp;lt;jdbc-connection-pool driver-classname=&amp;quot;com.mysql.jdbc.Driver&amp;quot; res-type=&amp;quot;java.sql.Driver&amp;quot; name=&amp;quot;realmPool&amp;quot; ping=&amp;quot;true&amp;quot;&amp;gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;property name=&amp;quot;URL&amp;quot; value=&amp;quot;jdbc:mysql://localhost:3306/test?autoReconnect=true&amp;amp;amp;useUnicode=true&amp;amp;amp;characterEncoding=UTF-8&amp;quot; /&amp;gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;property name=&amp;quot;password&amp;quot; value=&amp;quot;password&amp;quot; /&amp;gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;property name=&amp;quot;user&amp;quot; value=&amp;quot;root&amp;quot; /&amp;gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;lt;/jdbc-connection-pool&amp;gt;&lt;br /&gt;
&lt;/code&gt; &lt;br /&gt;
2) JDBC Resources, which is where you set the JNDI names for your JDBC Connection Pools.&lt;br /&gt;
&lt;br /&gt;
&lt;code&gt; &amp;nbsp;&amp;nbsp;&amp;lt;jdbc-resource pool-name=&amp;quot;testPool&amp;quot; jndi-name=&amp;quot;jdbc/test&amp;quot; /&amp;gt; &amp;nbsp;&amp;nbsp;&amp;lt;jdbc-resource pool-name=&amp;quot;realmPool&amp;quot; jndi-name=&amp;quot;jdbc/realm&amp;quot; /&amp;gt;	  &lt;br /&gt;
&lt;/code&gt; &lt;br /&gt;
3) JMS Resource - one connection factory for sending messages, and one destination which is the queue which references a physical destination in the jms service (which gets automatically added further down in the admin console under the JMS Service).&lt;br /&gt;
&lt;br /&gt;
&lt;code&gt; &amp;nbsp;&amp;nbsp;&amp;lt;admin-object-resource res-adapter=&amp;quot;jmsra&amp;quot; res-type=&amp;quot;javax.jms.Queue&amp;quot; description=&amp;quot;a test queue&amp;quot; jndi-name=&amp;quot;jms/destinationResource&amp;quot;&amp;gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;property name=&amp;quot;Name&amp;quot; value=&amp;quot;test_destination&amp;quot; /&amp;gt; &amp;nbsp;&amp;nbsp;&amp;lt;/admin-object-resource&amp;gt; &amp;nbsp;&amp;nbsp;&amp;lt;connector-resource pool-name=&amp;quot;jmsConnectionPool&amp;quot; jndi-name=&amp;quot;jmsConnectionPool&amp;quot; /&amp;gt; &amp;nbsp;&amp;nbsp;&amp;lt;connector-connection-pool name=&amp;quot;jmsConnectionPool&amp;quot; resource-adapter-name=&amp;quot;jmsra&amp;quot; is-connection-validation-required=&amp;quot;true&amp;quot; connection-definition-name=&amp;quot;javax.jms.ConnectionFactory&amp;quot; transaction-support=&amp;quot;XATransaction&amp;quot; /&amp;gt;&lt;br /&gt;
&lt;/code&gt; &lt;br /&gt;
4) A Javamail Session, so that my app could send email over POP3.&lt;br /&gt;
&lt;br /&gt;
&lt;code&gt; &amp;nbsp;&amp;nbsp;&amp;lt;mail-resource host=&amp;quot;localhost&amp;quot; store-protocol=&amp;quot;POP3&amp;quot; store-protocol-class=&amp;quot;com.sun.mail.pop3.POP3Store&amp;quot; jndi-name=&amp;quot;mail/Session&amp;quot; from=&amp;quot;boss@maxant.co.uk&amp;quot; user=&amp;quot;boss&amp;quot;&amp;gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;property name=&amp;quot;mail-password&amp;quot; value=&amp;quot;boss&amp;quot; /&amp;gt; &amp;nbsp;&amp;nbsp;&amp;lt;/mail-resource&amp;gt;&lt;br /&gt;
&lt;/code&gt; &lt;br /&gt;
5) Under Configuration / Security, I set up a JDBC realm which used the realm database connection pool which was configured above.&lt;br /&gt;
&lt;br /&gt;
&lt;code&gt; &amp;nbsp;&amp;nbsp;&amp;lt;auth-realm name=&amp;quot;database-realm&amp;quot; classname=&amp;quot;com.sun.enterprise.security.auth.realm.jdbc.JDBCRealm&amp;quot;&amp;gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;property name=&amp;quot;jaas-context&amp;quot; value=&amp;quot;jdbcRealm&amp;quot; /&amp;gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;property name=&amp;quot;datasource-jndi&amp;quot; value=&amp;quot;jdbc/realm&amp;quot; /&amp;gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;property name=&amp;quot;user-table&amp;quot; value=&amp;quot;party&amp;quot; /&amp;gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;property name=&amp;quot;user-name-column&amp;quot; value=&amp;quot;login&amp;quot; /&amp;gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;property name=&amp;quot;password-column&amp;quot; value=&amp;quot;password&amp;quot; /&amp;gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;property name=&amp;quot;group-table&amp;quot; value=&amp;quot;role&amp;quot; /&amp;gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;property name=&amp;quot;group-name-column&amp;quot; value=&amp;quot;role&amp;quot; /&amp;gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;property name=&amp;quot;db-user&amp;quot; value=&amp;quot;root&amp;quot; /&amp;gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;property name=&amp;quot;db-password&amp;quot; value=&amp;quot;password&amp;quot; /&amp;gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;property name=&amp;quot;digest-algorithm&amp;quot; value=&amp;quot;none&amp;quot; /&amp;gt; &amp;nbsp;&amp;nbsp;&amp;lt;/auth-realm&amp;gt;&lt;br /&gt;
&lt;/code&gt; &lt;br /&gt;
Here is the &lt;a href=&#034;/pebble/files/GFV3In20Mins/domain.xml&#034;&gt;domain.xml file&lt;/a&gt; (GlassFish&#039;s main configuration file, located under either %glassfishv3_install%/glassfish/domains/domain1/config if you installed the server, or under %GlassFish-Tools-Bundle-For-Eclipse-1.2-Install&amp;amp;/workspace/.metadata/.plugins/com.sun.enterprise.jst.server.sunappsrv92/domain1/config if you installed the GlassFish Tools Bundle for Eclipse).&lt;br /&gt;
&lt;br /&gt;
Put the Mysql J/Connector JAR into %GlassFish-Tools-Bundle-For-Eclipse-1.2-Install%/glassfishv3/glassfish/lib or %glassfishv3_install%\glassfish\lib.  GlassFish already contains Mail, Activation and JMS JARs on its classpath, so there is nothing else to do here.&lt;br /&gt;
&lt;br /&gt;
Using Eclipse, create a new EAR project, as well as a new web module. Once created, right click on the running server and click &amp;quot;add / remove&amp;quot;. Add the new EAR so that its deployed, and once deployed, return to the admin console.&lt;br /&gt;
&lt;br /&gt;
You can now set up a virtual server (host) so that you can run multiple domains using the same server (something you might realistically want to do with a prodution server). To do this, you either need to modify a DNS server so that multiple domains resolve to your IP address, or you can modify the hosts file (on windows its c:\windows\system32\drivers\etc\hosts) and add a domain. In the admin console, set up a new virtual server by  refering to that domain, and setting its default application to the one you just deployed. That way, any HTTP request which comes in for that domain is sent to your web application. To enable a request like &amp;quot;http://testwsmaxantcouk:8084/&amp;quot; to be redirected to &amp;quot;index.jsp&amp;quot; in your app, you need to set the context root of the webapp to &amp;quot;/&amp;quot;, in application.xml or the EAR:&lt;br /&gt;
&lt;br /&gt;
&lt;code&gt; &amp;nbsp;&amp;nbsp;&amp;lt;application xmlns:xsi=&amp;quot;http://www.w3.org/2001/XMLSchema-instance&amp;quot; xmlns=&amp;quot;http://java.sun.com/xml/ns/javaee&amp;quot; xmlns:application=&amp;quot;http://java.sun.com/xml/ns/javaee/application_5.xsd&amp;quot; xsi:schemaLocation=&amp;quot;http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/application_5.xsd&amp;quot; id=&amp;quot;Application_ID&amp;quot; version=&amp;quot;5&amp;quot;&amp;gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;display-name&amp;gt;Seven&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;module&amp;gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;web&amp;gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;web-uri&amp;gt;SevenWeb.war&amp;lt;/web-uri&amp;gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;context-root&amp;gt;/&amp;lt;/context-root&amp;gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;/web&amp;gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;/module&amp;gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;lt;/application&amp;gt;&lt;br /&gt;
&lt;/code&gt; &lt;br /&gt;
In order for this configuration to work, you need to create a database and relevant schema, which you can do using the three SQL files inside the download at the bottom of this article, to create the database, create tables for the realm and application, and insert some initial data into them.&lt;br /&gt;
&lt;br /&gt;
The next step is to add your servlet. I used the eclipse wizard to add a new servlet, which generates a class into your web project with Java EE 6 annotations:&lt;br /&gt;
&lt;br /&gt;
&lt;code&gt; &amp;nbsp;&amp;nbsp;@WebServlet(name = &amp;quot;SevenServlet&amp;quot;, urlPatterns = { &amp;quot;/SevenServlet&amp;quot; })&lt;br /&gt;
&amp;nbsp;&amp;nbsp;public class SevenServlet extends HttpServlet {&lt;br /&gt;
&amp;nbsp;&amp;nbsp;.&lt;br /&gt;
&amp;nbsp;&amp;nbsp;.&lt;br /&gt;
&lt;br /&gt;
&lt;/code&gt; The servlet delegates its work to a stateless session EJB, which ensures that a transaction is started. The EJB can also be used to check security, although the servlet needs to be deployed within a security context in order to get the web container to automatically reply with a redirection to the login page, in the case where the user is not logged in. In Java EE 6, you do this also using annotations:&lt;br /&gt;
&lt;br /&gt;
&lt;code&gt; &amp;nbsp;&amp;nbsp;@Resource(name=&amp;quot;java:app/SevenEJB/EJBSeven&amp;quot;)&lt;br /&gt;
&amp;nbsp;&amp;nbsp;private EJBSevenLocal ejbLocal;&lt;br /&gt;
&lt;/code&gt; &lt;br /&gt;
When the container finds this annotation in an servlet, it injects the EJB automatically.&lt;br /&gt;
&lt;br /&gt;
The EJB is declared with some annotations and resources too:&lt;br /&gt;
&lt;br /&gt;
&lt;code&gt; &amp;nbsp;&amp;nbsp;@DeclareRoles({Roles.REGISTERED})&lt;br /&gt;
&amp;nbsp;&amp;nbsp;@Stateless&lt;br /&gt;
&amp;nbsp;&amp;nbsp;@TransactionManagement(TransactionManagementType.CONTAINER)&lt;br /&gt;
&amp;nbsp;&amp;nbsp;public class EJBSeven implements EJBSevenLocal {&lt;br /&gt;
&amp;nbsp;&amp;nbsp;.&lt;br /&gt;
&amp;nbsp;&amp;nbsp;.&lt;br /&gt;
&lt;/code&gt; &lt;br /&gt;
This tells the EJB container that the EJB is stateless, uses container managed transactions and may be used by users with roles &amp;quot;registered&amp;quot;. The following resources are declared:&lt;br /&gt;
&lt;br /&gt;
&lt;code&gt; &amp;nbsp;&amp;nbsp;@Resource(mappedName = &amp;quot;jms/destinationResource&amp;quot;)&lt;br /&gt;
&amp;nbsp;&amp;nbsp;private Queue q;&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;@Resource(mappedName = &amp;quot;jmsConnectionPool&amp;quot;)&lt;br /&gt;
&amp;nbsp;&amp;nbsp;private QueueConnectionFactory qcf;&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;@Resource &lt;br /&gt;
&amp;nbsp;&amp;nbsp;private SessionContext sessionContext;&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;@PersistenceContext(unitName=&amp;quot;MessageManagement&amp;quot;)&lt;br /&gt;
&amp;nbsp;&amp;nbsp;private EntityManager em;&lt;br /&gt;
&lt;/code&gt; &lt;br /&gt;
These resources are a JMS connection factory, and a queue, for sending the asynchronous message. The session context is the EJBs session context which allows the EJB to query users roles and rollback transactions, amongst other things. A JPA Entity Manager is also declared allowing the EJB to use the database. Finally, the business method declared in the EJB interface is implemented:&lt;br /&gt;
&lt;br /&gt;
&lt;code&gt; &amp;nbsp;&amp;nbsp;@Override&lt;br /&gt;
&amp;nbsp;&amp;nbsp;@RolesAllowed({Roles.REGISTERED})&lt;br /&gt;
&amp;nbsp;&amp;nbsp;@TransactionAttribute(TransactionAttributeType.REQUIRED)&lt;br /&gt;
&amp;nbsp;&amp;nbsp;public String execute(String command) {&lt;br /&gt;
&amp;nbsp;&amp;nbsp;.&lt;br /&gt;
&amp;nbsp;&amp;nbsp;.&lt;br /&gt;
&lt;/code&gt; &lt;br /&gt;
The annotations above tell the container that the user must be in the given role in order to call this method, and that a transaction is required.&lt;br /&gt;
&lt;br /&gt;
Next, the message driven bean is implemented:&lt;br /&gt;
&lt;br /&gt;
&lt;code&gt; &amp;nbsp;&amp;nbsp;@MessageDriven(&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;activationConfig = { @ActivationConfigProperty(&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;propertyName = &amp;quot;destinationType&amp;quot;, propertyValue = &amp;quot;javax.jms.Queue&amp;quot;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;) }, &lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;mappedName = &amp;quot;jms/destinationResource&amp;quot;)&lt;br /&gt;
&amp;nbsp;&amp;nbsp;public class MDBean implements MessageListener {&lt;br /&gt;
&amp;nbsp;&amp;nbsp;.&lt;br /&gt;
&amp;nbsp;&amp;nbsp;.&lt;br /&gt;
&lt;br /&gt;
&lt;/code&gt; The annotations above tell the container which messages should be sent to the onMessage(Message) method of the bean. This bean too has resources, namely a mail session, for sending email:&lt;br /&gt;
&lt;br /&gt;
&lt;code&gt; &amp;nbsp;&amp;nbsp;@Resource(name=&amp;quot;mail/Session&amp;quot;)&lt;br /&gt;
&amp;nbsp;&amp;nbsp;private Session mailSession;&lt;br /&gt;
&lt;/code&gt; &lt;br /&gt;
The timer EJB is also implemented:&lt;br /&gt;
&lt;br /&gt;
&lt;code&gt; &amp;nbsp;&amp;nbsp;@Stateless&lt;br /&gt;
&amp;nbsp;&amp;nbsp;@TransactionManagement(TransactionManagementType.CONTAINER)&lt;br /&gt;
&amp;nbsp;&amp;nbsp;public class EJBTimerSeven {&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;@PersistenceContext(unitName=&amp;quot;MessageManagement&amp;quot;)&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;private EntityManager em;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;.&lt;br /&gt;
&amp;nbsp;&amp;nbsp;.&lt;br /&gt;
&lt;/code&gt; &lt;br /&gt;
In order for the timer bean to use the entity manager within a transactional context (so that it can for example update or insert data), it too needs a declaration that it uses container managed transactions.  The method which is scheduled is defined next:&lt;br /&gt;
&lt;br /&gt;
&lt;code&gt; &amp;nbsp;&amp;nbsp;@Schedule(second=&amp;quot;0&amp;quot;, minute=&amp;quot;*/1&amp;quot;, hour=&amp;quot;6-23&amp;quot;, dayOfWeek=&amp;quot;Mon-Fri&amp;quot;, dayOfMonth=&amp;quot;*&amp;quot;, month=&amp;quot;*&amp;quot;, year=&amp;quot;*&amp;quot;, info=&amp;quot;MyTimer&amp;quot;)&lt;br /&gt;
&amp;nbsp;&amp;nbsp;@TransactionAttribute(TransactionAttributeType.REQUIRES_NEW)&lt;br /&gt;
&amp;nbsp;&amp;nbsp;private void scheduledTimeout(final Timer t) {&lt;br /&gt;
.&lt;br /&gt;
.&lt;br /&gt;
&lt;/code&gt; &lt;br /&gt;
Note that there is nothing in this beans definition that makes it a timer bean. Rather the method which is to be called when the schedule fires, is simply annotated. I could have just as easily added this method to the main EJB in my project. The schedule pattern is similar to scheduling a cron job in unix, and the second part to ensuring that this methods actions on the entity manager are committed is to add the TransactionAttribute annotation, in this case ensuring that a new transaction is started.&lt;br /&gt;
&lt;br /&gt;
The last thing I needed was a class for JPA, to represent the table I want to write to:&lt;br /&gt;
&lt;br /&gt;
&lt;code&gt; &amp;nbsp;&amp;nbsp;@Entity&lt;br /&gt;
&amp;nbsp;&amp;nbsp;public class Message {&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;@GeneratedValue(strategy=GenerationType.IDENTITY)&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;@Id&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;private int uid;&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;@Column(name=&amp;quot;sender&amp;quot;)&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;private String sender;&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;@Column(name=&amp;quot;when_sent&amp;quot;)&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;private Timestamp whenSent;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;.&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;.&lt;br /&gt;
&lt;/code&gt; &lt;br /&gt;
This classes annotations show that its a persistable entity using JPA (the @Entity annotation), that the &amp;quot;uid&amp;quot; attribute is the primary key and is generated by the database and that the other attributes map to given columns in the database. Using these very simple annotations and configuring the entity manager using the follwing simple XML, JPA is enabled and it becomes very simple to use indeed.&lt;br /&gt;
&lt;br /&gt;
&lt;code&gt; &amp;nbsp;&amp;nbsp;&amp;lt;persistence&amp;gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;persistence-unit name=&amp;quot;MessageManagement&amp;quot;&amp;gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;jta-data-source&amp;gt;jdbc/test&amp;lt;/jta-data-source&amp;gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;class&amp;gt;uk.co.maxant.test.Message&amp;lt;/class&amp;gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;/persistence-unit&amp;gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;lt;/persistence&amp;gt;&lt;br /&gt;
&lt;/code&gt; &lt;br /&gt;
This XML file is saved as &amp;quot;persistence.xml&amp;quot; and dropped into the META-INF folder of the EJB project.&lt;br /&gt;
&lt;br /&gt;
So, setting up a Java EE 6 enterprise application is really simple! Here are some comments...&lt;br /&gt;
&lt;br /&gt;
Remember that when calling services (EJBs) from your web layer (servlets or in JSF backing beans), that you should always call a fa&amp;ccedil;ade whose job is to ensure that a transaction is started. In fact, you may have noticed that the realm JDBC resource was configured as a simple SQL Driver, whereas the JDBC resource for the application was set up as an XA Data Source. What&#039;s the difference? Well within the application we used JMS and the application database in the same business method of our EJB, which was run within a transaction. To ensure that either both resources were committed together, or neither, you MUST use XA. The JMS connection factory has a flag on it to say that it should be XA-enabled. The application which you can download at the end of this article contains a hyperlink for starting the process described at the top of the article, as well as another hyperlink for starting it with an error. Any errors that occur in your business logic, before the container attempts to commit resources, are not affected by XA. Rather, XA helps if one of the resources cannot commit, say due to a data constaint defined in the database. That means that if the container had sent the JMS message and then attempted to write data to the database and discovered the data was not valid, it would not commit the sending of the JMS message, so neither resource gets commited! It is important to understand the subtle differences in where the errors occur, in order to see the benefits of XA. For more information see &lt;a target=&#034;_blank&#034; href=&#034;http://en.wikipedia.org/wiki/2PC&#034;&gt;Wikipedia&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
If you get the following error after deploying the EAR, don&#039;t worry, it&#039;s quite normal:  &amp;quot;WEB9051: Error trying to scan the classes at .../eclipseApps/Seven/SevenEJB.jar for annotations in which a ServletContainerInitializer has expressed interest&amp;quot;. See &lt;a href=&#034;http://wiki.glassfish.java.net/Wiki.jsp?page=GlassFishV3ErrorMessageReferenceWEB&#034;&gt;here&lt;/a&gt;.&lt;br /&gt;
&lt;br /&gt;
GlassFish&#039;s log files can be found at either %glassfishv3_install%/glassfish/domains/domain1/logs if you installed the server, or under %GlassFish-Tools-Bundle-For-Eclipse-1.2-Install&amp;amp;/workspace/.metadata/.plugins/com.sun.enterprise.jst.server.sunappsrv92/domain1/logs if you installed the GlassFish Tools Bundle for Eclipse).&lt;br /&gt;
&lt;br /&gt;
If you experience problems with the security realm, the logs don&#039;t give much information. The easiest solution is to set a breakpoint for exception com.sun.enterprise.security.auth.login.common.LoginException and when it comes up, you can debug the JDBCRealm class. You need to download the source which you can find under https://svn.dev.java.net/svn/glassfish-svn/trunk/v3/security/core (login with user &amp;quot;guest&amp;quot; and no password). More information for the JDBC realm can be found &lt;a href=&#034;http://blogs.sun.com/swchan/entry/jdbcrealm_in_glassfish_with_mysql&#034; target=&#034;_blank&#034;&gt;here&lt;/a&gt;. One other noteworthy point about realms and GlassFish is that unlike with Tomcat, you must state which realm to use for your web app. You can either do this in the sun-application.xml file, or by adding the realm-name element to your login-config element of web.xml. Both are shown in the download for this article (see bottom).&lt;br /&gt;
&lt;br /&gt;
Until now, I have never used Java EE 6. I had got into the routine of using simple Spring for simple projects. But Java EE 6 is practically the same as Spring in terms of configuring services (EJBs) and adding security and transaction annotations. So I&#039;ve started to ask myself what the advantage of Spring now is. Well Spring still offers simple database handling in terms of not having to worry about exceptions and being able to call Hibernate or other frameworks in a standard way, but JPA offers the same advantages. Spring also offers simplified sending of email, which Java EE 6 does not have, but this is no huge deal. One nice feature of Spring is that it includes AOP, which I have used mostly for improving on Spring Security (by simplifying it, search on this blog for more details). While Java EE 6 doesn&#039;t offer AOP out of the box, you can add it quite simply (see http://www.eclipse.org/aspectj). What&#039;s more, the security offered by Java EE is much more standard than that offered by Spring. To so summarise, it&#039;s getting hard to justify wanting or needing to use Spring. While it is sold as being light weight, modern Java EE app servers are themselves quite light weight, and thanks to &amp;quot;profiles&amp;quot; you can obtain even lighter weight versions of them. See the java.sun.com for more information. &lt;br /&gt;
&lt;br /&gt;
You will notice that the JNDI names used in the resource annotations in my EJBs were added against &amp;quot;mappedName&amp;quot; attributes in the annotations, rather than &amp;quot;name&amp;quot;. What that means is that the standard indirection mappings that one should use when deploying EJBs, has not been used, namely the resource &amp;quot;jms/destinationResource&amp;quot; MUST be present in the JNDI tree, rather than the container looking for this name in a mapping in the deployment descriptor. This is fine when deploying your own EJBs to your own app server, but the original idea of creating EJBs was that you would write them, and the deployer would decide how the resources are named, which hence requires a mapping. If you do provice a mapping in the deployment descriptors, then you should use the &amp;quot;name&amp;quot; attribute in the annotations. See &lt;a href=&#034;http://forums.java.net/jive/thread.jspa?threadID=31634&#034; target=&#034;_blank&#034;&gt;here&lt;/a&gt; for more information.&lt;br /&gt;
&lt;br /&gt;
The full source code can be downloaded &lt;a href=&#034;/pebble/files/GFV3In20Mins/Seven.zip&#034;&gt;here&lt;/a&gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;copy; 2010 Ant Kutschera&lt;/p&gt;&lt;div class=&#034;tags&#034;&gt;&lt;span&gt;Social Bookmarks : &lt;/span&gt;&amp;nbsp;&lt;a href=&#034;http://slashdot.org/bookmark.pl?url=http://blog.maxant.co.uk:80/pebble/2010/05/08/1273354800000.html&amp;amp;title=GlassFish+3+In+30+Minutes&#034; target=&#034;_blank&#034; title=&#034;Add this post to Slash Dot&#034;&gt;&lt;img src=&#034;common/images/slashdot.png&#034; alt=&#034;Add this post to Slashdot&#034; border=&#034;0&#034; /&gt;&lt;/a&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;a href=&#034;http://digg.com/submit?url=http://blog.maxant.co.uk:80/pebble/2010/05/08/1273354800000.html&amp;amp;title=GlassFish+3+In+30+Minutes&#034; target=&#034;_blank&#034; title=&#034;Digg this post&#034;&gt;&lt;img src=&#034;common/images/digg.png&#034; alt=&#034;Add this post to Digg&#034; border=&#034;0&#034; /&gt;&lt;/a&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;a href=&#034;http://reddit.com/submit?url=http://blog.maxant.co.uk:80/pebble/2010/05/08/1273354800000.html&amp;amp;title=GlassFish+3+In+30+Minutes&#034; target=&#034;_blank&#034; title=&#034;Add this post to Reddit&#034;&gt;&lt;img src=&#034;common/images/reddit.png&#034; alt=&#034;Add this post to Reddit&#034; border=&#034;0&#034; /&gt;&lt;/a&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;a href=&#034;http://del.icio.us/post?url=http://blog.maxant.co.uk:80/pebble/2010/05/08/1273354800000.html&amp;amp;title=GlassFish+3+In+30+Minutes&#034; target=&#034;_blank&#034; title=&#034;Save this post to Del.icio.us&#034;&gt;&lt;img src=&#034;common/images/delicious.png&#034; alt=&#034;Add this post to Delicious&#034; border=&#034;0&#034; /&gt;&lt;/a&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;a href=&#034;http://www.stumbleupon.com/submit?url=http://blog.maxant.co.uk:80/pebble/2010/05/08/1273354800000.html&amp;amp;title=GlassFish+3+In+30+Minutes&#034; target=&#034;_blank&#034; title=&#034;Stumble this post&#034;&gt;&lt;img src=&#034;common/images/stumbleupon.png&#034; alt=&#034;Add this post to Stumble it&#034; border=&#034;0&#034; /&gt;&lt;/a&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;a href=&#034;http://www.google.com/bookmarks/mark?op=edit&amp;amp;bkmk=http://blog.maxant.co.uk:80/pebble/2010/05/08/1273354800000.html&amp;amp;title=GlassFish+3+In+30+Minutes&#034; target=&#034;_blank&#034; title=&#034;Add this post to Google&#034;&gt;&lt;img src=&#034;common/images/google.png&#034; alt=&#034;Add this post to Google&#034; border=&#034;0&#034; /&gt;&lt;/a&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;a href=&#034;http://technorati.com/faves?add=http://blog.maxant.co.uk:80/pebble/2010/05/08/1273354800000.html&#034; target=&#034;_blank&#034; title=&#034;Add this post to Technorati&#034;&gt;&lt;img src=&#034;common/images/technorati.png&#034; alt=&#034;Add this post to Technorati&#034; border=&#034;0&#034; /&gt;&lt;/a&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;a href=&#034;http://www.bloglines.com/sub/http://blog.maxant.co.uk:80/pebble/2010/05/08/1273354800000.html&#034; target=&#034;_blank&#034; title=&#034;Add this post to Bloglines&#034;&gt;&lt;img src=&#034;common/images/bloglines.png&#034; alt=&#034;Add this post to Bloglines&#034; border=&#034;0&#034; /&gt;&lt;/a&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;a href=&#034;http://www.facebook.com/share.php?u=http://blog.maxant.co.uk:80/pebble/2010/05/08/1273354800000.html&#034; target=&#034;_blank&#034; title=&#034;Add this post to Facebook&#034;&gt;&lt;img src=&#034;common/images/facebook.png&#034; alt=&#034;Add this post to Facebook&#034; border=&#034;0&#034; /&gt;&lt;/a&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;a href=&#034;http://www.furl.net/storeIt.jsp?u=http://blog.maxant.co.uk:80/pebble/2010/05/08/1273354800000.html&amp;amp;t=GlassFish+3+In+30+Minutes&#034; target=&#034;_blank&#034; title=&#034;Add this post to Furl&#034;&gt;&lt;img src=&#034;common/images/furl.png&#034; alt=&#034;Add this post to Furl&#034; border=&#034;0&#034; /&gt;&lt;/a&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;a href=&#034;https://favorites.live.com/quickadd.aspx?mkt=en-us&amp;amp;url=http://blog.maxant.co.uk:80/pebble/2010/05/08/1273354800000.html&amp;amp;title=GlassFish+3+In+30+Minutes&#034; target=&#034;_blank&#034; title=&#034;Add this post to Windows Live&#034;&gt;&lt;img src=&#034;common/images/windowslive.png&#034; alt=&#034;Add this post to Windows Live&#034; border=&#034;0&#034; /&gt;&lt;/a&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;a href=&#034;http://bookmarks.yahoo.com/toolbar/savebm?opener=tb&amp;amp;u=http://blog.maxant.co.uk:80/pebble/2010/05/08/1273354800000.html&amp;amp;t=GlassFish+3+In+30+Minutes&#034; target=&#034;_blank&#034; title=&#034;Add this post to Yahoo!&#034;&gt;&lt;img src=&#034;common/images/yahoo.png&#034; alt=&#034;Add this post to Yahoo!&#034; border=&#034;0&#034; /&gt;&lt;/a&gt;&lt;/div&gt;
        </description>
      
      
    
    
    
    <comments>http://blog.maxant.co.uk:80/pebble/2010/05/08/1273354800000.html#comments</comments>
    <guid isPermaLink="true">http://blog.maxant.co.uk:80/pebble/2010/05/08/1273354800000.html</guid>
    <pubDate>Sat, 08 May 2010 21:40:00 GMT</pubDate>
  </item>
  
  <item>
    <title>Enterprise GWT: Combining Google Web Toolkit, Spring and Other Features to Build Enterprise Applications</title>
    <link>http://blog.maxant.co.uk:80/pebble/2010/01/25/1264446000000.html</link>
    
      
        <description>
          &lt;p&gt;The following is just the introduction taken from a new white paper available at &lt;a target=&#034;_blank&#034; href=&#034;http://www.maxant.co.uk/whitepapers.jsp&#034;&gt;www.maxant.co.uk/whitepapers.jsp&lt;/a&gt;:&lt;br /&gt;
&lt;br /&gt;
Google Web Toolkit (GWT) provides developers with a powerful means of developing&lt;br /&gt;
AJAX front ends without the worry of having to maintain complex Java script libraries to&lt;br /&gt;
support multiple browsers and browser versions.&lt;br /&gt;
&lt;br /&gt;
GWT also provides support for Remote Procedure Calls (RPC) to the server. Since April&lt;br /&gt;
2009 the Google App Engine has existed, which allows developers to deploy their GWT&lt;br /&gt;
applications and also provides support for Java Data Objects (JDO) and the Java&lt;br /&gt;
Persistence API (JPA).&lt;br /&gt;
&lt;br /&gt;
However what is missing for GWT to be deployed to a modern Enterprise environment is a service framework providing dependency injection and inversion of control (IoC),&lt;br /&gt;
transaction demarcation and security, such as that provided by Spring or Enterprise Java Beans (EJB) 3.0. Furthermore GWT does not define any patterns for User Interface&lt;br /&gt;
designs, or composite widgets.&lt;br /&gt;
&lt;br /&gt;
This paper describes how to successfully integrate Spring into a GWT Application with the aim of creating a fully scalable development framework for deployment in the Enterprise and beyond (including simple and small applications), with very little start up time being required, because you can download the demo application. It includes UI Patterns and composite widgets to improve the development of the front end. This GWT Demo Application is live at http://gwtdemo.maxant.co.uk and is available for download at&lt;br /&gt;
http://www.maxant.co.uk/whitepapers.jsp.&lt;br /&gt;
&lt;br /&gt;
(c) 2010 Ant Kutschera&lt;/p&gt;&lt;div class=&#034;tags&#034;&gt;&lt;span&gt;Social Bookmarks : &lt;/span&gt;&amp;nbsp;&lt;a href=&#034;http://slashdot.org/bookmark.pl?url=http://blog.maxant.co.uk:80/pebble/2010/01/25/1264446000000.html&amp;amp;title=Enterprise+GWT%3A+Combining+Google+Web+Toolkit%2C+Spring+and+Other+Features+to+Build+Enterprise+Applications&#034; target=&#034;_blank&#034; title=&#034;Add this post to Slash Dot&#034;&gt;&lt;img src=&#034;common/images/slashdot.png&#034; alt=&#034;Add this post to Slashdot&#034; border=&#034;0&#034; /&gt;&lt;/a&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;a href=&#034;http://digg.com/submit?url=http://blog.maxant.co.uk:80/pebble/2010/01/25/1264446000000.html&amp;amp;title=Enterprise+GWT%3A+Combining+Google+Web+Toolkit%2C+Spring+and+Other+Features+to+Build+Enterprise+Applications&#034; target=&#034;_blank&#034; title=&#034;Digg this post&#034;&gt;&lt;img src=&#034;common/images/digg.png&#034; alt=&#034;Add this post to Digg&#034; border=&#034;0&#034; /&gt;&lt;/a&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;a href=&#034;http://reddit.com/submit?url=http://blog.maxant.co.uk:80/pebble/2010/01/25/1264446000000.html&amp;amp;title=Enterprise+GWT%3A+Combining+Google+Web+Toolkit%2C+Spring+and+Other+Features+to+Build+Enterprise+Applications&#034; target=&#034;_blank&#034; title=&#034;Add this post to Reddit&#034;&gt;&lt;img src=&#034;common/images/reddit.png&#034; alt=&#034;Add this post to Reddit&#034; border=&#034;0&#034; /&gt;&lt;/a&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;a href=&#034;http://del.icio.us/post?url=http://blog.maxant.co.uk:80/pebble/2010/01/25/1264446000000.html&amp;amp;title=Enterprise+GWT%3A+Combining+Google+Web+Toolkit%2C+Spring+and+Other+Features+to+Build+Enterprise+Applications&#034; target=&#034;_blank&#034; title=&#034;Save this post to Del.icio.us&#034;&gt;&lt;img src=&#034;common/images/delicious.png&#034; alt=&#034;Add this post to Delicious&#034; border=&#034;0&#034; /&gt;&lt;/a&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;a href=&#034;http://www.stumbleupon.com/submit?url=http://blog.maxant.co.uk:80/pebble/2010/01/25/1264446000000.html&amp;amp;title=Enterprise+GWT%3A+Combining+Google+Web+Toolkit%2C+Spring+and+Other+Features+to+Build+Enterprise+Applications&#034; target=&#034;_blank&#034; title=&#034;Stumble this post&#034;&gt;&lt;img src=&#034;common/images/stumbleupon.png&#034; alt=&#034;Add this post to Stumble it&#034; border=&#034;0&#034; /&gt;&lt;/a&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;a href=&#034;http://www.google.com/bookmarks/mark?op=edit&amp;amp;bkmk=http://blog.maxant.co.uk:80/pebble/2010/01/25/1264446000000.html&amp;amp;title=Enterprise+GWT%3A+Combining+Google+Web+Toolkit%2C+Spring+and+Other+Features+to+Build+Enterprise+Applications&#034; target=&#034;_blank&#034; title=&#034;Add this post to Google&#034;&gt;&lt;img src=&#034;common/images/google.png&#034; alt=&#034;Add this post to Google&#034; border=&#034;0&#034; /&gt;&lt;/a&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;a href=&#034;http://technorati.com/faves?add=http://blog.maxant.co.uk:80/pebble/2010/01/25/1264446000000.html&#034; target=&#034;_blank&#034; title=&#034;Add this post to Technorati&#034;&gt;&lt;img src=&#034;common/images/technorati.png&#034; alt=&#034;Add this post to Technorati&#034; border=&#034;0&#034; /&gt;&lt;/a&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;a href=&#034;http://www.bloglines.com/sub/http://blog.maxant.co.uk:80/pebble/2010/01/25/1264446000000.html&#034; target=&#034;_blank&#034; title=&#034;Add this post to Bloglines&#034;&gt;&lt;img src=&#034;common/images/bloglines.png&#034; alt=&#034;Add this post to Bloglines&#034; border=&#034;0&#034; /&gt;&lt;/a&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;a href=&#034;http://www.facebook.com/share.php?u=http://blog.maxant.co.uk:80/pebble/2010/01/25/1264446000000.html&#034; target=&#034;_blank&#034; title=&#034;Add this post to Facebook&#034;&gt;&lt;img src=&#034;common/images/facebook.png&#034; alt=&#034;Add this post to Facebook&#034; border=&#034;0&#034; /&gt;&lt;/a&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;a href=&#034;http://www.furl.net/storeIt.jsp?u=http://blog.maxant.co.uk:80/pebble/2010/01/25/1264446000000.html&amp;amp;t=Enterprise+GWT%3A+Combining+Google+Web+Toolkit%2C+Spring+and+Other+Features+to+Build+Enterprise+Applications&#034; target=&#034;_blank&#034; title=&#034;Add this post to Furl&#034;&gt;&lt;img src=&#034;common/images/furl.png&#034; alt=&#034;Add this post to Furl&#034; border=&#034;0&#034; /&gt;&lt;/a&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;a href=&#034;https://favorites.live.com/quickadd.aspx?mkt=en-us&amp;amp;url=http://blog.maxant.co.uk:80/pebble/2010/01/25/1264446000000.html&amp;amp;title=Enterprise+GWT%3A+Combining+Google+Web+Toolkit%2C+Spring+and+Other+Features+to+Build+Enterprise+Applications&#034; target=&#034;_blank&#034; title=&#034;Add this post to Windows Live&#034;&gt;&lt;img src=&#034;common/images/windowslive.png&#034; alt=&#034;Add this post to Windows Live&#034; border=&#034;0&#034; /&gt;&lt;/a&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;a href=&#034;http://bookmarks.yahoo.com/toolbar/savebm?opener=tb&amp;amp;u=http://blog.maxant.co.uk:80/pebble/2010/01/25/1264446000000.html&amp;amp;t=Enterprise+GWT%3A+Combining+Google+Web+Toolkit%2C+Spring+and+Other+Features+to+Build+Enterprise+Applications&#034; target=&#034;_blank&#034; title=&#034;Add this post to Yahoo!&#034;&gt;&lt;img src=&#034;common/images/yahoo.png&#034; alt=&#034;Add this post to Yahoo!&#034; border=&#034;0&#034; /&gt;&lt;/a&gt;&lt;/div&gt;
        </description>
      
      
    
    
    
    <comments>http://blog.maxant.co.uk:80/pebble/2010/01/25/1264446000000.html#comments</comments>
    <guid isPermaLink="true">http://blog.maxant.co.uk:80/pebble/2010/01/25/1264446000000.html</guid>
    <pubDate>Mon, 25 Jan 2010 19:00:00 GMT</pubDate>
  </item>
  
  <item>
    <title>Java EE Security and Spring</title>
    <link>http://blog.maxant.co.uk:80/pebble/2009/06/02/1243967400000.html</link>
    
      
        <description>
          &lt;p&gt;&lt;a target=&#034;_blank&#034; href=&#034;http://static.springsource.org/spring-security/site/index.html&#034;&gt;Spring Security&lt;/a&gt; (originally ACEGI) does not seem to work out of the box with Java EE security (see &lt;a target=&#034;_blank&#034; href=&#034;http://forum.springsource.org/showthread.php?t=31388&#034;&gt;here&lt;/a&gt;). I guess the reason is clear, namely that the people from Spring don&#039;t want you to be tied into Java EE and that makes sense because Spring something that you can use without Java EE. But instead of having to learn something new and instead of having to configure my security in a non-standard way, I wanted a way to ensure my services are only called by someone with the right authorization, exactly when they are deployed in a Java EE environment. &lt;br /&gt;
&lt;br /&gt;
Since a standard web application running in a Java EE container can be configured to have security, I expected to be able to configure Spring to use the web request to check the Principal for its security roles before calling a service, but that isn&#039;t possible. So, I set to work to quickly create a little library to help me out. &lt;br /&gt;
&lt;br /&gt;
The first step was to implement a Filter in the web application so that it could intercept every call and insert the web request (containing the Principal) into a ThreadLocal variable. The idea was that the ThreadLocal variable could then be used further up the call stack to query the security roles of the authenticated user. The filter implementation looks like this: &lt;br /&gt;
&lt;br /&gt;
&lt;code&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; public void doFilter(&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; ServletRequest request,&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ServletResponse response,&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; FilterChain chain) &lt;/code&gt;&lt;/p&gt;
&lt;p&gt;&lt;code&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; throws IOException, ServletException {&amp;nbsp;&lt;br /&gt;
&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;&lt;code&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; //set the request in the security thread local&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; SecurityHelper.set((HttpServletRequest)request);&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;&lt;code&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;chain.doFilter(request, response);&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;&lt;code&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; //all done, so remove references to unwanted objects&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;&lt;code&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; SecurityHelper.finished();&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; } &lt;/code&gt;&lt;br /&gt;
&lt;br /&gt;
The filter is configured in the Java EE web application&#039;s web.xml like this: &lt;br /&gt;
&lt;code&gt;&lt;filter&gt;&lt;/filter&gt;&lt;filter-name&gt;&lt;/filter-name&gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;filter&amp;gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;filter-name&amp;gt;maxantSpringSecurity&amp;lt;/filter-name&amp;gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;filter-class&amp;gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; uk.co.maxant.spring.security.SecurityFilter&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/filter-class&amp;gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/filter&amp;gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;filter-mapping&amp;gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;filter-name&amp;gt;maxantSpringSecurity&amp;lt;/filter-name&amp;gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;url-pattern&amp;gt;/*&amp;lt;/url-pattern&amp;gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/filter-mapping&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;/code&gt;The filter calls the SecurityHelper which uses a ThreadLocal variable to store the web request as follows. The web request can be used to gain access to the Principal, as well as ask if the Principal has a given role. &lt;br /&gt;
&lt;code&gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; private static ThreadLocal&lt;httpservletrequest&gt;&lt;/httpservletrequest&gt; tls = new ThreadLocal&lt;httpservletrequest&gt;&lt;/httpservletrequest&gt;();&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;&lt;code&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; public static void set(HttpServletRequest request){&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; tls.set(request);&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; public static boolean isInRole(String role){&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; HttpServletRequest req = tls.get();&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; if(req == null){&lt;br /&gt;
&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; return false;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; }else{&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; return req.isUserInRole(role);&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; } &lt;/code&gt;&lt;br /&gt;
&lt;br /&gt;
The Security Helper also contains an additional method which can be called to release the reference to the request. This is important because the web request contains a reference to the session and that might be large. We don&#039;t want to be holding on to such things for a long time as they may use memory unncessarily. This method can is called as soon as all security queries are finished, and is implemented as follows. For more information on thread locals and threads that are stored in pools, see &lt;a target=&#034;_blank&#034; href=&#034;http://blog.maxant.co.uk/pebble/2008/09/23/1222200780000.html&#034;&gt;here&lt;/a&gt;.&lt;code&gt;&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; public static void finished(){&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; tls.remove();&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; } &lt;/code&gt;&lt;br /&gt;
&lt;br /&gt;
The final step was to configure my Spring configuration to setup an aspect to intercept all service calls. The advice which this aspect gives is whether the current user has the role required to call the method. The required role comes from an annotation added to the service methods and the current user comes from the Principal stored in the ThreadLocal from step one, above. If the user has rights, the service method is called. If not, a simple SecurityException is thrown, providing details about the missing roles. In cases where the user is not logged in, the Security Exception is also thrown. In cases where a Service method has no annotation, then no security is checked. The aspect is configured in the Spring configuration like this: &lt;code&gt;&lt;bean id=&#034;security&#034; class=&#034;uk.co.maxant.spring.security.SecurityAspect&#034;&gt;&lt;/bean&gt;&lt;!-- execute before the transactional advice (hence the lower order number)
			but after say profiling --&gt;
&lt;property value=&#034;2&#034; name=&#034;order&#034;&gt;&lt;/property&gt;
&amp;nbsp;&lt;aop:config&gt;&lt;/aop:config&gt;&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;!-- security aspect --&amp;gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;bean id=&amp;quot;security&amp;quot;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; class=&amp;quot;uk.co.maxant.spring.security.SecurityAspect&amp;quot;&amp;gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;!-- execute before the transactional advice (hence the lower order number)&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; but after profiling --&amp;gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;property name=&amp;quot;order&amp;quot; value=&amp;quot;2&amp;quot; /&amp;gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/bean&amp;gt;&lt;br /&gt;
&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;aop:config&amp;gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;!-- this advice will execute around the transactional advice --&amp;gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;aop:aspect id=&amp;quot;securityAspect&amp;quot; ref=&amp;quot;security&amp;quot;&amp;gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;aop:pointcut id=&amp;quot;serviceMethod&amp;quot; &lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; expression=&amp;quot;execution(* uk.co.maxant.gwtdemo16.server.*Service.*(..))&amp;quot; /&amp;gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;aop:around method=&amp;quot;checkSecurity&amp;quot;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; pointcut-ref=&amp;quot;serviceMethod&amp;quot; /&amp;gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/aop:aspect&amp;gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/aop:config&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The expression in the above pointcut needs to be configured to match your package and Service naming conventions.&amp;nbsp;&lt;/p&gt;
&lt;p&gt;The aspect itself is implemented like this: &lt;br /&gt;
&lt;code&gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; public Object checkSecurity(ProceedingJoinPoint call)&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; throws Throwable {&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; String[] requiredRoles = null;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; MethodSignature ms =&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; (MethodSignature)call.getSignature();&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Method m = ms.getMethod(); //lets check it for the&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;nbsp; // RolesAllowed annotation&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; RolesAllowed roles = m.getAnnotation(RolesAllowed.class);&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; if(roles != null){&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; requiredRoles = roles.value();&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; for(String role : requiredRoles){&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; if(SecurityHelper.isInRole(role)){&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; //ok, no problem, lets continue &lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; //with the call&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; requiredRoles = null; //since we can now&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; // carry out the call&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; break;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; if(requiredRoles == null){&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Object returnValue = call.proceed();&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; return returnValue;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }else{&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; String rrs = &amp;quot;[&amp;quot;;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; for(String s : requiredRoles){&lt;br /&gt;
&lt;/code&gt;&lt;code&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/code&gt;&lt;code&gt;rrs += s + &amp;quot;, &amp;quot;;&lt;br /&gt;
&lt;/code&gt;&lt;code&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/code&gt;&lt;code&gt;}&lt;br /&gt;
&lt;/code&gt;&lt;code&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/code&gt;&lt;code&gt;rrs = rrs.substring(0, rrs.length() - 2) + &amp;quot;]&amp;quot;;&lt;br /&gt;
&lt;/code&gt;&lt;code&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;br /&gt;
&lt;/code&gt;&lt;code&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/code&gt;&lt;code&gt;throw new SecurityException(&amp;quot;To call [&amp;quot; +&lt;br /&gt;
&lt;/code&gt;&lt;code&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/code&gt;&lt;code&gt;call.getSignature().toLongString() +&lt;br /&gt;
&lt;/code&gt;&lt;code&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/code&gt;&lt;code&gt;&amp;quot;] the user must be authenticated and &amp;quot; +&lt;br /&gt;
&lt;/code&gt;&lt;code&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;quot;&lt;/code&gt;&lt;code&gt;authorized &lt;/code&gt;&lt;code&gt;in these roles: &amp;quot; + rrs);&lt;br /&gt;
&lt;/code&gt;&lt;code&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&lt;/code&gt;&lt;code&gt;}&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;
&amp;nbsp;&lt;/code&gt;&lt;br /&gt;
The annotation is defined as such: &lt;br /&gt;
&lt;code&gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; @Retention(value=RetentionPolicy.RUNTIME)&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; @Target(value={ElementType.METHOD})&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; public @interface RolesAllowed {&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; String[] value();&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; } &lt;/code&gt;&lt;br /&gt;
&lt;br /&gt;
The annotation is used like this, on all service methods requiring security: &lt;br /&gt;
&lt;code&gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; @RolesAllowed (&amp;quot;registered&amp;quot;)&amp;nbsp;&lt;/code&gt;&lt;br /&gt;
&amp;nbsp;&lt;br /&gt;
What I now have is a simple library which I can configure using a Filter and an Aspect. Additionally to allow the user to log in in the first place, I can use a standard Java EE security constraint in my web application. The standard steps to use this security extension of Spring would be: &lt;/p&gt;
&lt;ul&gt;
    &lt;li&gt;Add a security constraint to the web application&lt;/li&gt;
    &lt;li&gt;Add the annotation to the service methods requiring security&lt;/li&gt;
    &lt;li&gt;Add the filter to the web application&lt;/li&gt;
    &lt;li&gt;Add the aspect to the Spring configuration&lt;/li&gt;
    &lt;li&gt;Add the library to the classpath&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;I understand that Spring does not want you to need a dependency on Java EE, but on the other hand if I have that dependency due to other requirements, I do not want to have to configure my application using a third party security concept (Spring) as opposed to a standard one (Java EE). Spring Security is not even part of Standard Spring - it is downloaded seperately. The more extensions you use, the more skills your developers need. The maxant Spring Security extension provides a very simple way to secure your service methods. &lt;br /&gt;
&lt;br /&gt;
Download the library including source code &lt;a href=&#034;http://www.maxant.co.uk/tools.jsp#maxantSpringSecurity&#034;&gt;here&lt;/a&gt;. &lt;br /&gt;
&lt;br /&gt;
Copyright (c) 2009 Ant Kutschera&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;div class=&#034;tags&#034;&gt;&lt;span&gt;Social Bookmarks : &lt;/span&gt;&amp;nbsp;&lt;a href=&#034;http://slashdot.org/bookmark.pl?url=http://blog.maxant.co.uk:80/pebble/2009/06/02/1243967400000.html&amp;amp;title=Java+EE+Security+and+Spring&#034; target=&#034;_blank&#034; title=&#034;Add this post to Slash Dot&#034;&gt;&lt;img src=&#034;common/images/slashdot.png&#034; alt=&#034;Add this post to Slashdot&#034; border=&#034;0&#034; /&gt;&lt;/a&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;a href=&#034;http://digg.com/submit?url=http://blog.maxant.co.uk:80/pebble/2009/06/02/1243967400000.html&amp;amp;title=Java+EE+Security+and+Spring&#034; target=&#034;_blank&#034; title=&#034;Digg this post&#034;&gt;&lt;img src=&#034;common/images/digg.png&#034; alt=&#034;Add this post to Digg&#034; border=&#034;0&#034; /&gt;&lt;/a&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;a href=&#034;http://reddit.com/submit?url=http://blog.maxant.co.uk:80/pebble/2009/06/02/1243967400000.html&amp;amp;title=Java+EE+Security+and+Spring&#034; target=&#034;_blank&#034; title=&#034;Add this post to Reddit&#034;&gt;&lt;img src=&#034;common/images/reddit.png&#034; alt=&#034;Add this post to Reddit&#034; border=&#034;0&#034; /&gt;&lt;/a&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;a href=&#034;http://del.icio.us/post?url=http://blog.maxant.co.uk:80/pebble/2009/06/02/1243967400000.html&amp;amp;title=Java+EE+Security+and+Spring&#034; target=&#034;_blank&#034; title=&#034;Save this post to Del.icio.us&#034;&gt;&lt;img src=&#034;common/images/delicious.png&#034; alt=&#034;Add this post to Delicious&#034; border=&#034;0&#034; /&gt;&lt;/a&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;a href=&#034;http://www.stumbleupon.com/submit?url=http://blog.maxant.co.uk:80/pebble/2009/06/02/1243967400000.html&amp;amp;title=Java+EE+Security+and+Spring&#034; target=&#034;_blank&#034; title=&#034;Stumble this post&#034;&gt;&lt;img src=&#034;common/images/stumbleupon.png&#034; alt=&#034;Add this post to Stumble it&#034; border=&#034;0&#034; /&gt;&lt;/a&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;a href=&#034;http://www.google.com/bookmarks/mark?op=edit&amp;amp;bkmk=http://blog.maxant.co.uk:80/pebble/2009/06/02/1243967400000.html&amp;amp;title=Java+EE+Security+and+Spring&#034; target=&#034;_blank&#034; title=&#034;Add this post to Google&#034;&gt;&lt;img src=&#034;common/images/google.png&#034; alt=&#034;Add this post to Google&#034; border=&#034;0&#034; /&gt;&lt;/a&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;a href=&#034;http://technorati.com/faves?add=http://blog.maxant.co.uk:80/pebble/2009/06/02/1243967400000.html&#034; target=&#034;_blank&#034; title=&#034;Add this post to Technorati&#034;&gt;&lt;img src=&#034;common/images/technorati.png&#034; alt=&#034;Add this post to Technorati&#034; border=&#034;0&#034; /&gt;&lt;/a&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;a href=&#034;http://www.bloglines.com/sub/http://blog.maxant.co.uk:80/pebble/2009/06/02/1243967400000.html&#034; target=&#034;_blank&#034; title=&#034;Add this post to Bloglines&#034;&gt;&lt;img src=&#034;common/images/bloglines.png&#034; alt=&#034;Add this post to Bloglines&#034; border=&#034;0&#034; /&gt;&lt;/a&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;a href=&#034;http://www.facebook.com/share.php?u=http://blog.maxant.co.uk:80/pebble/2009/06/02/1243967400000.html&#034; target=&#034;_blank&#034; title=&#034;Add this post to Facebook&#034;&gt;&lt;img src=&#034;common/images/facebook.png&#034; alt=&#034;Add this post to Facebook&#034; border=&#034;0&#034; /&gt;&lt;/a&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;a href=&#034;http://www.furl.net/storeIt.jsp?u=http://blog.maxant.co.uk:80/pebble/2009/06/02/1243967400000.html&amp;amp;t=Java+EE+Security+and+Spring&#034; target=&#034;_blank&#034; title=&#034;Add this post to Furl&#034;&gt;&lt;img src=&#034;common/images/furl.png&#034; alt=&#034;Add this post to Furl&#034; border=&#034;0&#034; /&gt;&lt;/a&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;a href=&#034;https://favorites.live.com/quickadd.aspx?mkt=en-us&amp;amp;url=http://blog.maxant.co.uk:80/pebble/2009/06/02/1243967400000.html&amp;amp;title=Java+EE+Security+and+Spring&#034; target=&#034;_blank&#034; title=&#034;Add this post to Windows Live&#034;&gt;&lt;img src=&#034;common/images/windowslive.png&#034; alt=&#034;Add this post to Windows Live&#034; border=&#034;0&#034; /&gt;&lt;/a&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;a href=&#034;http://bookmarks.yahoo.com/toolbar/savebm?opener=tb&amp;amp;u=http://blog.maxant.co.uk:80/pebble/2009/06/02/1243967400000.html&amp;amp;t=Java+EE+Security+and+Spring&#034; target=&#034;_blank&#034; title=&#034;Add this post to Yahoo!&#034;&gt;&lt;img src=&#034;common/images/yahoo.png&#034; alt=&#034;Add this post to Yahoo!&#034; border=&#034;0&#034; /&gt;&lt;/a&gt;&lt;/div&gt;
        </description>
      
      
    
    
    
    <comments>http://blog.maxant.co.uk:80/pebble/2009/06/02/1243967400000.html#comments</comments>
    <guid isPermaLink="true">http://blog.maxant.co.uk:80/pebble/2009/06/02/1243967400000.html</guid>
    <pubDate>Tue, 02 Jun 2009 18:30:00 GMT</pubDate>
  </item>
  
  <item>
    <title>Spring Services Anywhere</title>
    <link>http://blog.maxant.co.uk:80/pebble/2008/08/07/1218142260000.html</link>
    
      
        <description>
          &lt;p&gt;I recently embarked on some &lt;a target=&#034;_blank&#034; href=&#034;http://www.springframework.org&#034;&gt;Spring&lt;/a&gt; &amp;quot;re-training&amp;quot; (I haven&#039;t looked at it in a few years and it was time to get my skills up to scratch again). Since the last time I looked at Spring, I have worked on a couple of rich (thick) client projects where  it was almost impossible to find people with both server skills and GUI skills (the market is quite good at the moment and people like me with all those skills get snapped up very quickly  &lt;img alt=&#034;&#034; src=&#034;/pebble/images/smiley.jpg&#034; /&gt;). &lt;br /&gt;
&lt;br /&gt;
Anyway, since it is hard to find strong GUI programmers who also know how to deploy an app server and start it,  it becomes desirable to be able to run the services inside the same JVM as the GUI programmer is developing in. There is then no wasted time due to EJB configurations and all the crap that comes with server development. &lt;br /&gt;
&lt;br /&gt;
About 18 months ago, I got around the problem by quickly implementing a &lt;a href=&#034;/pebble/2007/01/18/1169153820000.html&#034;&gt;clever service locator&lt;/a&gt;. It worked brilliantly, the only  real problem being that we had a few bugs because people had developed code which worked when services were local but not when they were remote. The effort in fixing those bugs was however minimal. &lt;br /&gt;
&lt;br /&gt;
On my current project, we are using a proprietary framework based on Inversion of Control and Dependency Injection. Based upon its configuration, a client can call services locally or remotely too. If calling services  remotely, they are invoked inside a stateless session bean which uses reflection and proxies in order to load the  service and call its method. Transaction and security inteceptors are also in place ensuring that the services are called in the correct context. It is all very clever, but sadly proprietary (although at least we have the source code!). &lt;br /&gt;
&lt;br /&gt;
Anyway, so as I am reading up on Spring, I am reminded how it too is intended to provide services independently of the environment in which it is running (that is, whether it is running in a stand alone application, inside a web container or an EJB container). &lt;br /&gt;
&lt;br /&gt;
However, there is a marked difference compared to my Service Locator solution and the proprietary solution of my  current project. In Spring, services are not automatically &amp;quot;remoted&amp;quot;. To move services from a standalone application to run inside an EJB container, you need to write code which sits between the client and those services to allow them to be called. &lt;br /&gt;
&lt;br /&gt;
In EJB 3.0, a stateless session bean is simply a POJO. If it is not deployed in a server, a standalone application which has that POJO on its classpath can call a method in the POJO (admittedly without security or transaction  functionality). &lt;br /&gt;
&lt;br /&gt;
In Spring, you deploy your service to a Web or EJB Container and that container can use the services, but the  client is no longer able to call those services. At the best, you can &amp;quot;remote&amp;quot; your service so that it can  be called through its interface, however, it will live inside the web container. If you want the client to  be able to call your service that is now in the EJB container, you need to write an EJB with the correct  interface to expose that services functionality.  &lt;br /&gt;
&lt;br /&gt;
Now, is that a problem? What&#039;s wrong with just using the web container or indeed just a  web server? Ahhh... its not capable of handling transactions, I hear you say. True, but Spring provides mechanisms for applying a transactional context to your services. You can even use the transaction manager from your application server, so it will provide the same transactional  functionality as provided to EJBs (for example XA compliant and having the ability to run across nodes in a cluster). &lt;br /&gt;
&lt;br /&gt;
OK, OK, the web container doesn&#039;t provide security to service methods!  Well, also not true, since you can use declarative and programmatic security from the web container to ensure the user can only use functionality for which they are authorised. &lt;br /&gt;
&lt;br /&gt;
OK, but the web container isn&#039;t scalable/reliable/robust! Also not true, just like the EJB container, it has the  ability to synchronise state across a cluster. And running in a cluster also means it is scalable, reliable and robust. &lt;br /&gt;
&lt;br /&gt;
So, you might now start to agree, that actually, there is no need to run in an application server. Everything you do day in and day out can now be handled by Spring in the web container, ie. by a friendly cluster-aware web server like Apache Tomcat... &lt;br /&gt;
&lt;br /&gt;
I wouldn&#039;t disagree with that statement. However, here are some reasons to run inside a full application server:&lt;/p&gt;
&lt;ul&gt;
    &lt;li&gt;You need a JTA Transaction manager capable of propagating transactions across nodes in a cluster,&lt;/li&gt;
    &lt;li&gt;The enterprise architecture department in charge of specifying the environment you run in is also 	capable of specifying that services must run in the EJB layer,&lt;/li&gt;
    &lt;li&gt;You need to receive JMS messages in message beans&lt;/li&gt;
    &lt;li&gt;You need to use Timer Beans&lt;/li&gt;
    &lt;li&gt;You need a clustered JNDI tree as provided by your application server&lt;/li&gt;
    &lt;li&gt;You need access to resources which your application server can provide and manage (eg. JCA)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;If you don&#039;t have any of these constraints, an you are committed to using Spring, then I currently do not see many reasons to run in anything other than a Java EE compliant Web Container. If you can think of other reasons  to run in a full application server, please leave comments below. &lt;/p&gt;&lt;div class=&#034;tags&#034;&gt;&lt;span&gt;Social Bookmarks : &lt;/span&gt;&amp;nbsp;&lt;a href=&#034;http://slashdot.org/bookmark.pl?url=http://blog.maxant.co.uk:80/pebble/2008/08/07/1218142260000.html&amp;amp;title=Spring+Services+Anywhere&#034; target=&#034;_blank&#034; title=&#034;Add this post to Slash Dot&#034;&gt;&lt;img src=&#034;common/images/slashdot.png&#034; alt=&#034;Add this post to Slashdot&#034; border=&#034;0&#034; /&gt;&lt;/a&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;a href=&#034;http://digg.com/submit?url=http://blog.maxant.co.uk:80/pebble/2008/08/07/1218142260000.html&amp;amp;title=Spring+Services+Anywhere&#034; target=&#034;_blank&#034; title=&#034;Digg this post&#034;&gt;&lt;img src=&#034;common/images/digg.png&#034; alt=&#034;Add this post to Digg&#034; border=&#034;0&#034; /&gt;&lt;/a&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;a href=&#034;http://reddit.com/submit?url=http://blog.maxant.co.uk:80/pebble/2008/08/07/1218142260000.html&amp;amp;title=Spring+Services+Anywhere&#034; target=&#034;_blank&#034; title=&#034;Add this post to Reddit&#034;&gt;&lt;img src=&#034;common/images/reddit.png&#034; alt=&#034;Add this post to Reddit&#034; border=&#034;0&#034; /&gt;&lt;/a&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;a href=&#034;http://del.icio.us/post?url=http://blog.maxant.co.uk:80/pebble/2008/08/07/1218142260000.html&amp;amp;title=Spring+Services+Anywhere&#034; target=&#034;_blank&#034; title=&#034;Save this post to Del.icio.us&#034;&gt;&lt;img src=&#034;common/images/delicious.png&#034; alt=&#034;Add this post to Delicious&#034; border=&#034;0&#034; /&gt;&lt;/a&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;a href=&#034;http://www.stumbleupon.com/submit?url=http://blog.maxant.co.uk:80/pebble/2008/08/07/1218142260000.html&amp;amp;title=Spring+Services+Anywhere&#034; target=&#034;_blank&#034; title=&#034;Stumble this post&#034;&gt;&lt;img src=&#034;common/images/stumbleupon.png&#034; alt=&#034;Add this post to Stumble it&#034; border=&#034;0&#034; /&gt;&lt;/a&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;a href=&#034;http://www.google.com/bookmarks/mark?op=edit&amp;amp;bkmk=http://blog.maxant.co.uk:80/pebble/2008/08/07/1218142260000.html&amp;amp;title=Spring+Services+Anywhere&#034; target=&#034;_blank&#034; title=&#034;Add this post to Google&#034;&gt;&lt;img src=&#034;common/images/google.png&#034; alt=&#034;Add this post to Google&#034; border=&#034;0&#034; /&gt;&lt;/a&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;a href=&#034;http://technorati.com/faves?add=http://blog.maxant.co.uk:80/pebble/2008/08/07/1218142260000.html&#034; target=&#034;_blank&#034; title=&#034;Add this post to Technorati&#034;&gt;&lt;img src=&#034;common/images/technorati.png&#034; alt=&#034;Add this post to Technorati&#034; border=&#034;0&#034; /&gt;&lt;/a&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;a href=&#034;http://www.bloglines.com/sub/http://blog.maxant.co.uk:80/pebble/2008/08/07/1218142260000.html&#034; target=&#034;_blank&#034; title=&#034;Add this post to Bloglines&#034;&gt;&lt;img src=&#034;common/images/bloglines.png&#034; alt=&#034;Add this post to Bloglines&#034; border=&#034;0&#034; /&gt;&lt;/a&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;a href=&#034;http://www.facebook.com/share.php?u=http://blog.maxant.co.uk:80/pebble/2008/08/07/1218142260000.html&#034; target=&#034;_blank&#034; title=&#034;Add this post to Facebook&#034;&gt;&lt;img src=&#034;common/images/facebook.png&#034; alt=&#034;Add this post to Facebook&#034; border=&#034;0&#034; /&gt;&lt;/a&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;a href=&#034;http://www.furl.net/storeIt.jsp?u=http://blog.maxant.co.uk:80/pebble/2008/08/07/1218142260000.html&amp;amp;t=Spring+Services+Anywhere&#034; target=&#034;_blank&#034; title=&#034;Add this post to Furl&#034;&gt;&lt;img src=&#034;common/images/furl.png&#034; alt=&#034;Add this post to Furl&#034; border=&#034;0&#034; /&gt;&lt;/a&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;a href=&#034;https://favorites.live.com/quickadd.aspx?mkt=en-us&amp;amp;url=http://blog.maxant.co.uk:80/pebble/2008/08/07/1218142260000.html&amp;amp;title=Spring+Services+Anywhere&#034; target=&#034;_blank&#034; title=&#034;Add this post to Windows Live&#034;&gt;&lt;img src=&#034;common/images/windowslive.png&#034; alt=&#034;Add this post to Windows Live&#034; border=&#034;0&#034; /&gt;&lt;/a&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;a href=&#034;http://bookmarks.yahoo.com/toolbar/savebm?opener=tb&amp;amp;u=http://blog.maxant.co.uk:80/pebble/2008/08/07/1218142260000.html&amp;amp;t=Spring+Services+Anywhere&#034; target=&#034;_blank&#034; title=&#034;Add this post to Yahoo!&#034;&gt;&lt;img src=&#034;common/images/yahoo.png&#034; alt=&#034;Add this post to Yahoo!&#034; border=&#034;0&#034; /&gt;&lt;/a&gt;&lt;/div&gt;
        </description>
      
      
    
    
    
    <comments>http://blog.maxant.co.uk:80/pebble/2008/08/07/1218142260000.html#comments</comments>
    <guid isPermaLink="true">http://blog.maxant.co.uk:80/pebble/2008/08/07/1218142260000.html</guid>
    <pubDate>Thu, 07 Aug 2008 20:51:00 GMT</pubDate>
  </item>
  
  <item>
    <title>Secure Remoting with Spring and JBoss</title>
    <link>http://blog.maxant.co.uk:80/pebble/2008/08/07/1218135480000.html</link>
    
      
        <description>
          &lt;p&gt;If you are faced with having to write a rich client application in a multi-tier Java EE environment, you will typically connect to the application server over RMI. In theory, you are meant to use the servers Application Client Container and deploy your application as a client in that container. You probably won&#039;t do that though, because the client container is unfriendly for many reasons:&lt;/p&gt;
&lt;ol&gt;
    &lt;li&gt;As an example, the WebSphere 6.1 Client Container is a 200 megabyte install,&lt;/li&gt;
    &lt;li&gt;Client Containers tend to be started as batch commands which set up the environment in which your application will run. If you however have an application that is meant to be started with a sexy launcher, as is the case with Eclipse RCP applications, you will struggle to get the environment created properly by the launcher, and its not supported by the vendor anyway,&lt;/li&gt;
    &lt;li&gt;If you need to connect to the server securely (ie. so that serverside you have a valid security context allowing you to authorise users to call given services), then I personally have never been able to get the security callback mechanism to work. Theoretically you can tell the container to call your code at the point which it logs on to the server in order to get the credentials (eg. you can pop up a little login window),&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;For these reasons, I have never ever used a client container in a production environment. Instead I have repeatedly gone to the trouble of getting the client environment fit so that it can call the server over RMI with a security context. The problem is not only that this is painful, but that it is unsupported by the App Server vendor, and is almost guaranteed to break with the next release of the App Server, requiring further pain from a consultant in order to get be able to migrate to the next App Server version. Additionally, setting the environment for the Initial Context in a client, to connect to the server and find objects in the JNDI tree can be difficult and is often poorly documented (after all, you are meant to do it from inside the client container where you do not need to provide the environment yourself). &lt;br /&gt;
&lt;br /&gt;
However, there is another way! In a &lt;a href=&#034;/pebble/2007/12/01/1196542920000.html&#034;&gt;previous article&lt;/a&gt;, I wrote about how I got an applet to send information back to the server by implementing a custom protocol containing serialised objects. In hindsight I discovered Hessian from &lt;a target=&#034;_blank&#034; href=&#034;http://www.caucho.com&#034;&gt;Caucho&lt;/a&gt; which does a similar thing. Recently I have been looking into &lt;a target=&#034;_blank&#034; href=&#034;http://www.springframework.org&#034;&gt;Spring&lt;/a&gt; which supports Hessian (Custom Binary over HTTP), Burlap (XML over HTTP) and its own kind of remoting, namely Java Serialisation over HTTP.&lt;br /&gt;
&lt;br /&gt;
With little effort I was able to find out how to secure the HTTP connection with the server, meaning that I am now free to write an arbitrary rich client who can call services in a Java EE environment without the use of a Client Container, and without a non-supported RMI environment that is likely to not work after a server version migration. Woo Hoo! How? Easy, keep reading... &lt;br /&gt;
&lt;br /&gt;
First, lets start with a little diagram: &lt;br /&gt;
&lt;br /&gt;
&lt;img alt=&#034;&#034; src=&#034;/pebble/images/secure_remoting1.jpg&#034; /&gt; &lt;br /&gt;
&lt;br /&gt;
This article won&#039;t go into detail about how to create an RCP application or plugin, and will simply call the remote service from a simple Java application. The steps involved in getting to where we are going are:&lt;/p&gt;
&lt;ol&gt;
    &lt;li&gt;Add a Datasource to JBoss&lt;/li&gt;
    &lt;li&gt;Add Security to JBoss (using the datasource, although LDAP would be an option too)&lt;/li&gt;
    &lt;li&gt;Create a Web Application containing the service implementation&lt;/li&gt;
    &lt;li&gt;Create a client capable of calling the remote service&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;strong&gt;&lt;u&gt;1) Add a datasource to JBoss&lt;/u&gt;&lt;/strong&gt; &lt;br /&gt;
&lt;br /&gt;
For this article, JBoss 4.2.2 was used. To add a datasource, create a configuration file: &lt;br /&gt;
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;code&gt;&amp;lt;JBoss-Home&amp;gt;/server/&amp;lt;instance&amp;gt;/deploy/mysql-ds.xml&lt;/code&gt;&lt;br /&gt;
&lt;br /&gt;
where &amp;lt;instance&amp;gt; was &amp;quot;default&amp;quot; in the case of this example. This example uses MySQL 4.1. This configuration file should contain the following: &lt;br /&gt;
&lt;textarea readonly=&#034;true&#034; rows=&#034;10&#034; cols=&#034;60&#034;&gt;&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;UTF-8&amp;quot;?&amp;gt; &amp;lt;datasources&amp;gt;   &amp;lt;local-tx-datasource&amp;gt;     &amp;lt;jndi-name&amp;gt;jdbc/MySqlDS&amp;lt;/jndi-name&amp;gt; 	&amp;lt;connection-url&amp;gt;jdbc:mysql://localhost:3306/test&amp;lt;/connection-url&amp;gt; 	&amp;lt;driver-class&amp;gt;com.mysql.jdbc.Driver&amp;lt;/driver-class&amp;gt; 	&amp;lt;user-name&amp;gt;user&amp;lt;/user-name&amp;gt; 	&amp;lt;password&amp;gt;changeit&amp;lt;/password&amp;gt;     &amp;lt;exception-sorter-class-name&amp;gt;org.jboss.resource.adapter.jdbc.vendor.MySQLExceptionSorter&amp;lt;/exception-sorter-class-name&amp;gt; 	&amp;lt;valid-connection-checker-class-name&amp;gt;org.jboss.resource.adapter.jdbc.vendor.MySQLValidConnectionChecker&amp;lt;/valid-connection-checker-class-name&amp;gt;     &amp;lt;check-valid-connection-sql&amp;gt;select 1&amp;lt;/check-valid-connection-sql&amp;gt;      &lt;!-- corresponding type-mapping in the standardjbosscmp-jdbc.xml --&gt;     &amp;lt;metadata&amp;gt;        &amp;lt;type-mapping&amp;gt;mySQL&amp;lt;/type-mapping&amp;gt;     &amp;lt;/metadata&amp;gt;   &amp;lt;/local-tx-datasource&amp;gt; &amp;lt;/datasources&amp;gt; &lt;/textarea&gt;&lt;br /&gt;
&lt;br /&gt;
A restart of JBoss will make this datasource available in JNDI under the name &lt;code&gt;java:/jdbc/MySqlDS&lt;/code&gt;. &lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;&lt;u&gt;2. Add Security to JBoss&lt;/u&gt;&lt;/b&gt; &lt;br /&gt;
&lt;br /&gt;
Add the following application policy to:&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;&lt;code&gt;JBoss-Home&amp;gt;/server/&amp;lt;instance&amp;gt;/conf/login-config.xml&lt;/code&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;textarea readonly=&#034;true&#034; cols=&#034;60&#034; rows=&#034;10&#034;&gt;     &amp;lt;application-policy name=&amp;quot;SpringWeb&amp;quot;&amp;gt;         &amp;lt;authentication&amp;gt;             &amp;lt;login-module code=&amp;quot;org.jboss.security.auth.spi.DatabaseServerLoginModule&amp;quot;                              flag=&amp;quot;required&amp;quot;&amp;gt;                 &amp;lt;module-option name=&amp;quot;dsJndiName&amp;quot;&amp;gt;java:/jdbc/MySqlDS&amp;lt;/module-option&amp;gt;                 &amp;lt;module-option name=&amp;quot;principalsQuery&amp;quot;&amp;gt;                     select password from users username where username=?&amp;lt;/module-option&amp;gt;                 &amp;lt;module-option name=&amp;quot;rolesQuery&amp;quot;&amp;gt;                     select role, &#039;Roles&#039; from roles where username=?&amp;lt;/module-option&amp;gt;             &amp;lt;/login-module&amp;gt;         &amp;lt;/authentication&amp;gt;     &amp;lt;/application-policy&amp;gt; &lt;/textarea&gt; &lt;br /&gt;
&lt;br /&gt;
Before it can work, you will need to add two tables to the database. The following is some SQL to do that: &lt;br /&gt;
&lt;br /&gt;
&lt;textarea readonly=&#034;true&#034; rows=&#034;10&#034; cols=&#034;60&#034;&gt; create table users( 	username varchar(64),  	password varchar(64), 	primary key (username) ) type = innodb;  create table roles( 	username varchar(64),  	role varchar(64),  	foreign key (username) references users(username), 	index (username) ) type = innodb;  insert into users values(&#039;admin2&#039;, &#039;admin2&#039;);  insert into roles  values(&#039;admin2&#039;, &#039;registered&#039;); &lt;/textarea&gt; &lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;&lt;u&gt;3) Create Web App&lt;/u&gt;&lt;/b&gt; &lt;br /&gt;
&lt;br /&gt;
To create the web application you need the following files: &lt;br /&gt;
&lt;br /&gt;
&lt;img alt=&#034;&#034; src=&#034;/pebble/images/secure_remoting2.jpg&#034; /&gt; &lt;br /&gt;
&lt;br /&gt;
&lt;code&gt;web.xml&lt;/code&gt; contains:&lt;br /&gt;
&lt;textarea readonly=&#034;true&#034; rows=&#034;10&#034; cols=&#034;60&#034;&gt; &amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;UTF-8&amp;quot;?&amp;gt; &amp;lt;web-app xmlns:xsi=&amp;quot;http://www.w3.org/2001/XMLSchema-instance&amp;quot; 	xmlns=&amp;quot;http://java.sun.com/xml/ns/javaee&amp;quot; xmlns:web=&amp;quot;http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd&amp;quot; 	xsi:schemaLocation=&amp;quot;http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd&amp;quot; 	id=&amp;quot;WebApp_ID&amp;quot; version=&amp;quot;2.5&amp;quot;&amp;gt; 	&amp;lt;display-name&amp;gt;SpringWeb&amp;lt;/display-name&amp;gt;  	&amp;lt;context-param&amp;gt; 		&amp;lt;param-name&amp;gt;contextConfigLocation&amp;lt;/param-name&amp;gt; 		&amp;lt;param-value&amp;gt;/WEB-INF/applicationContext.xml&amp;lt;/param-value&amp;gt; 	&amp;lt;/context-param&amp;gt;  	&amp;lt;listener&amp;gt; 		&amp;lt;listener-class&amp;gt;org.springframework.web.context.ContextLoaderListener&amp;lt;/listener-class&amp;gt; 	&amp;lt;/listener&amp;gt;  	&amp;lt;servlet&amp;gt; 		&amp;lt;servlet-name&amp;gt;remoting&amp;lt;/servlet-name&amp;gt; 		&amp;lt;servlet-class&amp;gt;org.springframework.web.servlet.DispatcherServlet&amp;lt;/servlet-class&amp;gt; 		&amp;lt;load-on-startup&amp;gt;1&amp;lt;/load-on-startup&amp;gt; 	&amp;lt;/servlet&amp;gt;  	&amp;lt;servlet-mapping&amp;gt; 		&amp;lt;servlet-name&amp;gt;remoting&amp;lt;/servlet-name&amp;gt; 		&amp;lt;url-pattern&amp;gt;/remoting/*&amp;lt;/url-pattern&amp;gt; 	&amp;lt;/servlet-mapping&amp;gt;     &amp;lt;security-constraint&amp;gt;     	&amp;lt;display-name&amp;gt;secure remoting&amp;lt;/display-name&amp;gt; 		&amp;lt;web-resource-collection&amp;gt; 			&amp;lt;web-resource-name&amp;gt;secure&amp;lt;/web-resource-name&amp;gt; 			&amp;lt;url-pattern&amp;gt;/secure/*&amp;lt;/url-pattern&amp;gt; 			&amp;lt;url-pattern&amp;gt;/remoting/*&amp;lt;/url-pattern&amp;gt; 		&amp;lt;/web-resource-collection&amp;gt; 		&amp;lt;auth-constraint&amp;gt; 			&amp;lt;role-name&amp;gt;registered&amp;lt;/role-name&amp;gt; 		&amp;lt;/auth-constraint&amp;gt; 		&amp;lt;user-data-constraint&amp;gt; 			&amp;lt;transport-guarantee&amp;gt;NONE&amp;lt;/transport-guarantee&amp;gt; 		&amp;lt;/user-data-constraint&amp;gt; 	&amp;lt;/security-constraint&amp;gt;  	&amp;lt;login-config&amp;gt;     	&amp;lt;auth-method&amp;gt;BASIC&amp;lt;/auth-method&amp;gt; 	&amp;lt;/login-config&amp;gt;    	&amp;lt;security-role&amp;gt; 		&amp;lt;role-name&amp;gt;registered&amp;lt;/role-name&amp;gt; 	&amp;lt;/security-role&amp;gt; &amp;lt;/web-app&amp;gt; &lt;/textarea&gt; &lt;br /&gt;
&lt;br /&gt;
In the above &lt;code&gt;web.xml&lt;/code&gt;, I have configured a Spring ContextLoaderListener which uses the  contextConfigLocation parameter to load the Spring configuration. A servlet has also been configured  for the URL pattern &amp;quot;remoting&amp;quot; and this URL pattern has also been secured, requiring basic  authentication in order to be requested. &lt;br /&gt;
&lt;br /&gt;
&lt;code&gt;remoting-servlet.xml&lt;/code&gt; contains:&lt;br /&gt;
&lt;textarea readonly=&#034;true&#034; rows=&#034;10&#034; cols=&#034;60&#034;&gt; &amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;UTF-8&amp;quot; ?&amp;gt; &amp;lt;beans&amp;gt; 	&amp;lt;bean name=&amp;quot;/TestService&amp;quot; class=&amp;quot;org.springframework.remoting.httpinvoker.HttpInvokerServiceExporter&amp;quot;&amp;gt; 		&amp;lt;property name=&amp;quot;service&amp;quot; ref=&amp;quot;testService&amp;quot;&amp;gt;&amp;lt;/property&amp;gt; 		&amp;lt;property name=&amp;quot;serviceInterface&amp;quot; value=&amp;quot;uk.co.maxant.test.spring.service.TestService&amp;quot;&amp;gt;&amp;lt;/property&amp;gt; 	&amp;lt;/bean&amp;gt; &amp;lt;/beans&amp;gt; &lt;/textarea&gt; &lt;br /&gt;
&lt;br /&gt;
The above &lt;code&gt;remoting-servlet.xml&lt;/code&gt; is firstly named after the dispatcher servlet which was defined in  &lt;code&gt;web.xml&lt;/code&gt;. Secondly, it defines the service exporter and our service that we wish to make  remote, namely &amp;quot;TestService&amp;quot;. What is missing from the above is the definition of the &amp;quot;testService&amp;quot; bean.  That definition is located under the &lt;code&gt;applicationContext.xml&lt;/code&gt;: &lt;br /&gt;
&lt;textarea readonly=&#034;true&#034; rows=&#034;10&#034; cols=&#034;60&#034;&gt; &amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;UTF-8&amp;quot;?&amp;gt; &amp;lt;beans xmlns=&amp;quot;http://www.springframework.org/schema/beans&amp;quot;&amp;gt; 	&amp;lt;bean id=&amp;quot;testService&amp;quot; class=&amp;quot;uk.co.maxant.test.spring.service.TestServiceImpl&amp;quot; &amp;gt;&amp;lt;/bean&amp;gt; &amp;lt;/beans&amp;gt; &lt;/textarea&gt; That bean definition could equally have actually been included in &lt;code&gt;remoting-servlet.xml&lt;/code&gt;.&lt;br /&gt;
Finally, the &lt;code&gt;jboss-web.xml&lt;/code&gt; file contains the link between the security policy that was added to  &lt;code&gt;login-config.xml&lt;/code&gt;, and the web application:&lt;br /&gt;
&lt;textarea readonly=&#034;true&#034; rows=&#034;10&#034; cols=&#034;60&#034;&gt; &amp;lt;?xml version=&#039;1.0&#039; encoding=&#039;UTF-8&#039; ?&amp;gt;   &amp;lt;!DOCTYPE jboss-web     PUBLIC &amp;quot;-//JBoss//DTD Web Application 2.3V2//EN&amp;quot;     &amp;quot;http://www.jboss.org/j2ee/dtd/jboss-web_3_2.dtd&amp;quot;&amp;gt;  &amp;lt;jboss-web&amp;gt;     &amp;lt;security-domain&amp;gt;java:/jaas/SpringWeb&amp;lt;/security-domain&amp;gt; &amp;lt;/jboss-web&amp;gt; &lt;/textarea&gt; &lt;br /&gt;
&lt;br /&gt;
Next, on the web app classpath, we need to have two classes, namely the service interface and its implementation. &lt;br /&gt;
&lt;textarea readonly=&#034;true&#034; rows=&#034;10&#034; cols=&#034;60&#034;&gt; package uk.co.maxant.test.spring.service;  public interface TestService {  	public String sayHello(String s) throws Exception; } &lt;/textarea&gt; &lt;textarea readonly=&#034;true&#034; rows=&#034;10&#034; cols=&#034;60&#034;&gt; package uk.co.maxant.test.spring.service;  import javax.naming.InitialContext;  import uk.co.maxant.test.TestBeanLocal;  public class TestServiceImpl implements TestService {  	public String sayHello(String s) throws Exception {  		//for example, we could call an EJB here 		InitialContext ctx = new InitialContext(); 		TestBeanLocal bean = (TestBeanLocal)ctx.lookup(&amp;quot;TestEAR/TestBean/local&amp;quot;); 		bean.doSomething();  		return &amp;quot;hi there &amp;quot; + s; 	}  } &lt;/textarea&gt; The web application now contains everything it needs to go. Restart JBoss and deploy the web application to it. &lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;&lt;u&gt;4) Create Client&lt;/u&gt;&lt;/b&gt; &lt;br /&gt;
All that is now left is to create a client that can call the remote service. Create a project with the following files:&lt;br /&gt;
&lt;img alt=&#034;&#034; src=&#034;/pebble/images/secure_remoting3.jpg&#034; /&gt; &lt;br /&gt;
&lt;br /&gt;
To start with, the &lt;code&gt;applicationContext.xml&lt;/code&gt; is a Spring configuration and looks like this: &lt;br /&gt;
&lt;textarea readonly=&#034;true&#034; rows=&#034;10&#034; cols=&#034;60&#034;&gt; &amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;UTF-8&amp;quot;?&amp;gt; &amp;lt;beans xmlns=&amp;quot;http://www.springframework.org/schema/beans&amp;quot;&amp;gt; 	&amp;lt;bean id=&amp;quot;basicAuthenticationInvokerRequestExecutor&amp;quot; 		class=&amp;quot;uk.co.maxant.spring.remoting.BasicAuthenticationInvokerRequestExecutor&amp;quot; &amp;gt; 	&amp;lt;/bean&amp;gt; 	&amp;lt;bean id=&amp;quot;testService&amp;quot; 		class=&amp;quot;org.springframework.remoting.httpinvoker.HttpInvokerProxyFactoryBean&amp;quot;&amp;gt; 		&amp;lt;property name=&amp;quot;serviceUrl&amp;quot; 			value=&amp;quot;http://localhost:8080/SpringWeb/remoting/TestService&amp;quot; &amp;gt;&amp;lt;/property&amp;gt; 		&amp;lt;property name=&amp;quot;serviceInterface&amp;quot; value=&amp;quot;uk.co.maxant.test.spring.service.TestService&amp;quot; &amp;gt;&amp;lt;/property&amp;gt; 		&amp;lt;property name=&amp;quot;httpInvokerRequestExecutor&amp;quot; ref=&amp;quot;basicAuthenticationInvokerRequestExecutor&amp;quot; &amp;gt;&amp;lt;/property&amp;gt; 	&amp;lt;/bean&amp;gt; &amp;lt;/beans&amp;gt; &lt;/textarea&gt; &lt;br /&gt;
In the Spring configuration above, the remote service is defined in terms of its URL and its interface class. The  &amp;quot;basicAuthenticationInvokerRequestExecutor&amp;quot; bean simply tells the &amp;quot;HttpInvokerProxyFactoryBean&amp;quot; to use a special InvokerRequestExecutor which is capable of logging into the service.  The &lt;code&gt;BasicAuthenticationInvokerRequestExecutor&lt;/code&gt; basically comes from a &lt;a target=&#034;_blank&#034; href=&#034;http://forum.springframework.org/showthread.php?t=17227&#034;&gt;Spring Forum&lt;/a&gt;, and is shown  in its modified form next:&lt;br /&gt;
&lt;textarea readonly=&#034;true&#034; rows=&#034;10&#034; cols=&#034;60&#034;&gt; package uk.co.maxant.spring.remoting;  import java.io.ByteArrayOutputStream; import java.io.IOException; import java.net.URI; import java.net.URISyntaxException; import java.util.ArrayList; import java.util.List;  import org.apache.commons.httpclient.Credentials; import org.apache.commons.httpclient.HttpClient; import org.apache.commons.httpclient.UsernamePasswordCredentials; import org.apache.commons.httpclient.auth.AuthPolicy; import org.springframework.remoting.httpinvoker.CommonsHttpInvokerRequestExecutor; import org.springframework.remoting.httpinvoker.HttpInvokerClientConfiguration; import org.springframework.remoting.support.RemoteInvocationResult;  public class BasicAuthenticationInvokerRequestExecutor extends CommonsHttpInvokerRequestExecutor {      private String username;      private String password;      private boolean httpClientStateSet = false;      public void setUsername(String username) {         this.username = username;         this.httpClientStateSet = false;     }      public synchronized void setPassword(String password) {         this.password = password;         this.httpClientStateSet = false;     }      protected RemoteInvocationResult doExecuteRequest(             final HttpInvokerClientConfiguration config,             final ByteArrayOutputStream baos) throws IOException,             ClassNotFoundException {         synchronized (this) {             if (!this.httpClientStateSet) {                 final HttpClient client = getHttpClient();                 final URI uri;                 try {                     uri = new URI(config.getServiceUrl());                 } catch (URISyntaxException e) {                     final IOException ioe = new IOException();                     ioe.initCause(e);                     throw ioe;                 }                 if (username != null &amp;amp;&amp;amp; password != null) {          			Credentials defaultcreds = new UsernamePasswordCredentials(         					username, password);         			         			//the URI created above, could be used to fill         			//in the port and host, but its not actually required.         			client.getState().setCredentials(null, null, defaultcreds);                      //This is to make HttpClient pick the Basic authentication         			//scheme over NTLM &amp;amp; Digest                     List&amp;lt;String&amp;gt; authPrefs = new ArrayList&amp;lt;String&amp;gt;(3);                     authPrefs.add(AuthPolicy.BASIC);                     authPrefs.add(AuthPolicy.NTLM);                     authPrefs.add(AuthPolicy.DIGEST);                     client.getParams().setParameter(                             AuthPolicy.AUTH_SCHEME_PRIORITY, authPrefs);                     client.getParams().setAuthenticationPreemptive(true);                 } else {                     throw new NullPointerException(                             &amp;quot;Username and Password cannot be null&amp;quot;);                 }                 this.httpClientStateSet = true;             }         }         return super.doExecuteRequest(config, baos);     } } &lt;/textarea&gt; &lt;br /&gt;
This class uses the Apache Commons HttpClient to use basic authentication when it logs into the  web application when it calls the remote service.&lt;br /&gt;
&lt;br /&gt;
Finally, the code which calls the remote service:&lt;br /&gt;
&lt;textarea readonly=&#034;true&#034; rows=&#034;10&#034; cols=&#034;60&#034;&gt; package uk.co.maxant.test.spring.remoting.client;  import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext;  import uk.co.maxant.spring.remoting.BasicAuthenticationInvokerRequestExecutor; import uk.co.maxant.test.spring.service.TestService;  public class RemoteClient {  	public static void main(String[] args) throws Throwable { 		ApplicationContext context =  			new ClassPathXmlApplicationContext(&amp;quot;applicationContext.xml&amp;quot;);  		Object obj = context.getBean(&amp;quot;basicAuthenticationInvokerRequestExecutor&amp;quot;); 		BasicAuthenticationInvokerRequestExecutor executor = (BasicAuthenticationInvokerRequestExecutor)obj; 		executor.setUsername(&amp;quot;admin2&amp;quot;); 		executor.setPassword(&amp;quot;admin2&amp;quot;);  		obj = context.getBean(&amp;quot;testService&amp;quot;); 		TestService service = (TestService)obj; 		 		String s = null; 		int NUM_CALLS = 100; 		long start = System.nanoTime(); 		for(int i = 0; i &amp;lt; NUM_CALLS; i++){ 			s = service.sayHello(&amp;quot;Remote client&amp;quot;); 		} 		System.out.println(&amp;quot;Remote service says: &amp;quot; + s + &amp;quot; (called on average in &amp;quot; + ((System.nanoTime()-start)/1000000.0/NUM_CALLS) + &amp;quot;ms).&amp;quot;); 	} } &lt;/textarea&gt; On thing missing in the above description, is that the client needs a reference to the service interface.  In this example, built in Eclipse 3.4, the client project simply has a reference to the web application project containing the service interface. In reality you would want to  have this interface in a client library which both the web application and the client can refer to. &lt;br /&gt;
&lt;br /&gt;
Now everything is in place to call services on a remote server from a client, securely, and independently of application server Client Container. I chose to use Spring HTTP Remoting with standard Java serialisation (as opposed to Hessian or Burlap, which have their own problems due to restrictive serialisation),  which locks the client and server to compatible Java versions. However, Java serialisation has not changed  much in a while and I have successfully tested a client running in Sun Java 1.3, calling a Sun Java 1.6 server! &lt;br /&gt;
&lt;br /&gt;
That is the end of this article, I hope it works for you, and gives you an insight into how to securely call services in a Java EE application server without the need to use the client container. Good Luck!&lt;/p&gt;&lt;div class=&#034;tags&#034;&gt;&lt;span&gt;Social Bookmarks : &lt;/span&gt;&amp;nbsp;&lt;a href=&#034;http://slashdot.org/bookmark.pl?url=http://blog.maxant.co.uk:80/pebble/2008/08/07/1218135480000.html&amp;amp;title=Secure+Remoting+with+Spring+and+JBoss&#034; target=&#034;_blank&#034; title=&#034;Add this post to Slash Dot&#034;&gt;&lt;img src=&#034;common/images/slashdot.png&#034; alt=&#034;Add this post to Slashdot&#034; border=&#034;0&#034; /&gt;&lt;/a&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;a href=&#034;http://digg.com/submit?url=http://blog.maxant.co.uk:80/pebble/2008/08/07/1218135480000.html&amp;amp;title=Secure+Remoting+with+Spring+and+JBoss&#034; target=&#034;_blank&#034; title=&#034;Digg this post&#034;&gt;&lt;img src=&#034;common/images/digg.png&#034; alt=&#034;Add this post to Digg&#034; border=&#034;0&#034; /&gt;&lt;/a&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;a href=&#034;http://reddit.com/submit?url=http://blog.maxant.co.uk:80/pebble/2008/08/07/1218135480000.html&amp;amp;title=Secure+Remoting+with+Spring+and+JBoss&#034; target=&#034;_blank&#034; title=&#034;Add this post to Reddit&#034;&gt;&lt;img src=&#034;common/images/reddit.png&#034; alt=&#034;Add this post to Reddit&#034; border=&#034;0&#034; /&gt;&lt;/a&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;a href=&#034;http://del.icio.us/post?url=http://blog.maxant.co.uk:80/pebble/2008/08/07/1218135480000.html&amp;amp;title=Secure+Remoting+with+Spring+and+JBoss&#034; target=&#034;_blank&#034; title=&#034;Save this post to Del.icio.us&#034;&gt;&lt;img src=&#034;common/images/delicious.png&#034; alt=&#034;Add this post to Delicious&#034; border=&#034;0&#034; /&gt;&lt;/a&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;a href=&#034;http://www.stumbleupon.com/submit?url=http://blog.maxant.co.uk:80/pebble/2008/08/07/1218135480000.html&amp;amp;title=Secure+Remoting+with+Spring+and+JBoss&#034; target=&#034;_blank&#034; title=&#034;Stumble this post&#034;&gt;&lt;img src=&#034;common/images/stumbleupon.png&#034; alt=&#034;Add this post to Stumble it&#034; border=&#034;0&#034; /&gt;&lt;/a&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;a href=&#034;http://www.google.com/bookmarks/mark?op=edit&amp;amp;bkmk=http://blog.maxant.co.uk:80/pebble/2008/08/07/1218135480000.html&amp;amp;title=Secure+Remoting+with+Spring+and+JBoss&#034; target=&#034;_blank&#034; title=&#034;Add this post to Google&#034;&gt;&lt;img src=&#034;common/images/google.png&#034; alt=&#034;Add this post to Google&#034; border=&#034;0&#034; /&gt;&lt;/a&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;a href=&#034;http://technorati.com/faves?add=http://blog.maxant.co.uk:80/pebble/2008/08/07/1218135480000.html&#034; target=&#034;_blank&#034; title=&#034;Add this post to Technorati&#034;&gt;&lt;img src=&#034;common/images/technorati.png&#034; alt=&#034;Add this post to Technorati&#034; border=&#034;0&#034; /&gt;&lt;/a&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;a href=&#034;http://www.bloglines.com/sub/http://blog.maxant.co.uk:80/pebble/2008/08/07/1218135480000.html&#034; target=&#034;_blank&#034; title=&#034;Add this post to Bloglines&#034;&gt;&lt;img src=&#034;common/images/bloglines.png&#034; alt=&#034;Add this post to Bloglines&#034; border=&#034;0&#034; /&gt;&lt;/a&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;a href=&#034;http://www.facebook.com/share.php?u=http://blog.maxant.co.uk:80/pebble/2008/08/07/1218135480000.html&#034; target=&#034;_blank&#034; title=&#034;Add this post to Facebook&#034;&gt;&lt;img src=&#034;common/images/facebook.png&#034; alt=&#034;Add this post to Facebook&#034; border=&#034;0&#034; /&gt;&lt;/a&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;a href=&#034;http://www.furl.net/storeIt.jsp?u=http://blog.maxant.co.uk:80/pebble/2008/08/07/1218135480000.html&amp;amp;t=Secure+Remoting+with+Spring+and+JBoss&#034; target=&#034;_blank&#034; title=&#034;Add this post to Furl&#034;&gt;&lt;img src=&#034;common/images/furl.png&#034; alt=&#034;Add this post to Furl&#034; border=&#034;0&#034; /&gt;&lt;/a&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;a href=&#034;https://favorites.live.com/quickadd.aspx?mkt=en-us&amp;amp;url=http://blog.maxant.co.uk:80/pebble/2008/08/07/1218135480000.html&amp;amp;title=Secure+Remoting+with+Spring+and+JBoss&#034; target=&#034;_blank&#034; title=&#034;Add this post to Windows Live&#034;&gt;&lt;img src=&#034;common/images/windowslive.png&#034; alt=&#034;Add this post to Windows Live&#034; border=&#034;0&#034; /&gt;&lt;/a&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;a href=&#034;http://bookmarks.yahoo.com/toolbar/savebm?opener=tb&amp;amp;u=http://blog.maxant.co.uk:80/pebble/2008/08/07/1218135480000.html&amp;amp;t=Secure+Remoting+with+Spring+and+JBoss&#034; target=&#034;_blank&#034; title=&#034;Add this post to Yahoo!&#034;&gt;&lt;img src=&#034;common/images/yahoo.png&#034; alt=&#034;Add this post to Yahoo!&#034; border=&#034;0&#034; /&gt;&lt;/a&gt;&lt;/div&gt;
        </description>
      
      
    
    
    
    <comments>http://blog.maxant.co.uk:80/pebble/2008/08/07/1218135480000.html#comments</comments>
    <guid isPermaLink="true">http://blog.maxant.co.uk:80/pebble/2008/08/07/1218135480000.html</guid>
    <pubDate>Thu, 07 Aug 2008 18:58:00 GMT</pubDate>
  </item>
  
  </channel>
</rss>

