Some Eclipse Foundation services are deprecated, or will be soon. Please ensure you've read this important communication.

Bug 356274

Summary: NullPointerException on SslSocketConnector
Product: [RT] Jetty Reporter: Guy Korland <gkorland>
Component: serverAssignee: Greg Wilkins <gregw>
Status: RESOLVED FIXED QA Contact:
Severity: major    
Priority: P3 CC: jesse.mcconnell, jetty-inbox, moran
Version: 7.4.5   
Target Milestone: 7.5.x   
Hardware: All   
OS: other   
Whiteboard:

Description Guy Korland CLA 2011-08-31 03:00:09 EDT
Build Identifier: 7.4.5

We got a NullPointerException when we use an SslSocketConnector 

instantiate web-1.0 [1]; Caused by: org.jini.rio.core.JSBInstantiationException: java.lang.NullPointerException
	at org.eclipse.jetty.server.ssl.SslSocketConnector.newServerSocket(SslSocketConnector.java:372)
	at org.eclipse.jetty.server.bio.SocketConnector.open(SocketConnector.java:75)

This worked in Jetty 7.1.4, but not in Jetty 7.4.0. 
We have narrowed it down to the SslSocketConnector and specifically the newServerSocket method. 
In Jetty 7.1.4, it is checked if _context == null and if it is, a new SSLContext is created. 
In Jetty 7.4.0 this check is not there anymore so the SSLContext is not created and thus an NPE is thrown because of this. 

It seems like the fix is not part of 7.4.5.
Looking at the source code of the SslSocketFactory.newServerSocket(), I see no change in the Jetty code. 
The method begins like this: 

protected ServerSocket newServerSocket(String host, int port,int backlog) throws IOException 
{ 
SSLServerSocketFactory factory = _sslContextFactory.getSslContext().getServerSocketFactory(); 

In previous versions it was like this: 

@Override 
protected ServerSocket newServerSocket(String host, int port,int backlog) throws IOException 
{ 
SSLServerSocketFactory factory = null; 
SSLServerSocket socket = null; 

try 
{ 
factory = createFactory(); 

socket = (SSLServerSocket) (host==null? 
factory.createServerSocket(port,backlog): 
factory.createServerSocket(port,backlog,InetAddress.getByName(host))); 

The Jetty Server now first makes sure that the SSLServerSocketFactory is created before the newServerSocket() method is called. That is a change in how Jetty should be started. 



Reproducible: Always
Comment 1 Jesse McConnell CLA 2011-08-31 11:11:54 EDT
Could you attach some source showing how your starting this up?  The api has changed a bit for configuring ssl contexts and we should make sure your calling all the right things. 

The ssl context should not be null where your hitting it, that it is makes me wonder if the ssl context factory is being initialized correctly and started.  

alternately this is a blurb from one of our examples showing ssl is configured that might help sort out what is different, its the nio one but the api is the same for it.


        SslSelectChannelConnector ssl_connector = new SslSelectChannelConnector();
        String jetty_home = System.getProperty("jetty.home","../jetty-distribution/target/distribution");
        System.setProperty("jetty.home",jetty_home);
        ssl_connector.setPort(8443);
        SslContextFactory cf = ssl_connector.getSslContextFactory();
        cf.setKeyStore(jetty_home + "/etc/keystore");
        cf.setKeyStorePassword("OBF:1vny1zlo1x8e1vnw1vn61x8g1zlu1vn4");
        cf.setKeyManagerPassword("OBF:1u2u1wml1z7s1z7a1wnl1u2g");


        server.setConnectors(new Connector[]
        { connector0, connector1, ssl_connector });
Comment 2 moran CLA 2011-09-06 04:18:32 EDT
Hi Jesse McConnell,

We are setting up the SslSocketConnector using Spring.

<bean class="org.eclipse.jetty.server.ssl.SslSocketConnector">
<property name="port" ref="confidentialPort"/>
<property name="maxIdleTime" value="${web.selector.maxIdleTime}"/>
<property name="acceptors" value="${web.selector.acceptors}"/>
<property name="statsOn" value="${web.statsOn}"/>
<property name="forwarded" value="${web.selector.forwarded}"/>

<property name="keystore" value="${web.sslselector.keystore}"/>
<property name="password" value="${web.sslselector.password}"/>
<property name="keyPassword" value="${web.sslselector.keypassword}"/>
</bean>

We noticed that in previous versions, the createSSLContext() was part of the 
createFactory() method called by SslSocketConnector.newServerSocket(java.lang.String,int,int) invoked by our call to Connector.open().

In latest version, the createSslContext() is only called on SslContextFactory.doStart() instead of SslSocketConnector.createFactory()

The reason we are calling Connector.open() is to see if the connection can be created using the specified port configuration.

Do you have any suggestions on how to initialize the SSL context at this stage?

Thank you,
Moran
Comment 3 Greg Wilkins CLA 2011-09-20 01:19:42 EDT
I've fixed this by making the open() call start the ssl context if need be