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

Bug 362407

Summary: Spring configuration of truststore fails for SslContextFactory
Product: [RT] Jetty Reporter: David Rosell <wmdaros>
Component: serverAssignee: Jesse McConnell <jesse.mcconnell>
Status: CLOSED FIXED QA Contact:
Severity: normal    
Priority: P3 CC: jetty-inbox, wmdaros
Version: 7.5.4   
Target Milestone: 7.0.1 M0   
Hardware: Macintosh   
OS: Mac OS X - Carbon (unsup.)   
Whiteboard:
Attachments:
Description Flags
Diff for suggested change and tests
none
And a proper git patch file (same as above) jesse.mcconnell: iplog+

Description David Rosell CLA 2011-10-29 16:36:30 EDT
The setTrustStore(..) method in SslContextFactory class is overloaded. It either takes a String or a Resource.

This is a problem when configuring a truststore with SpringFramework since (according to them) the JavaBean specification doesn't allow overloading of setters.
What happens is that when Spring looks for a property to inject into, it will stopp looking when it finds the first method with the correct name - and if it happens to be the setter taking a String, the Resource object provided will not be accepted.

The setKeyStore(..) method has a similar companion, but is named setKeyStoreResource(..), so here there are no problem.

I suggest a renaming of the method taking a Resource as inparameter to setTrustStoreResource(..) so that it will follow the same pattern as for the keystore setter.

The reason this is important is that this change will enable a big improvement for handeling keystore-/ truststore-files used by tests. Instead of having to specify a system base-path, these resources can be loaded from classpath:

Resource.newSystemResource("keystore");

When using classpath there is no differences when running inside the IDE or in Maven.

This configuration can easily be done in spring as well:

  <bean id="sslContextFactory" class="org.eclipse.jetty.http.ssl.SslContextFactory">
    <property name="keyStoreResource" ref="keyStoreResource" />
    <property name="trustStoreResource" ref="trustStoreResource"/>
  </bean>

  <bean id="keyStoreResource" class="org.eclipse.jetty.util.resource.Resource" factory-method="newSystemResource">
    <constructor-arg value="${server.keystore}"/>
  </bean>

  <bean id="trustStoreResource" class="org.eclipse.jetty.util.resource.Resource" factory-method="newSystemResource">
    <constructor-arg value="${server.truststore}"/>
  </bean>

A diff of the suggested change and tests for it are attached.

There are another point to this as well.
setKeyStore(..) is overridden in a similar way - taking either a String or a KeyStore objekt. This class together with SslSelectChannelConnector are heavily used  for configuring Jetty. It is risky to depend on the good will of the JVM for which method will come up on top when Spring is searching for a place to inject. It works correct for me on OsX and on our UbuntuServer - but who knows what will break it in the future...

So, setKeyStore(..) should not be overloaded...
Comment 1 David Rosell CLA 2011-10-29 16:39:02 EDT
Created attachment 206170 [details]
Diff for suggested change and tests
Comment 2 David Rosell CLA 2011-10-29 18:39:16 EDT
Created attachment 206171 [details]
And a proper git patch file (same as above)
Comment 3 Jesse McConnell CLA 2011-11-02 15:41:39 EDT
I have applied this, thanks for the patch!