users@grizzly.java.net

Re: SEVERE: ProtocolChain exception - ARP over HTTPS problem

From: Jeanfrancois Arcand <Jeanfrancois.Arcand_at_Sun.COM>
Date: Wed, 12 Mar 2008 15:59:30 -0400

Salut,

Danijel wrote:
> Hello,
>
> I'm trying to do some async request processing, but I get an error.
>
> I tried to code some ARP using Brian McCallister example
> (http://kasparov.skife.org/blog/src/java/grizzly-arp-basic.html) as a
> starting point, I added some of my own code like a ResumeThead and
> TransactionHandler so that I can send response before scheduler call if I
> have a response ready.
>
> Now, my code works fine in a HTTP version, but same code in a HTTPS version
> fails and throws SEVERE
> exception, only difference beetween the two is that HTTPS version uses
> SSLSelectorThread.




>
> I tested this both with grizzly-http-webserver jars in version 1.7.1 and
> 1.7.2.
>
> Finally I downloaded 1.7.2 source code from SVN and did some debugging.
>
> Here what I found:
>
> When execution comes to DefaultProtocolChain::executeProtocolFilter method I
> see that in my
> protocol chain there are 2 filters SSLReadFilter and SSLAsyncProtocolFilter
>
> SSLReadFilter executes fine but SSLAsyncProtocolFilter fails,
> and it fails in AsyncProtocolFilter:: execute method at nextBuffer.clear();
>
> /**
> * Switch ByteBuffer since we are asynchronous.
> */
> ByteBuffer nextBuffer = inputStream.getByteBuffer();
> nextBuffer.clear();
>
> This inputStream.getByteBuffer(); returns null, and there for I get
> NullPointerException
> inputStream's inputBB buffer exists but byteBuffer does not, it's null
>
> Any ideas how to solve this?
>
> I'll put code of my main SSLApp class below and here is my output.

Looks like a bug. Can you file an issue here:

https://grizzly.dev.java.net/issues/

so this time I don't forget to reply.

I will take a look as soon as possible...I'm at a php conference and
well, this is a little boring so I might fix the issue today. If not,
tomorrow for sure as your issue is most probably reproducible using
GlassFish v3, which means they will file an issue as well :-)!

A+

-- Jeanfrancois





>
> Mar 12, 2008 7:49:39 PM com.sun.grizzly.http.SelectorThread
> displayConfiguration
> INFO:
> Grizzly configuration for port 8282
> maxThreads: 5
> minThreads: 5
> ByteBuffer size: 8192
> useDirectByteBuffer: false
> useByteBufferView: false
> maxHttpHeaderSize: 8192
> maxKeepAliveRequests: 256
> keepAliveTimeoutInSeconds: 30
> Static File Cache enabled: true
> Stream Algorithm : com.sun.grizzly.http.algorithms.NoParsingAlgorithm
> Pipeline : com.sun.grizzly.http.LinkedListPipeline
> Round Robin Selector Algorithm enabled: false
> Round Robin Selector pool size: 0
> recycleTasks: true
> Asynchronous Request Processing enabled: true
> Mar 12, 2008 7:51:00 PM com.sun.grizzly.DefaultProtocolChain
> executeProtocolFilter
> SEVERE: ProtocolChain exception
> java.lang.NullPointerException
> at
> com.sun.grizzly.arp.AsyncProtocolFilter.execute(AsyncProtocolFilter.java:136)
> at
> com.sun.grizzly.DefaultProtocolChain.executeProtocolFilter(DefaultProtocolChain.java:101)
> at
> com.sun.grizzly.DefaultProtocolChain.execute(DefaultProtocolChain.java:78)
> at com.sun.grizzly.http.SelectorThread$1.execute(SelectorThread.java:669)
> at
> com.sun.grizzly.ProtocolChainContextTask.doCall(ProtocolChainContextTask.java:54)
> at
> com.sun.grizzly.SelectionKeyContextTask.call(SelectionKeyContextTask.java:57)
> at com.sun.grizzly.util.WorkerThreadImpl.run(WorkerThreadImpl.java:179)
>
>
>
> import java.io.IOException;
> import java.util.HashMap;
> import java.util.concurrent.ArrayBlockingQueue;
>
> import com.sun.grizzly.SSLConfig;
> import com.sun.grizzly.arp.DefaultAsyncHandler;
> import com.sun.grizzly.http.AsyncExecutor;
> import com.sun.grizzly.http.AsyncFilter;
> import com.sun.grizzly.http.AsyncHandler;
> import com.sun.grizzly.http.AsyncTask;
> import com.sun.grizzly.http.DefaultProcessorTask;
> import com.sun.grizzly.http.SelectorThread;
> import com.sun.grizzly.ssl.SSLSelectorThread;
> import com.sun.grizzly.util.buf.ByteChunk;
> import com.sun.grizzly.util.net.jsse.JSSEImplementation;
>
> public class SSLApp {
> public static ArrayBlockingQueue<NameValue> msgs = new
> ArrayBlockingQueue<NameValue>( 100 );
> public static HashMap<String, TransactionHandler> map = new HashMap<String,
> TransactionHandler>();
> public static String TRAN_ID = "ID";
> static long count = 0;
> public static void main( String[] args ) {
> SSLApp app = new SSLApp();
> ServerStarter ss = app.new ServerStarter();
> ss.start();
> ResumerThread resThread = new ResumerThread();
> resThread.start();
> }
>
> public class ServerStarter extends Thread {
> private SSLConfig sslConfig;
>
> private void setUp() {
> sslConfig = new SSLConfig();
> // override system properties
> sslConfig.setTrustStoreFile("c:/temp/key/ssltest-cacerts.jks");
> sslConfig.setKeyStoreFile("c:/temp/key/ssltest-keystore.jks");
> }
>
> private SelectorThread createSelectorThread(int port) {
> SSLSelectorThread selectorThread = new SSLSelectorThread();
> selectorThread.setPort(port);
> SSLSelectorThread.setWebAppRootPath( "/dev/null" );
> selectorThread.setSSLConfig(sslConfig);
> try {
> selectorThread.setSSLImplementation( new JSSEImplementation() );
> } catch ( ClassNotFoundException e ) {
> // TODO Auto-generated catch block
> e.printStackTrace();
> }
> AsyncHandler handler = new DefaultAsyncHandler();
> handler.addAsyncFilter( new MyAsyncFilter() );
> selectorThread.setAsyncHandler( handler );
> selectorThread.setEnableAsyncExecution( true );
> selectorThread.setAdapter( new MyAdapter() );
> return selectorThread;
> }
> @Override
> public void run() {
> setUp();
> SelectorThread sel = createSelectorThread( 8282 );
> sel.setDisplayConfiguration( true );
> try {
> sel.initEndpoint();
> sel.startEndpoint();
> } catch ( IOException e ) {
> e.printStackTrace();
> } catch ( InstantiationException e ) {
> e.printStackTrace();
> }
> }
> }
> private class MyAsyncFilter implements AsyncFilter {
> public boolean doFilter( AsyncExecutor executor ) {
> System.out.println("DO_FILTER");
> AsyncTask asyncTask = executor.getAsyncTask();
> AsyncHandler asyncHandler = executor.getAsyncHandler();
> DefaultProcessorTask processorTask = (DefaultProcessorTask)
> executor.getAsyncTask().getProcessorTask();
> int contentLenght = processorTask.getRequest().getContentLength();
> ByteChunk byteChunk = new ByteChunk();
> byteChunk.setLimit( contentLenght );
> try {
> processorTask.getRequest().doRead( byteChunk );
> } catch ( IOException e ) {
> e.printStackTrace();
> }
> String requestURI = processorTask.getRequest().requestURI().toString();
> System.out.println("New incoming to service: " + getService( requestURI
> ));
> String inStr = byteChunk.toString();
> TransactionHandler transHandler = new TransactionHandler();
> transHandler.setMsg( inStr );
> transHandler.setRunnable( new MyRunnable( asyncHandler, asyncTask ) );
> map.put( Long.toString( count), transHandler );
> processorTask.getRequest().setAttribute( TRAN_ID, Long.toString( count)
> );
> processorTask.invokeAdapter();
> return false;
> }
> }
>
> /**
> * Get the service that is mapped to the specified request.
> */
> private String getService( String uri ) {
> if ( uri == null )
> return "";
> String serviceName="";
> if ( uri.startsWith( "/" ) ) {
> serviceName = uri.substring( 1 );
> } else {
> serviceName = uri;
> }
> return serviceName;
> }
> }
>
> -----
> --
> Danijel