doInvoke service throwing Null pointer exception

Hi Castro,

Thanks for the solution. It worked finally :o

code:

String serviceName = “threadsPOC.services:new_javaService”;
NSName nsName = NSName.create(serviceName);
ServiceThread thread = new ServiceThread(nsName, InvokeState.getCurrentSession(), null);
String id = ThreadManager.runTarget(thread);
ThreadManager.interrupt(id);
IDataUtil.put(pipelineCursor, “ThreadID”, id );

Actually we are not having any control over the child service (The service which contains pub.client:ftp and pub.client:login services). We should just invoke the child service ( need not to pass any inputs also) and wait for the status ( file transfer successful/failed etc.) returned from the child service. So the main service starts the timer after invoking the child service and checks periodically for status returned from child service. If status is not returned even after the timeout then we should kill the thread which is executing the child service. I believe now you understood the whole requirement. Also the thread ID returned from above service is something like “c0a8f40100003ac90000045e”. When I call the WmRoot/killThread it is throwing “java.lang.NumberFormatException” exception. Please suggest me If I am doing anything wrong anywhere. Thanks once again for the help.

Thanks,
vinodkumar.

Unfortunately, the thread ID returned by runTarget is not the same as the thread ID expected by the killThread service. I was originally under the impression that they would be the same, but they are not. Hence, in my last post I suggested that you would have to call getThreadList first before calling interruptThread/killThread.

Percio

Vinod,

I’ve thought about it a little more and now I think that the only option to really forcedly kill the thread is to use a JVM where java threads are implemented as OS threads, and then use some OS API to kill the thread. But that may leave the JVM in a very instable state since you’d pull the thread off under its feet.

Let me elaborate. Even if ouy find out how to use the ThreadManager API etc, the most it can is to call “interrupt” on some java.lang.Thread object. I think, in the end it comes to this class, I don’t think SAG has implemented the thread concept natively - why use java then?

A java thread must be programmed in an appropriate way to be interruptible. I.e. it should check some variable or its “interrupted” status to see whether it should terminate. And this kind of programming must be everywhere, i.e. in all actions performed on the thread.

Now, which code is executed in an IS thread? Mostly it will be flow or java services. Flow services are interpreted, so SAG might have implemented the interpreter so that it checks (e.g. after having executed a flow step) whether it should stop. But honestly, I doubt the did it that way.

And if you have a java service, then it also should be programmed that way. ALL java services must programmed that way. And I’m sure it’s not the case.

Hence you can’t stop the thread with native java means. And hence the only option would be to use the OS API which is beyond java.

Or you could find a java implementation which would stop a thread when it’s interrupted.

Hi castro,

As you said ThreadManager.interrupt(id) will attempt to interrupt the thread. However, this will not necessarily stop the thread (e.g. if your thread is stuck in a REPEAT loop or any code, for that matter, which is not checking the isInterrupted() flag.).

But what we need to do if we want to forcefully kill the thread ? will that be possible ? Also I have a query. What is the expected input to “wm.server.query:ikillThread” service. I used the thread ID which I got from “WmRoot/wm.server.query:getThreadList”. killThread service always throwing an exception saying invalid threadID.

Thanks,
vinodkumar.

Hi Castro,

Did u get a chance to look at my message. Please let me know if you have some suggestion/solution.

Thanks,
vinodkumar.

Hi Guys,

I think I found a solution for killing a service even if it got stuck in an infinite loop etc. Please find the following solution for this. Basically the main program will have 2 inputs service name and timeout value after which you want to kill the service for further execution. Sub program will have service name as input.

Main Program:

package threadsPOC.latestImplementation;

import com.wm.data.*;
import com.wm.util.Values;
import com.wm.app.b2b.server.Service;
import com.wm.app.b2b.server.ServiceException;
import com.wm.lang.ns.NSName;
import com.wm.app.b2b.server.ServiceThread;
import com.wm.app.b2b.server.InvokeState;
import com.wm.app.b2b.server.ThreadManager;

public final class invokeFilePullingImpService_SVC

{

/** 
 * The primary method for the Java service
 *
 * @param pipeline
 *            The IData pipeline
 * @throws ServiceException
 */
public static final void invokeFilePullingImpService(IData pipeline)
		throws ServiceException {

	IDataCursor pipelineCursor = pipeline.getCursor();
	try
	{
		String serviceName = "threadsPOC.services:xyz";
		long timeout = 20000;
		
		int startTimer=0;
		IData status = null;
		IData threadDetails;
		IDataCursor threadCursor;
		IData interruptThreadDet;
		IDataCursor interruptThreadCursor;
		
		FilePullImpService m1=new FilePullImpService(serviceName);
		Thread t1 =new Thread(m1);
		
		t1.start();
		long threadID = t1.getId();
		System.out.println("ThreadID ---> " +threadID);
		
		while(true)
		{
			if(startTimer < timeout)
			{
				status = m1.returnval();
				
				if(status != null)
				{
					com.wm.util.JournalLogger.log( com.wm.util.JournalLogger.INFO, com.wm.util.JournalLogger.FAC_FLOW_SVC, com.wm.util.JournalLogger.DEBUG, "Recieved Result From Thread Class");
					IDataUtil.put( pipelineCursor, "status", status );
					break;
				}
				else
				{
					startTimer +=1000;
					t1.join(1000);
					System.out.println("Timer " +startTimer);
				}					
			}
			else
			{
				com.wm.util.JournalLogger.log( com.wm.util.JournalLogger.INFO, com.wm.util.JournalLogger.FAC_FLOW_SVC, com.wm.util.JournalLogger.DEBUG, "Thread Faied To Complete Before Timeout");
				System.out.println("Status Of Thread Before Killing " + t1.getState());
				
				m1.killService();
				Thread.sleep(1000);
				System.out.println("Status Of Thread After Killing " + t1.getState());
				if(t1.getState().toString().equals("TERMINATED"))
				{
					System.out.println("Thread Got Killed ");
					break;
				}
				threadDetails = IDataFactory.create();
				threadCursor = threadDetails.getCursor();
				IDataUtil.put(threadCursor, "threadID", threadID);
				threadCursor.destroy();
				System.out.println(threadDetails);
				
				NSName nsName = NSName.create("wm.server.query:getThreadDumpForThread");
				IData threadDumpIData = Service.doInvoke(nsName, threadDetails);
				
				IDataCursor threadDumpCursor = threadDumpIData.getCursor();
				String threadDump = IDataUtil.getString(threadDumpCursor,"threadDump");
				
				threadDump = threadDump.replace("\n", " ");
				int iniIndex = threadDump.indexOf("Id=");
				int actIndex = threadDump.indexOf("Id=", iniIndex+3);
				int spaceIndex = threadDump.indexOf(" ", actIndex+3);
				String threadIDNew = threadDump.substring(actIndex+3,spaceIndex).trim();
				
				System.out.println("threadDump " +threadDump);
				System.out.println("threadID " +threadIDNew);
				
				interruptThreadDet = IDataFactory.create();
				interruptThreadCursor = interruptThreadDet.getCursor();
				IDataUtil.put(interruptThreadCursor, "threadID", threadIDNew);
				interruptThreadCursor.destroy();
				
				System.out.println(interruptThreadDet);
				NSName nsNameInt = NSName.create("wm.server.query:interruptThread");
				Service.doInvoke(nsNameInt, interruptThreadDet);
				
				
				Thread.sleep(1000);
				System.out.println("Status Of Thread After Killing " + t1.getState());
				
				break;
				
			}
		}
	}
	catch(Exception e)
	{
		throw new ServiceException(e);
	}
	pipelineCursor.destroy();
}

// --- <<IS-BEGIN-SHARED-SOURCE-AREA>> ---

static class FilePullImpService extends Thread
{
	IData serviceDetails;
	IDataCursor outputCursor;
	IData outputData = null;
	String thrId = null;
	FilePullImpService(String serviceName)
	{
		serviceDetails = IDataFactory.create();
		outputCursor = serviceDetails.getCursor();
		IDataUtil.put(outputCursor, "serviceName", serviceName);
		outputCursor.destroy();

	}
	public void run()
	{
		try
		{
			com.wm.util.JournalLogger.log( com.wm.util.JournalLogger.INFO, com.wm.util.JournalLogger.FAC_FLOW_SVC, com.wm.util.JournalLogger.DEBUG, "Thread Class Started");
			NSName nsName = NSName.create("threadsPOC.latestImplementation:doInvokeService");
			ServiceThread thread = new ServiceThread(nsName, InvokeState.getCurrentSession(), serviceDetails);
			thrId = ThreadManager.runTarget(thread);
			outputData = thread.getIData();
			com.wm.util.JournalLogger.log( com.wm.util.JournalLogger.INFO, com.wm.util.JournalLogger.FAC_FLOW_SVC, com.wm.util.JournalLogger.DEBUG, "Thread Class Completed");
		}
		catch(Exception e)
		{
			System.out.println(e);
			com.wm.util.JournalLogger.log( com.wm.util.JournalLogger.INFO, com.wm.util.JournalLogger.FAC_FLOW_SVC, com.wm.util.JournalLogger.DEBUG, "Exception Caught In Thread Class"); 
			
		}
		
	}
	public IData returnval()
	{
		return outputData;
	}
	public void killService()
	{
		System.out.println("Killing Service In Thread Class");
		ThreadManager.interrupt(thrId);
	}
}

// --- <<IS-END-SHARED-SOURCE-AREA>> ---

}

Sub Program:

public static final void doInvokeService(IData pipeline)
throws ServiceException {

	try
	{
		IDataCursor pipelineCursor = pipeline.getCursor(); 
		String serviceName = IDataUtil.getString(pipelineCursor,"serviceName");
		NSName nsName = NSName.create(serviceName); 
		IData outputData = Service.doInvoke(nsName, null); 
		IDataUtil.put( pipelineCursor,"result",outputData);
		pipelineCursor.destroy();
	}
	catch(Exception e)
	{
		throw new ServiceException(e);
	}
}

Please analyse the program and let me know if you guys have any queries. Thanks to Castro for the help.

Thanks,
vinodkumar.