NICOLA NARDINO

My Personal Site

In this page I'll post small tutorials built as "how-to", showing up technologies I am interested on. If you get interested in any topic I deal with and you'd like to ask questions on it, feel free to get in touch with me at this e-mail.

 

So far, these are the topics I'd like to discuss:




Java Realtime Programming

Starting from a couple years ago Java, specifically its run-time environment, has been enabled to get into the realtime world. Realtime JVM's rely on the undelying OS to fully implement RTSJ specifications, so forget about having such a JVM running on Windows environments. Later, I'll write down some notes on how to set up a Linux based environment, basically installing the RT Kernel (pre-emptive, priority inversion avoidance, proper thread priorities) and configure the realtime JVM (different from the standard one) to use its realtime features. (Soft or Hard)Realtime programming is all about dealing with latency, not strictly related to throughput!

Some of the best applications of RTSJ complaint JVMs in the finance area are in the Equities Derivatives Trading or Order Management Systems.

Some of the key topics addressed by this programming and runtime model are:

  • Ahead Class Loading.
  • JIT optimization.
  • Advanced Thread Scheduling.
  • High resolution timers.
  • Advanced Memory Management, i.e., it's possible to allocate memory in areas not garbage collected, called Immortal Memory!
The environment I'll run the sample code will be: Lunix Ubuntu 8.04.4 + RT Kernel, Sun Realtime JVM 2.2. One of the first issues you will face when starting to code with Java realtime will be how to set up an ExecutorService to create RealtimeThreads instead of the standard java.lang.Thread (RealtimeThread's superclass):

            
	    
	    package com.projects.concurrency.threadfactory;
	    	    
	    import java.util.concurrent.ThreadFactory;
	    	    
	    import javax.realtime.PriorityParameters;
	    import javax.realtime.PriorityScheduler;
	    import javax.realtime.RealtimeThread;
	    	    
	    public class RealtimeThreadFactory implements ThreadFactory {
	    	    
	    public Thread newThread(final Runnable r) {
	        final RealtimeThread rtThread = new RealtimeThread(null, null, null, null, null, r);
	    	    
	    	PriorityParameters pp = (PriorityParameters) rtThread.getSchedulingParameters();
	    	PriorityScheduler scheduler = PriorityScheduler.instance();
	    	pp.setPriority(scheduler.getMaxPriority());
	    	    
	    	return rtThread;
	     }
             }
             
             

You could have a factory of thread factories in order to create the better factory for your runtime environment. Here it is an application of the above thread factory:

            
	    
             package com.projects.concurrency.task.testcase;
	     
	     import java.util.concurrent.Executors;
	     import java.util.concurrent.ScheduledExecutorService;
	     import java.util.concurrent.ThreadFactory;
	     import java.util.concurrent.TimeUnit;
	     import java.util.logging.Logger;
	     
	     import com.projects.concurrency.threadfactory.RealtimeThreadFactory;
	     import com.projects.concurrency.task.Task;
	     import com.projects.concurrency.task.TaskFactory;
	     
	     public class TimedExecutor {
	     	
	         public final ScheduledExecutorService te;
	         
	         private static final Logger logger = Logger.getLogger(TimedExecutor.class.getName()); 
	         
	         public TimedExecutor(final ThreadFactory tf, final int nrThreads) {
	         	te =  Executors.newScheduledThreadPool(nrThreads, tf);
	         }
	         
	         public void schedule(final Task task) {
	         	final Runnable runnableTask = new Runnable() {
	     
	     			public void run() {
	     				final long startT = System.nanoTime();
	     				logger.info("Executing Task "+task.getId()+" at "+System.currentTimeMillis());
	     				task.execute();
	     				logger.info("Task Duration "+(System.nanoTime()-startT));
	     			}
	         		
	         	}; 
	         	te.scheduleWithFixedDelay(runnableTask, 10, 100, TimeUnit.MILLISECONDS);
	         }
	         
	         public void shutdown() {
	         	te.shutdown();
	         	try {
	     			te.awaitTermination(1000, TimeUnit.MILLISECONDS);
	     		} catch (final InterruptedException e) {
	     			e.printStackTrace();
	     		}
	         }
	         
	     	public static void main(String[] args) {
	     		final TimedExecutor te = new TimedExecutor(new RealtimeThreadFactory(), 5);
	     		te.schedule(/*your task goes here*/);
	     		try {
	     			Thread.sleep(20000);
	     		} catch (final InterruptedException e) {
	     			e.printStackTrace();
	     		}
	     		te.shutdown();
	     	}
	     }

            
            

Java Multithreading tips.

Interrupting legacy code

This tip is about Thread interruption, how to design an interruption strategy on some legacy code not designed to be responsive to interruption. The test case could be a long not interruptible task, for instance, triggered by a third party library which is not responsive to interruption, although you could be able to close the underlying resources used by it, doing some sort of clean-up. In general, java.lang.Threads can be made responsive to interruption, for instance, by wrapping the long running, and not interruption responsive task, with a FutureTask instance. Then that future task can be run by another Thread and the parent Thread can poll its completion or interruption status each fixed time period. Here it is a sample usage of that technique:

	    
	                public class Task extends Thread {
	    		private static Logger logger = Logger.getLogger(Task.class.getName());
	    		public Task() {
	    			super("TaskExecutorThread");
	    		}
	    		
	    		public void run() {
	    			boolean interrupted = false; 		
	    			final FutureTask future = new FutureTask(new Callable()  { 
	    				public String  call() throws Exception 
	    				{ 
	    					return longRunningNonInterruptibleTask();
	    				} 
	    			}); 
	    			new Thread(future).start(); 
	    			while(!future.isDone() && !Thread.currentThread().isInterrupted()) { 
	    				try { 
	    					Thread.sleep(100);//sleep for a 100 milliseconds.
	    				} 
	    				catch(final InterruptedException e) { 
	    					interrupted = true; 
	    					break; 
	    				} 
	    			}
	    			if (interrupted) {
	    				cleanUpUnderlyingResources();
	    			}
	    			try {
	    				String result = future.get();
	    			} 
	    			catch (final Exception e) {
	    				if (e instanceof ExecutionException) {
	    					ExecutionException ex = (ExecutionException)e;
	    					finalize(ex)
	    				}
	    				else
	    					doStuff(e);
	    			}
	    		}
	                }
	                
	    

In the above code, longRunningNonInterruptibleTask() runs third party code, which is not interruptible though there wouldn't be no way to make it a cancellable operation without that wrapping machinery.

The strange case of FutureTask and UncaughtExceptionHandler

According to Doug Lee, the below case is a feature, well if he says that, given his undoubtable reputation, we must agree but someone could have lost his sleep trying to figure out why that's a feature and not a bug!

	    
	    import java.lang.Thread.UncaughtExceptionHandler;
	    import java.util.concurrent.Callable;
	    import java.util.concurrent.ExecutorService;
	    import java.util.concurrent.Executors;
	    import java.util.concurrent.FutureTask;
	    
	    
	    public class MysticBehaviour {
	    
	    	public static void main(final String[] args) {
	    		final UncaughtExceptionHandler u = new UncaughtExceptionHandler() {
	    			@Override
	    			public void uncaughtException(Thread t, Throwable tr) {
	    				System.out.println("UncaughtExceptionHandler.uncaughtException Thread "+t+" Throwable "+tr);
	    			}
	    		};
	    		Thread.setDefaultUncaughtExceptionHandler(u);	
	    		final Callable c = new Callable() {
	    			@Override
	    			public String call() throws Exception {
	    				System.out.println("Starting call");
	    				throw new RuntimeException("Here we are");
	    			}
	    		};
	    		final FutureTask ft = new FutureTask(c) {
	    			@Override
	    			public void done() {
	    				System.out.println("Job done...don't care about the RuntimeException.");
	    			}
	    		};
	    		final ExecutorService ex = Executors.newSingleThreadExecutor();
	    		ex.execute(ft);
	    //		try {
	    //			final String result = ft.get();
	    //		}
	    //		catch(final Exception e) {
	    //			e.printStackTrace();
	    //		}
	    	}
	    }	    
	    
	    

Running the above would give:

	    
	    Starting call
	    Job done...don't care about the RuntimeException.
            
            

The execution begins, the execution get raised and not caught by the default exception handler! Try to do the same replacing submitting a runnable task to the executor service. The only way to know about the Runtime raised is commenting out the commented code and get the computation result by Future.get(). That way you'll get:

            
            Caused by: java.lang.RuntimeException: Here we are
	    	at MysticBehaviour$2.call(MysticBehaviour.java:22)
	    	at MysticBehaviour$2.call(MysticBehaviour.java:1)
	    	at java.util.concurrent.FutureTask$Sync.innerRun(Unknown Source)
	    	at java.util.concurrent.FutureTask.run(Unknown Source)
	    	at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(Unknown Source)
	    	at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
	        at java.lang.Thread.run(Unknown Source)
	    
            
The above, of course, has an impact on the SwingWorker, which is better to understand and digest.

Platform Interoperability by Web Services

Inter-platform communication has always been involved software architects and web services are one of the main choices of achieving it. Anyway, there are a lot of other choices a software architect could follow, for instance, MOM(Message Oriented Middleware), CORBA, RMI/IIOP, shared database and more. In this section, I'll explain how to code web services either in .NET and Java/JBoss platforms and make them comunicate. I've not got much time, so I'll be as much direct as possibile. Problem is being a distributed calculator, so there will be a Sum Web Method deployed on JBoss AS and a Multiply Web Method deployed on IIS and coded in C#.

Step 1 : code and deploy the Java/JBoss 4.2.0.GA web service.

I'll use JAX-WS, EJB3 and Java SDK 5.0 annotations to code and deploy the web service either as POJO and stateless EJB.

Web Service as POJO :
    
    
    package com.enterprise.ws_learning;
    @javax.jws.WebService
    public class SumWS {
        @javax.jws.WebMethod(operationName = "sumOperation")
        public int sum(int op1,int op2)
        {
          return (op1 + op2);
        }
    }
    

This is the minimal way we can code Java web services. Next we've to deploy it as a web application, declaring our web service as a Servlet into WEb-INF/web.xml WEB-INF : 

<web-app xmlns="http://java.sun.com/xml/ns/j2ee"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd" version="2.4">  

<servlet>                                                                                                                                                                                                                                                                                                                                                                                                          <servletname>SumWSServlet</servletname>                                                                                                                                                                                                                                                                                                    <servlet-class>com.enterprise.ws_learning.SumWS</servlet-class>                                                                                                           </servlet>                                                                                                                                                                                                      <servlet-mapping>                                                                                                                                                                                              <servlet-name>SumWSServlet</servlet-name>                                                                                                                                                    <url-pattern>/SumWS</url-pattern>                                                                                                                                                                    </servlet-mapping>                                                                                                                                                                                                </web-app>

 Last step is making a .war(e.g. WebServicesLearning.war) file packaging SumWS.class and WEB-INF/web.xml and copying it into the deploy directory of JBoss, for instance, %JBOSS_HOME%/server/default/deploy. The hot deploy feature of JBoss will deploy the war and will create the WSDL file :

<definitions name="SumWSService" targetNamespace="http://ws_learning.enterprise.com/"><types><xs:schema targetNamespace="http://ws_learning.enterprise.com/" version="1.0"><xs:element name="sumOperation" type="tns:sumOperation"/><xs:element name="sumOperationResponse" type="tns:sumOperationResponse"/><xs:complexType name="sumOperation"><xs:sequence><xs:element name="arg0" type="xs:int"/><xs:element name="arg1" type="xs:int"/></xs:sequence></xs:complexType><xs:complexType name="sumOperationResponse"><xs:sequence><xs:element name="return" type="xs:int"/></xs:sequence></xs:complexType></xs:schema></types><message name="SumWS_sumOperation"><part element="tns:sumOperation" name="sumOperation"/></message><message name="SumWS_sumOperationResponse"><part element="tns:sumOperationResponse" name="sumOperationResponse"/></message>

<portType name="SumWS">                                                                                                                  <operation name="sumOperation" parameterOrder="sumOperation">                                                  <input message="tns:SumWS_sumOperation"/>                                                                                   <output message="tns:SumWS_sumOperationResponse"/>                                            </operation></portType>

<binding name="SumWSBinding" type="tns:SumWS">              <soap:binding style="document" transport="http://schemas.xmlsoap.org/soap/http"/>                       <operation name="sumOperation">                                      <soap:operation soapAction=""/>                                                     <input>                                                                                     <soap:body use="literal"/>                                                             </input>                                                                                         <output>                                                                                     <soap:body use="literal"/>                                                               </output>                                                                                 </operation>                                                                                </binding>                                                                                                                                                                                                         <service name="SumWSService">                                                                                                                <port binding="tns:SumWSBinding" name="SumWSPort">                                                               <soap:address location="http://127.0.0.1:8080/WebServicesLearning/SumWS"/>                                 </port>                                                                                                                                                    </service>                                                                                                                                                    </definitions>

As a result of deploying, the JBoss web services console shows resume about the deployed service : ServiceEndpointID : jboss.ws:context=WebServicesLearning,endpoint=SumWSServlet ServiceEndpointAddress : http://127.0.0.1:8080/WebServicesLearning/SumWS?wsdl

Just for the sake of completion I 'll expose a web service deployed as stateless EJB :

The remote interface :               

import javax.ejb.Remote;
@Remote public interface
ISumWS_StatelessEJB {
    public int sum(int op1, int op2);
}  
           
            

The EJB class with web services annotation :

import javax.ejb.Remote;
import javax.ejb.Stateless;
import javax.jws.WebMethod;
import javax.jws.WebService;
import javax.jws.soap.SOAPBinding;

import org.jboss.annotation.ejb.RemoteBinding;

@Stateless
@Remote(ISumWS_StatelessEJB.class)
@RemoteBinding(jndiBinding = "/ejb3/SumWS_StatelessEJB")
@WebService
@SOAPBinding(style = SOAPBinding.Style.RPC)
public class SumWS_StatelessEJB implements ISumWS_StatelessEJB{
    
	@WebMethod(operationName = "sumOperation")
	public int sum(int op1, int op2) {
    	return op1 + op2;
    }
}

Deploying it on JBoss AS is as simple as deploy an EJB 3, so no deployment descriptor needed, just making a jar with the remote interface and the bean class and copy it into the deploy directory of JBoss : ServiceEndpointID : jboss.ws:context=SumWS_StatelessEJBService,endpoint=SumWS_StatelessEJB ServiceEndpointAddress : http://127.0.0.1:8080/SumWS_StatelessEJBService/SumWS_StatelessEJB?wsdl.

Step 2 : consume the deployed web service.

Consuming is just like saying using web service client side. I will use the top-down approach, starting with the URL of the WSDL file. Web services were introduced to make platform communication where each platorm is agnostic with each other, so the only think you've to know abot the service is the endpoint, the service name and the WSDL file by which you can create the client stub to the service itself. JBoss AS gives up the routine "wsconsume" to generate client stubs :

C:\>wsconsume http://127.0.0.1:8080/SumWS_StatelessEJBService/SumWS_StatelessEJB?wsdl

com\enterprise\ws_learning\SumWSStatelessEJB.java com\enterprise\ws_learning\SumWSStatelessEJBService.java com\enterprise\ws_learning\SumWSStatelessEJB.java com\enterprise\ws_learning\SumWSStatelessEJBService.java

Having generated the client stub it's possibile coding the client :

package com.enterprise.ws_learning.client;

import com.enterprise.ws_learning.SumWSStatelessEJB;
import com.enterprise.ws_learning.SumWSStatelessEJBService;

public class WSEJBClient 
{
   public static void main(String args[])
   { 
      SumWSStatelessEJBService service = new SumWSStatelessEJBService();
      SumWSStatelessEJB sumWS = service.getSumWSStatelessEJBPort();
      System.out.println("Sum " + sumWS.sumOperation(10000, 20000));
   } 
}

Step 3 : code and deploy the .NET/IIS web service.

It's very simple coding and deployg .NET web services. You just have to create an ASP.NET Web Services project :


ASP.NET Web Services projec

This wizard will create a virtual directory on your IIS web server linked to "C:\Inetpub\wwwroot\WebServicesLearning" file system location. You can configure it, of course, in another location on your file system.

Later, let us code a simple web service :

using System;
using System.Web;
using System.Web.Services;
using System.Web.Services.Protocols;

[WebService(Namespace = "http://com.enterprise.dotNet.webservices/")]
[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
public class MultiplyService : System.Web.Services.WebService
{
    public MultiplyService() {

        
    }

    [WebMethod]
    public double Multiply(double op1, double op2) {
        return op1*op2;
    }
} 
          

Now, we have the MultiplyService web service, with Multiply web method deployed on IIS into the namespace http://com.enterprise.dotNet.webservices/. Consuming it into another .NET project is trivial and I'll not cover it as you just have to add a web reference in the project and looking up web service URL :


ASP.NET Web Services projec

 

Step 4 : consume .NET/IIS web service in Java.

We have to use wsconsume routine :

C:\>wsconsume http://localhost/WebServicesLearning/Service.asmx?WSDL
warning: Ignoring SOAP port "MultiplyServiceSoap12": it uses non-standard SOAP 1.2 binding.
You must specify the "-extension" option to use this binding.
webservices\dotnet\enterprise\com\Multiply.java
webservices\dotnet\enterprise\com\MultiplyResponse.java
webservices\dotnet\enterprise\com\MultiplyService.java
webservices\dotnet\enterprise\com\MultiplyServiceSoap.java
webservices\dotnet\enterprise\com\ObjectFactory.java
webservices\dotnet\enterprise\com\package-info.java
webservices\dotnet\enterprise\com\Multiply.java
webservices\dotnet\enterprise\com\MultiplyResponse.java
webservices\dotnet\enterprise\com\MultiplyService.java
webservices\dotnet\enterprise\com\MultiplyServiceSoap.java
webservices\dotnet\enterprise\com\ObjectFactory.java
webservices\dotnet\enterprise\com\package-info.java

So, we have generated clien stub accessing .NET/IIS deployed web serivice. We can code the Java client :

package com.enterprise.ws_learning.client;

import webservices.dotnet.enterprise.com.*;

public class WSNETMultiplyServiceClient {
    public static void main(String args[])
    { 
	MultiplyService service = new  MultiplyService();
	MultiplyServiceSoap multiplyWS = service.getMultiplyServiceSoap();
	System.out.println("Multiply " + multiplyWS.multiply(20, 30)); 
     }
}

Don't forget to add generated stub classes into the client classpath.

Step 5 : consume Java/JBoss web service in .NET.

You just have to add a web reference into your .NET project, referring the WSDL file of the deployed JBoss web service, then you can code the .NET client :

using System;
using System.Collections.Generic;
using System.Text;
using ClientJBossWS.SumWSEJB;

namespace ClientJBossWS
{
    class Program
    {
        static void Main(string[] args)
        {
            SumWS_StatelessEJBService sumWS = new SumWS_StatelessEJBService();
            int result = sumWS.sumOperation(1000, 2000);
        }
    }
}
            

Having named the web reference as "SumWSEJB".

[This page was accessed 13831 times]

[Overall web site access counter : 338271 ]