I'm new to the Play Framework and just trying to get HTTPS going for the first time with 2.4.2 on Java 8. I can get it working with the default keystore but not with my own keystore. I configured the working default keystore in build.sbt
:
javaOptions ++= Seq(
"-Dhttps.port=9443"
)
Then the official documentation for configuring your own keystore gets a bit too abstract for me. It mentions configuring it in application.conf
but doesn't say how, or on the command line but not with a Java example. Googling reveals some Scala examples but I cannot cajole them as they use things like devSettings
that don't seem to come across to the Java world, or at least I do not understand Play and Scala enough to get a grip on them.
So as far as I know I seem to be using my own unique configuration in build.sbt
:
javaOptions ++= Seq(
"-Dhttps.port=9443",
"-Dhttps.keyStore.path=keystore.jks",
"-Dhttps.keyStore.password=password")
It builds and runs ok:
p.c.s.NettyServer - Listening for HTTPS on port /0:0:0:0:0:0:0:0:9443
play.api.Play - Application started (Dev)
But on the first https:// access I get an endless stack trace in the Actuator UI:
play.core.server.NettyServer$PlayPipelineFactory - cannot load SSL context
java.lang.reflect.InvocationTargetException: null
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method) ~[na:1.8.0_45]
...
play.core.server.netty.PlayDefaultUpstreamHandler - Exception caught in Netty
java.lang.IllegalArgumentException: empty text
at org.jboss.netty.handler.codec.http.HttpVersion.<init>(HttpVersion.java:89) ~[netty-3.10.3.Final.jar:na]
...
My first thought is that I'm not configuring it correctly but I haven't managed to find a definitive guide for Play 2.4. I'm seriously starting to question my Googling powers. I find lots of references to front-end proxies and avoiding SSL termination in Play but I'm not developing a public website and find this approach overkill.
I don't know if it's a red herring but the Netty project dropped the org.jboss.netty
a long time ago and now uses io.netty
. I see org.jboss.netty all over the stack trace and Play 2.4.2 seems to be using Netty 3.10.3.Final which is very old. I happen to be familiar with Netty and have used 4.x in production while 5.x is currently in Alpha. Why is Play stuck in the past here? Should I be worried?
I found several issues which seem closely related such as a bug in Play 2.2.x and a bug in AHC (which Play uses), but both appear to have been fixed well before Play 2.4.2 that I'm using. Nevertheless I tried fixes such as upgrading the async-http-client dependency, excluding the org.jboss.netty transitive dependency from async-http-client and upgrading to Netty 3.10.4.Final.
So now I'm stuck but I feel like I'm just missing a getting started guide. Maybe all these dependency issues and related bugs are just a waste of time?
So 5 minutes after posting the question I figured it out... My configuration keys were wrong and the keystore path needed to be either absolute or relative to the project root (i.e. add conf/ if it's in your conf folder):
javaOptions ++= Seq(
"-Dhttps.port=9443",
"-Dhttps.keyStore=conf/keystore.jks",
"-Dhttps.keyStorePassword=password")
My mistake with the keys was to use dots per the documentation:
https.keyStore.path
https.keyStore.password
Instead of:
https.keyStore
https.keyStorePassword
I'm not sure how one gets from dot.notation to camelCase or even what exactly I'm configuring here. These parameters are more like the standard JVM arguments javax.net.ssl.keyStore
and javax.net.ssl.keyStorePassword
, yet not quite. I feel like I'm missing a trick here. It would also be nice if Play would report that it couldn't find the keystore rather than an NPE, but since I seem to be configuring the JVM maybe there's nothing Play can do about it unless there is another way to configure this stuff... with decent documentation!
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With