Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[native-image] Scala Apache HttpClient LogConfigurationException #1009

Closed
kronolynx opened this issue Feb 25, 2019 · 3 comments
Closed

[native-image] Scala Apache HttpClient LogConfigurationException #1009

kronolynx opened this issue Feb 25, 2019 · 3 comments
Assignees

Comments

@kronolynx
Copy link

kronolynx commented Feb 25, 2019

I'm getting this error

Exception in thread "main" org.apache.commons.logging.LogConfigurationException: java.lang.ClassNotFoundException: org.
apache.commons.logging.impl.LogFactoryImpl (Caused by java.lang.ClassNotFoundException: org.apache.commons.logging.impl
.LogFactoryImpl)                                                                                                       
        at org.apache.commons.logging.LogFactory.createFactory(LogFactory.java:1158)                                   
        at org.apache.commons.logging.LogFactory$2.run(LogFactory.java:960)                                            
        at java.security.AccessController.doPrivileged(AccessController.java:62)                                       
        at org.apache.commons.logging.LogFactory.newFactory(LogFactory.java:957)                                       
        at org.apache.commons.logging.LogFactory.getFactory(LogFactory.java:624)                                       
        at org.apache.commons.logging.LogFactory.getLog(LogFactory.java:655)                                           
        at org.apache.http.conn.ssl.DefaultHostnameVerifier.<init>(DefaultHostnameVerifier.java:82)                    
        at org.apache.http.impl.client.HttpClientBuilder.build(HttpClientBuilder.java:966)
        at org.apache.http.impl.client.HttpClients.createDefault(HttpClients.java:56)
        at example.Sample$.runSample(ScalaApacheHttpRestClient.scala:19)
        at example.ScalaApacheHttpRestClient$.main(ScalaApacheHttpRestClient.scala:51)
        at example.ScalaApacheHttpRestClient.main(ScalaApacheHttpRestClient.scala)
Caused by: java.lang.ClassNotFoundException: org.apache.commons.logging.impl.LogFactoryImpl
        at com.oracle.svm.core.hub.ClassForNameSupport.forName(ClassForNameSupport.java:51)
        at java.lang.ClassLoader.loadClass(Target_java_lang_ClassLoader.java:127)
        at org.apache.commons.logging.LogFactory.createFactory(LogFactory.java:1020)
        ... 11 more

In issue #768 someone suggest to fix this error using:

{
    "name" : "org.apache.commons.logging.impl.Jdk14Logger",
    "allDeclaredConstructors" : true,
    "allPublicConstructors" : true,
    "allDeclaredMethods" : true,
    "allPublicMethods" : true
  }

I can't make it work on GraalVM 1.0.0-rc12 and I haven't found any other solution.

Steps to reproduce

https://github.com/kronolynx/scala-graal-apache-http

After cloning the project

$ sbt assembly
$ native-image --enable-url-protocols=http,https -H:ReflectionConfigurationFiles=reflect.json --no-server -jar target/scala-2.12/graal-http.jar 
$ ./graal-http
@kronolynx kronolynx changed the title [native-image] Apache HttpClient LogConfigurationException [native-image] Scala Apache HttpClient LogConfigurationException Feb 25, 2019
@cstancu cstancu self-assigned this Feb 25, 2019
@Jurrie
Copy link

Jurrie commented Feb 27, 2019

Hi @kronolynx! While not a direct answer to your question why the reflection configuration doesn't work, I do have an alternative. You could substitute the methods in LogFactory and LogFactoryImpl that do reflection. With the following code (which is based on the work of @DmPanov, I get this to work:

@TargetClass(LogFactory.class)
final class LogFactorySubstituted
{
	@Substitute
	protected static LogFactory newFactory(final String factoryClass, final ClassLoader classLoader, final ClassLoader contextClassLoader)
	{
		return new LogFactoryImpl();
	}
}

@TargetClass(LogFactoryImpl.class)
final class LogFactoryImplSubstituted
{
	@Substitute
	private Log discoverLogImplementation(String logCategory)
	{
		return new SimpleLog(logCategory);
	}
}

The used annotations are in package com.oracle.substratevm:svm.

Of course, you loose the functionality to determine the delegate logging facility at runtime.

@kronolynx
Copy link
Author

kronolynx commented Feb 28, 2019

Thanks @Jurrie
In my case I'm not sure if it's possible to use that kind of substitution, I'm actually trying to make a project in Scala with Elastic4s. Elastic4s uses the apache HttpClient.

@cstancu
Copy link
Member

cstancu commented Oct 13, 2020

@kronolynx the behavior has changed since this issue was opened. I suggest using the Native Image agent to get the complete reflection configuration.

@cstancu cstancu closed this as completed Oct 13, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants