Skip to main content

Java standalone webservice : Multithreading the Endpoint Publisher

While going through a very good book on web services by Martin Kalin ( Java Web services : Up and Running) I came across the section that is dealing with how to multithread the endpoint publisher so that the web service request wont wait for another one to finish.

Given below is the enhancement to the example mentioned in the above book where I am using multithreaded endpoint publisher.

STEP 1 : Web service Server

1. Create a new Java project.
2. Create a class TimeServer which is Service Endpoint Interface (SEI) as below.

 package ch01.ts;  
 import javax.jws.WebService;  
 import javax.jws.WebMethod;  
 import javax.jws.soap.SOAPBinding;  
 import javax.jws.soap.SOAPBinding.Style;  
 /**  
 * The annotation @WebService signals that this is the  
 * SEI (Service Endpoint Interface). @WebMethod signals  
 * that each method is a service operation.  
 *  
 * The @SOAPBinding annotation impacts the under-the-hood  
 * construction of the service contract, the WSDL  
 * (Web Services Definition Language) document. Style.RPC  
 * simplifies the contract and makes deployment easier.  
 */  
 @WebService  
 @SOAPBinding(style = Style.RPC) // more on this later  
 public interface TimeServer {  
 @WebMethod String getTimeAsString();  
 @WebMethod long getTimeAsElapsed();  
 }  

3. Create class TimeServerImpl which is Service Implementation Bean(SIB).

 package ch01.ts;  
 import java.util.Date;  
 import javax.jws.WebService;  
 /**  
 * The @WebService property endpointInterface links the  
 * SIB (this class) to the SEI (ch01.ts.TimeServer).  
 * Note that the method implementations are not annotated  
 * as @WebMethods.  
 */  
 @WebService(endpointInterface = "ch01.ts.TimeServer")  
 public class TimeServerImpl implements TimeServer {  
      public String getTimeAsString() {  
           System.out.println("ThreadID:"+ Thread.currentThread().getId());  
           return new Date().toString();   
           }  
 public long getTimeAsElapsed() {  
      return new Date().getTime();   
      }  
 }  

4. This step we need to create an Executor which specifies the threadpool size and other parameters for the Java Threadpool.

Create a Class MyExecutor which extends ThreadPoolExecutor as below.

 package ch01.ts;  
 import java.util.concurrent.BlockingQueue;  
 import java.util.concurrent.ThreadPoolExecutor;  
 import java.util.concurrent.TimeUnit;  
 public class MyExecutor extends ThreadPoolExecutor {  
      public MyExecutor(int corePoolSize, int maximumPoolSize,  
                long keepAliveTime, TimeUnit unit, BlockingQueue<Runnable> workQueue) {  
           super(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue);  
           // TODO Auto-generated constructor stub  
           System.out.println("########################HERE");  
      }  
 }  

Here what we do is subclass ThreadPoolExecutorfor the sake of providing an Executor to Endpoint class (which is mentioned below). This helps us to initialize the ThreadPool with the required Pool size and other parameters.

5. Create class TimeServerPublisher which is the web service publisher.

 package ch01.ts;  
 import java.util.concurrent.LinkedBlockingQueue;  
 import java.util.concurrent.ThreadPoolExecutor;  
 import java.util.concurrent.TimeUnit;  
 import javax.xml.ws.Endpoint;  
 /**  
 * This application publishes the web service whose  
 * SIB is ch01.ts.TimeServerImpl. For now, the  
 * service is published at network address 127.0.0.1.,  
 * which is localhost, and at port number 9876, as this  
 * port is likely available on any desktop machine. The  
 * publication path is /ts, an arbitrary name.  
 *  
 * The Endpoint class has an overloaded publish method.  
 * In this two-argument version, the first argument is the  
 * publication URL as a string and the second argument is  
 * an instance of the service SIB, in this case  
 * ch01.ts.TimeServerImpl.  
 *  
 * The application runs indefinitely, awaiting service requests.  
 * It needs to be terminated at the command prompt with control-C  
 * or the equivalent.  
 *  
 * Once the applicatation is started, open a browser to the URL  
 *  
 http://127.0.0.1:9876/ts?wsdl  
 *  
 * to view the service contract, the WSDL document. This is an  
 * easy test to determine whether the service has deployed  
 * successfully. If the test succeeds, a client then can be  
 * executed against the service.  
 */  
 public class TimeServerPublisher {  
      private Endpoint endpoint;  
      public static void main(String[ ] args) {  
           TimeServerPublisher t = new TimeServerPublisher();  
           t.endpoint= Endpoint.create(new TimeServerImpl());  
           MyExecutor me = new MyExecutor(5, 5, 10, TimeUnit.SECONDS, new LinkedBlockingQueue<Runnable>(10));  
           t.endpoint.setExecutor(me);  
           t.endpoint.publish("http://127.0.0.1:9877/ts");  
      }  
 }  

Here you can see that a new ThreadPool has been initialized with pool size =5.

MyExecutor me = new MyExecutor(5, 5, 10, TimeUnit.SECONDS, new LinkedBlockingQueue<Runnable>(10)); 

Now the webservice server is ready. Compile it and run.


STEP 2 : Web service Client

1. Create a Java project
2. Create a class TimeClient which is the main client class.

 package ch01.ts;  
 import javax.xml.namespace.QName;  
 import javax.xml.ws.Service;  
 import java.net.URL;  
 class TimeClient {  
      public static void main(String args[ ]) throws Exception {  
      URL url = new URL("http://localhost:9877/ts?wsdl");  
      // Qualified name of the service:  
      // 1st arg is the service URI  
      // 2nd is the service name published in the WSDL  
      QName qname = new QName("http://ts.ch01/", "TimeServerImplService");  
      // Create, in effect, a factory for the service.  
      Service service = Service.create(url, qname);  
      // Extract the endpoint interface, the service "port".  
      TimeServer eif = service.getPort(TimeServer.class);  
      System.out.println(eif.getTimeAsString());  
      System.out.println(eif.getTimeAsElapsed());  
      }  
 }  

3. Compile it and run. You will receive response as below

Fri Oct 10 14:53:53 CDT 2014
1412970833740
4. Now to check that whether multiple threads have been created or not, run the client multiple times.

5. Now check the Web service Server output in console. You will see 5 different thread IDs repeated throughout. This means it is using the new Thread pool of 5 that we created.

My Web service Server output in console is below.

########################HERE
ThreadID:14
ThreadID:17
ThreadID:15
ThreadID:13
ThreadID:16
ThreadID:14
ThreadID:17
ThreadID:16
ThreadID:13
ThreadID:16
ThreadID:14
ThreadID:17
ThreadID:15
ThreadID:13
ThreadID:14
ThreadID:16
ThreadID:13
ThreadID:17
ThreadID:16
ThreadID:13
ThreadID:16
ThreadID:17
ThreadID:16
ThreadID:13
ThreadID:17
ThreadID:14
ThreadID:15
ThreadID:15
ThreadID:14
ThreadID:16
ThreadID:13
ThreadID:17
ThreadID:16

6. If you want to cross check the single thread execution then modify the publisher as below.

 package ch01.ts;  
 import java.util.concurrent.LinkedBlockingQueue;  
 import java.util.concurrent.ThreadPoolExecutor;  
 import java.util.concurrent.TimeUnit;  
 import javax.xml.ws.Endpoint;  
 /**  
 * This application publishes the web service whose  
 * SIB is ch01.ts.TimeServerImpl. For now, the  
 * service is published at network address 127.0.0.1.,  
 * which is localhost, and at port number 9876, as this  
 * port is likely available on any desktop machine. The  
 * publication path is /ts, an arbitrary name.  
 *  
 * The Endpoint class has an overloaded publish method.  
 * In this two-argument version, the first argument is the  
 * publication URL as a string and the second argument is  
 * an instance of the service SIB, in this case  
 * ch01.ts.TimeServerImpl.  
 *  
 * The application runs indefinitely, awaiting service requests.  
 * It needs to be terminated at the command prompt with control-C  
 * or the equivalent.  
 *  
 * Once the applicatation is started, open a browser to the URL  
 *  
 http://127.0.0.1:9876/ts?wsdl  
 *  
 * to view the service contract, the WSDL document. This is an  
 * easy test to determine whether the service has deployed  
 * successfully. If the test succeeds, a client then can be  
 * executed against the service.  
 */  
 public class TimeServerPublisher {  
      private Endpoint endpoint;  
      public static void main(String[ ] args) {  
           TimeServerPublisher t = new TimeServerPublisher();  
           t.endpoint= Endpoint.create(new TimeServerImpl());  
           t.endpoint.publish("http://127.0.0.1:9877/ts");  
      }  
 }  


7. Now repeat step 4. You will see only one thread ID exists at a time.

ThreadID:12
ThreadID:12
ThreadID:12
ThreadID:12
ThreadID:12
ThreadID:12
ThreadID:12
ThreadID:12
ThreadID:12
ThreadID:13
ThreadID:13
ThreadID:13
ThreadID:13
ThreadID:13
ThreadID:13
ThreadID:13
ThreadID:13
ThreadID:13
ThreadID:13
ThreadID:13
ThreadID:13
ThreadID:13
ThreadID:13
ThreadID:13
ThreadID:13
ThreadID:13
ThreadID:13
ThreadID:13
ThreadID:13
ThreadID:13
ThreadID:13
ThreadID:13
ThreadID:13
ThreadID:13
ThreadID:13
ThreadID:13
ThreadID:13
ThreadID:13
ThreadID:13
ThreadID:13
ThreadID:13
ThreadID:13
ThreadID:13


Reference : Web Services Up and Running By Martin Kalin.








Comments

  1. Your favorite roulette wager can could depend upon what you want to get out of the game although. If the thought of smaller, extra regular wins appeals, you’re best off inserting outside bets on black or pink and odd or even. 카지노 If the thrill of a much bigger|an even bigger}, rarer digital win pursuits you, it’s better to place inside bets on particular person numbers.

    ReplyDelete

Post a Comment

Popular posts from this blog

How to format and install macOS in your old Macbook/ iMac

 You can follow these steps to install a mac OS on an old Mac book following these steps. Here I assume that you have the actual bootable CD for the OS for installation. 1. Restart the laptop 2. Press Command + R key until it shows recovery mode 3. Open Disk Utilities 4. Select the hard drive and try to partition the drive. For example I have created a partition called Partition1 5. Insert bootable CD and restart the laptop. When option comes choose to boot from the CD. 6. Choose partition1 as the place to install the OS 7. Continue the installation process. 8. Once installation is completed then it might need to restart for further updates. 9. Most of the times a more recent compatible version of the OS might be available. In order to upgrade to the more latest compatible OS follow below steps. 11. Find the latest compatible version of OS. 12. Go to apple support sites and manually download the image and click to install. 13. Follow installation instructions and this would upgrade you

How to create a minikube single node cluster for learning Kubernetes

In this post I will explain how to setup a minikube single node kubernetes cluster using AWS EC2 instance which would help anyone who is trying to learn kubernetes and also help them to gain practical knowledge in kubernetes by running kubernetes commands, creating kubernetes objects etc. Minikube is a single node kubernetes cluster which means a kubernetes cluster with only one node that is a single VM. Minikube is only used for learning purposes and it is not an alternative for a real kubernetes cluster and should not be used for development and production usage. In this example I have launched an AWS EC2 instance with below configuration where I will install minikube and related tools. AWS EC2 Instance Configuration AMI: Ubuntu Free tier eligible 64 bit Instance type : t2-large ( For me t2-small or t2-micro is giving performance issues due to less memory) Once the EC2 instance is up and running, login to the instance using below command on terminal. If you are using wi

log4j - How to write log to multiple log files using log4j.properties

In Java applications some times you may need to write your log messages to specific log files with its own specific log properties. If you are using log4j internally then first step that you need to do is to have a proper log4j.properties file. Below example shows 2 log4j appenders which write to 2 different log files, one is a debug log and another one is a reports log. Debug log file can have all log messages and reports log can have log messages specific to reporting on say splunk monitoring. # Root logger option log4j.rootLogger=ALL,STDOUT,debugLog log4j.logger.reportsLogger=INFO,reportsLog log4j.additivity.reportsLogger=false     log4j.appender.STDOUT=org.apache.log4j.ConsoleAppender log4j.appender.STDOUT.layout=org.apache.log4j.PatternLayout log4j.appender.STDOUT.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss} %-5p %C:%L - %m%n     # Direct log messages to a log file log4j.appender.debugLog=org.apache.log4j.RollingFileAppender log4j.appender.debugLo