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

graal unable to make simple HTTP request #926

Closed
bootstraponline opened this issue Jan 20, 2019 · 5 comments
Closed

graal unable to make simple HTTP request #926

bootstraponline opened this issue Jan 20, 2019 · 5 comments
Assignees

Comments

@bootstraponline
Copy link

bootstraponline commented Jan 20, 2019

I have a reproducible example here:
https://github.com/bootstraponline/native-image-GenericJson

Tested on graalvm-ce-1.0.0-rc11 with Java 1.8.0_192 on macOS 10.14.2

Run ./native_build.sh

Run ./gtest

Observe

./gtest
Exception in thread "main" com.oracle.svm.core.jdk.UnsupportedFeatureError: Accessing an URL protocol that was not enabled. The URL protocol https is supported but not enabled by default. It must be enabled by adding the --enable-url-protocols=https option to the native-image command.
	at com.oracle.svm.core.util.VMError.unsupportedFeature(VMError.java:109)
	at com.oracle.svm.core.jdk.JavaNetSubstitutions.unsupported(JavaNetSubstitutions.java:164)
	at com.oracle.svm.core.jdk.JavaNetSubstitutions.getURLStreamHandler(JavaNetSubstitutions.java:151)
	at java.net.URL.getURLStreamHandler(URL.java:60)
	at java.net.URL.<init>(URL.java:599)
	at java.net.URL.<init>(URL.java:490)
	at java.net.URL.<init>(URL.java:439)
	at com.google.api.client.http.GenericUrl.parseURL(GenericUrl.java:637)
	at com.google.api.client.http.GenericUrl.<init>(GenericUrl.java:115)
	at com.google.api.client.auth.oauth2.Credential$Builder.setTokenServerEncodedUrl(Credential.java:746)
	at com.google.api.client.googleapis.auth.oauth2.GoogleCredential$Builder.setTokenServerEncodedUrl(GoogleCredential.java:832)
	at com.google.api.client.googleapis.auth.oauth2.GoogleCredential$Builder.<init>(GoogleCredential.java:563)
	at com.google.api.client.googleapis.testing.auth.oauth2.MockGoogleCredential$Builder.<init>(MockGoogleCredential.java:58)
	at gtest.Main$Companion$defaultCredential$2.invoke(Main.kt:31)
	at gtest.Main$Companion$defaultCredential$2.invoke(Main.kt:12)
	at kotlin.SynchronizedLazyImpl.getValue(LazyJVM.kt:74)
	at gtest.Main$Companion.getDefaultCredential(Main.kt)
	at gtest.Main$Companion$toolResults$2.invoke(Main.kt:22)
	at gtest.Main$Companion$toolResults$2.invoke(Main.kt:12)
	at kotlin.SynchronizedLazyImpl.getValue(LazyJVM.kt:74)
	at gtest.Main$Companion.getToolResults(Main.kt)
	at gtest.Main$Companion.main(Main.kt:48)
	at gtest.Main.main(Main.kt)

In addition I also see:

Caused by: java.lang.IllegalArgumentException: unable to create new instance of class com.google.api.client.json.GenericJson because it has no accessible default constructor
	at com.google.api.client.util.Types.handleExceptionForNewInstance(Types.java:165)
	at com.google.api.client.util.Types.newInstance(Types.java:120)
	at com.google.api.client.util.Data.newMapInstance(Data.java:526)
	at com.google.api.client.json.JsonParser.parseValue(JsonParser.java:763)
	... 37 more
Caused by: java.lang.InstantiationException: Type `com.google.api.client.json.GenericJson` can not be instantiated reflectively as it does not have a no-parameter constructor or the no-parameter constructor has not been added explicitly to the native image.
	at java.lang.Class.newInstance(DynamicHub.java:652)
	at com.google.api.client.util.Types.newInstance(Types.java:116)
	... 39 more

which is not solved by:

[
  {
    "name" : "com.google.api.client.json.GenericJson",
    "methods": [
      { "name": "<init>", "parameterTypes": [] }
    ],
    "allDeclaredConstructors" : true,
    "allPublicConstructors" : true,
    "allDeclaredMethods" : true,
    "allPublicMethods" : true
  },

Also...

Error: No instances are allowed in the image heap for a class that is initialized or reinitialized at image runtime: sun.security.provider.NativePRNG
Trace: 	object java.security.SecureRandom
	object sun.security.ssl.SSLContextImpl$TLSContext
	object sun.security.ssl.SSLSocketFactoryImpl
	object com.google.api.client.http.javanet.NetHttpTransport
	field gtest.gcloud.Config.HTTP_TRANSPORT

Error: Image building with exit status 1

Graal native images are unable to make basic HTTP requests to Google services using the Java client libraries.

@sniperliu
Copy link

Same here, use goolge api

Error: No instances are allowed in the image heap for a class that is initialized or reinitialized at image runtime: sun.security.provider.NativePRNG
Trace: 	object java.security.SecureRandom
	object sun.security.ssl.SSLContextImpl$TLSContext
	object sun.security.ssl.SSLSocketFactoryImpl
	object com.google.api.client.http.javanet.NetHttpTransport
	object clojure.lang.Var
	method google_apps_clj.credentials$get_auth_map.invokeStatic(Object, Object)

@ludoch
Copy link

ludoch commented Mar 13, 2019

For Cloud Datastore (link above), the error is like:

A Caused by: java.lang.IllegalArgumentException: unable to create new instance of class com.google.api.client.util.GenericData because it has no accessible default constructor
A at com.google.api.client.util.Types.handleExceptionForNewInstance(Types.java:165)
A at com.google.api.client.util.Types.newInstance(Types.java:120)
A at com.google.api.client.util.Data.newMapInstance(Data.java:526)
A at com.google.api.client.json.JsonParser.parseValue(JsonParser.java:762)
A ... 93 more
A Caused by: java.lang.InstantiationException: Type com.google.api.client.util.GenericData can not be instantiated reflectively as it does not have a no-parameter constructor or the no-parameter constructor has not been added explicitly to the native image.
A at java.lang.Class.newInstance(DynamicHub.java:653)
A at com.google.api.client.util.Types.newInstance(Types.java:116)

@nhoughto
Copy link

nhoughto commented Jul 2, 2019

Hmm feels like this should work with latest graal builds?
The above error is likely a reflection config problem?

@jramirez-isc
Copy link

@bootstraponline you can try with GraalVM version 19.2.0 or later. Also, use the native-image-agent to automatically detect reflectively accessed elements.

I did some local testing using your code, and I had to modify some of the options:

native-image \
  -H:+ReportUnsupportedElementsAtRuntime \
  --no-server \
  --allow-incomplete-classpath \
  --rerun-class-initialization-at-runtime=javax.net.ssl.SSLContext \
  -H:-UseServiceLoaderFeature \
  --enable-all-security-services \
  -H:ConfigurationFileDirectories=config-dir \
  -H:EnableURLProtocols=http,https \
  -jar ./build/libs/gtest-SNAPSHOT.jar

Note: -H:ConfigurationFileDirectories=config-dir is referencing the folder generated by the native-image-agent.

One thing I noticed is when I run the .jar itself with java -jar build/libs/gtest-SNAPSHOT.jar the output is this:

Exception in thread "main" java.net.ConnectException: Connection refused (Connection refused)
	at java.net.PlainSocketImpl.socketConnect(Native Method)
	at java.net.AbstractPlainSocketImpl.doConnect(AbstractPlainSocketImpl.java:350)
	at java.net.AbstractPlainSocketImpl.connectToAddress(AbstractPlainSocketImpl.java:206)
	at java.net.AbstractPlainSocketImpl.connect(AbstractPlainSocketImpl.java:188)
	at java.net.SocksSocketImpl.connect(SocksSocketImpl.java:392)
	at java.net.Socket.connect(Socket.java:589)
	at sun.net.NetworkClient.doConnect(NetworkClient.java:175)
	at sun.net.www.http.HttpClient.openServer(HttpClient.java:463)
	at sun.net.www.http.HttpClient.openServer(HttpClient.java:558)
	at sun.net.www.http.HttpClient.<init>(HttpClient.java:242)
	at sun.net.www.http.HttpClient.New(HttpClient.java:339)
	at sun.net.www.http.HttpClient.New(HttpClient.java:357)
	at sun.net.www.protocol.http.HttpURLConnection.getNewHttpClient(HttpURLConnection.java:1220)
	at sun.net.www.protocol.http.HttpURLConnection.plainConnect0(HttpURLConnection.java:1156)
	at sun.net.www.protocol.http.HttpURLConnection.plainConnect(HttpURLConnection.java:1050)
	at sun.net.www.protocol.http.HttpURLConnection.connect(HttpURLConnection.java:984)
	at sun.net.www.protocol.http.HttpURLConnection.getOutputStream0(HttpURLConnection.java:1334)
	at sun.net.www.protocol.http.HttpURLConnection.getOutputStream(HttpURLConnection.java:1309)
	at com.google.api.client.http.javanet.NetHttpRequest.execute(NetHttpRequest.java:113)
	at com.google.api.client.http.javanet.NetHttpRequest.execute(NetHttpRequest.java:84)
	at com.google.api.client.http.HttpRequest.execute(HttpRequest.java:1040)
	at com.google.api.client.googleapis.services.AbstractGoogleClientRequest.executeUnparsed(AbstractGoogleClientRequest.java:515)
	at com.google.api.client.googleapis.services.AbstractGoogleClientRequest.executeUnparsed(AbstractGoogleClientRequest.java:448)
	at com.google.api.client.googleapis.services.AbstractGoogleClientRequest.execute(AbstractGoogleClientRequest.java:565)
	at gtest.Main$Companion.main(Main.kt:37)
	at gtest.Main.main(Main.kt)

And when I run the generated native-image with ./gtest I get the same output. Despite the exception, the native-image is supposedly okay.

@bootstraponline
Copy link
Author

Thanks! I think that's the correct result. On previous versions of Graal, the request itself wasn't sent. The simple example is using a mock server with a mock credential so it's not intended to connect.

I'll close this issue as solved.

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

7 participants