playframework/playframework

2.6.0-M1 Migration: NumberFormatException in WSClient

Closed this issue · 9 comments

Play Version (2.5.x / etc)

2.6.0-M1

API (Scala / Java / Neither / Both)

Both

Operating System (Ubuntu 15.10 / MacOS 10.10 / Windows 10)

MacOS 10.11.6 El Capitan

JDK (Oracle 1.8.0_72, OpenJDK 1.8.x, Azul Zing)

java version "1.8.0_102"
Java(TM) SE Runtime Environment (build 1.8.0_102-b14)
Java HotSpot(TM) 64-Bit Server VM (build 25.102-b14, mixed mode)

Expected Behavior

Application starts up, guice works.

Actual Behavior

I get the following exception, when guice tries to instantiate the shaded asynchttpclient.

Caused by: java.lang.NumberFormatException: null
at java.lang.Integer.parseInt(Integer.java:542)
at java.lang.Integer.parseInt(Integer.java:615)
at play.shaded.ahc.org.asynchttpclient.config.AsyncHttpClientConfigHelper$Config.getInt(AsyncHttpClientConfigHelper.java:85)
at play.shaded.ahc.org.asynchttpclient.config.AsyncHttpClientConfigDefaults.defaultMaxRedirects(AsyncHttpClientConfigDefaults.java:68)
at play.shaded.ahc.org.asynchttpclient.DefaultAsyncHttpClientConfig$Builder.(DefaultAsyncHttpClientConfig.java:599)
at play.api.libs.ws.ahc.AhcConfigBuilder.(AhcConfig.scala:127)
at play.api.libs.ws.ahc.AsyncHttpClientProvider.(AhcWSClientProvider.scala:36)
at play.api.libs.ws.ahc.AsyncHttpClientProvider$$FastClassByGuice$$68dd0aee.newInstance()
at com.google.inject.internal.DefaultConstructionProxyFactory$FastClassProxy.newInstance(DefaultConstructionProxyFactory.java:89)
at com.google.inject.internal.ConstructorInjector.provision(ConstructorInjector.java:111)
at com.google.inject.internal.ConstructorInjector.construct(ConstructorInjector.java:90)
at com.google.inject.internal.ConstructorBindingImpl$Factory.get(ConstructorBindingImpl.java:268)
at com.google.inject.internal.ProviderToInternalFactoryAdapter$1.call(ProviderToInternalFactoryAdapter.java:46)
at com.google.inject.internal.InjectorImpl.callInContext(InjectorImpl.java:1092)
at com.google.inject.internal.ProviderToInternalFactoryAdapter.get(ProviderToInternalFactoryAdapter.java:40)
.....

I don't have any specific ws.* settings in my configuration files.

It would be great to also get the shaded sources when importing the sources into IntelliJ .. I'm not sure, how hard that is to make, but it would make debugging much easier.

Ok, I think I found the issue:
image

shaded-asynchttpclient-1.0.0-M4.jar!/play/shaded/ahc/org/asynchttpclient/config/AsyncHttpClientConfigDefaults.class

public static int defaultMaxRedirects() { return AsyncHttpClientConfigHelper.getAsyncHttpClientConfig().getInt("play.shaded.ahc.org.asynchttpclient.maxRedirects"); }

wants to read play.shaded.ahc.org.asynchttpclient.maxRedirects
however, the config keys that are available at runtime don't start with play.shaded.ahc.org.asynchttpclient but with the default org.asynchttpclient
I'm not quite sure how this can happen, but it does.

I've got new insights and documented them in the play-ws project:
playframework/play-ws#87

Apparently its a classpath issue where the shaded ahc-client uses the ThreadContext-Classloader instead of the classloader used to load the current class. this results in reading the ahc-default.properties of the normal/unshaded ahc-client I have on the classpath.

/cc @wsargent

Workaround (for anyone else running into this problem):
create the file
/conf/ahc-default.properties with the contents of this gist https://gist.github.com/domdorn/3c80fac337ffc847650ae5f547f62c55

mkurz commented

I've got new insights and documented them in the play-ws project:
#7056

You probably mean playframework/play-ws#87

@mkurz correct, thx!

Please revert to use non-shaded version of ahc/netty.
Now we cannot use native transport from reacently released netty 4.1.9.Final because shaded version in Play framework contains different version of the native library.
Now it fails with following error when we try to create custom EventLoopGroup:

Caused by: java.lang.UnsatisfiedLinkError: could not load a native library: netty-transport-native-epoll
	at io.netty.util.internal.NativeLibraryLoader.load(NativeLibraryLoader.java:228)
	at io.netty.channel.epoll.Native.loadNativeLibrary(Native.java:269)
	at io.netty.channel.epoll.Native.<clinit>(Native.java:64)
	at io.netty.channel.epoll.IovArray.<clinit>(IovArray.java:57)
	at io.netty.channel.epoll.EpollEventLoop.<init>(EpollEventLoop.java:54)
	at io.netty.channel.epoll.EpollEventLoopGroup.newChild(EpollEventLoopGroup.java:135)
	at io.netty.channel.epoll.EpollEventLoopGroup.newChild(EpollEventLoopGroup.java:35)
	at io.netty.util.concurrent.MultithreadEventExecutorGroup.<init>(MultithreadEventExecutorGroup.java:84)
	at io.netty.util.concurrent.MultithreadEventExecutorGroup.<init>(MultithreadEventExecutorGroup.java:58)
	at io.netty.channel.MultithreadEventLoopGroup.<init>(MultithreadEventLoopGroup.java:51)
	at io.netty.channel.epoll.EpollEventLoopGroup.<init>(EpollEventLoopGroup.java:105)
	at io.netty.channel.epoll.EpollEventLoopGroup.<init>(EpollEventLoopGroup.java:68)
	at com.strikead.navarro.config.NavarroModule.eventLoopGroup(NavarroModule.scala:68)
	at com.strikead.navarro.config.NavarroModule$$FastClassByGuice$$acc3ff1a.invoke(<generated>)
	at com.google.inject.internal.ProviderMethod$FastClassProviderMethod.doProvision(ProviderMethod.java:264)
	at com.google.inject.internal.ProviderMethod$Factory.provision(ProviderMethod.java:401)
	at com.google.inject.internal.ProviderMethod$Factory.get(ProviderMethod.java:376)
	at com.google.inject.internal.ProviderToInternalFactoryAdapter$1.call(ProviderToInternalFactoryAdapter.java:46)
	at com.google.inject.internal.InjectorImpl.callInContext(InjectorImpl.java:1092)
	at com.google.inject.internal.ProviderToInternalFactoryAdapter.get(ProviderToInternalFactoryAdapter.java:40)
	at com.google.inject.internal.SingletonScope$1.get(SingletonScope.java:194)
	at com.google.inject.internal.InternalFactoryToProviderAdapter.get(InternalFactoryToProviderAdapter.java:41)
	at com.google.inject.internal.SingleParameterInjector.inject(SingleParameterInjector.java:38)
	at com.google.inject.internal.SingleParameterInjector.getAll(SingleParameterInjector.java:62)
	at com.google.inject.internal.ConstructorInjector.provision(ConstructorInjector.java:110)
	at com.google.inject.internal.ConstructorInjector.construct(ConstructorInjector.java:90)
	at com.google.inject.internal.ConstructorBindingImpl$Factory.get(ConstructorBindingImpl.java:268)
	at com.google.inject.internal.ProviderToInternalFactoryAdapter$1.call(ProviderToInternalFactoryAdapter.java:46)
	at com.google.inject.internal.InjectorImpl.callInContext(InjectorImpl.java:1092)
	at com.google.inject.internal.ProviderToInternalFactoryAdapter.get(ProviderToInternalFactoryAdapter.java:40)
	at com.google.inject.internal.SingletonScope$1.get(SingletonScope.java:194)
	at com.google.inject.internal.InternalFactoryToProviderAdapter.get(InternalFactoryToProviderAdapter.java:41)
	at com.google.inject.internal.FactoryProxy.get(FactoryProxy.java:56)
	at com.google.inject.internal.InternalInjectorCreator$1.call(InternalInjectorCreator.java:205)
	at com.google.inject.internal.InternalInjectorCreator$1.call(InternalInjectorCreator.java:199)
	at com.google.inject.internal.InjectorImpl.callInContext(InjectorImpl.java:1085)
	at com.google.inject.internal.InternalInjectorCreator.loadEagerSingletons(InternalInjectorCreator.java:199)
	at com.google.inject.internal.InternalInjectorCreator.injectDynamically(InternalInjectorCreator.java:180)
	at com.google.inject.internal.InternalInjectorCreator.build(InternalInjectorCreator.java:110)
	at com.google.inject.Guice.createInjector(Guice.java:99)
	at com.google.inject.Guice.createInjector(Guice.java:84)
	at play.api.inject.guice.GuiceBuilder.injector(GuiceInjectorBuilder.scala:181)
	at play.api.inject.guice.GuiceApplicationBuilder.build(GuiceApplicationBuilder.scala:137)
	at play.api.inject.guice.GuiceApplicationLoader.load(GuiceApplicationLoader.scala:21)
	at play.core.server.ProdServerStart$.start(ProdServerStart.scala:47)
	at play.core.server.ProdServerStart$.main(ProdServerStart.scala:22)
	at play.core.server.ProdServerStart.main(ProdServerStart.scala)
Caused by: java.lang.RuntimeException: failed to get field ID: DefaultFileRegion.transfered
	at java.lang.ClassLoader$NativeLibrary.load(Native Method)
	at java.lang.ClassLoader.loadLibrary0(ClassLoader.java:1941)
	at java.lang.ClassLoader.loadLibrary(ClassLoader.java:1824)
	at java.lang.Runtime.load0(Runtime.java:809)
	at java.lang.System.load(System.java:1086)
	at io.netty.util.internal.NativeLibraryUtil.loadLibrary(NativeLibraryUtil.java:36)
	at io.netty.util.internal.NativeLibraryLoader.loadLibrary(NativeLibraryLoader.java:259)
	at io.netty.util.internal.NativeLibraryLoader.load(NativeLibraryLoader.java:226)
	... 46 more

@domdorn are you still seeing this? I'm not really sure what I can do about playframework/play-ws#87 without swapping out the AHC implementation during shading...

hmm... I'm off the project where I had that error. There I "fixed" it by providing my own ahc.properties file that included the normal properties (from the ahc-jar) and the shaded ones (from the play one) ...
The problem probably will arise if people are using AHC directly as a dependency in their project, e.g. for using a third-party api-client that builds on AHC. Should I try to create a test-project ?

Closing for the playframework/play-ws#87 issue