<?xml version="1.0"?>
<rss version="2.0">
<channel>
  <title>The Kitchen in the Zoo - jboss tag</title>
  <link>http://blog.maxant.co.uk:80/pebble/tags/jboss/</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>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>

