Open cyw3 opened 3 years ago
@cyw3 use native-image tracing agent to create reflect-config.json https://medium.com/graalvm/introducing-the-tracing-agent-simplifying-graalvm-native-image-configuration-c3b56c486271
OK, I try native-image-agent now.
But I encounter some problems:
the same error as #2998. And after I change to use graalvm-jdk11, it works.
org.reflections8.ReflectionsException: could not create Vfs.Dir from url, no matching UrlType was found [resource:]
Steps to reproduce the issue
java -agentlib:native-image-agent=config-output-dir=META-INF/native-image -jar debug.jar -m
ant clean jar
native-image -jar debug.jar -H:Name=debug -H:+ReportUnsupportedElementsAtRuntime -H:+ReportExceptionStackTraces -R:-RemoveNeverExecutedCode -H:-RemoveNeverExecutedCode -H:+AllowIncompleteClasspath
./debug -m
[main] WARN org.reflections8.Reflections - could not create Vfs.Dir from url. ignoring the exception and continuing
org.reflections8.ReflectionsException: could not create Vfs.Dir from url, no matching UrlType was found [resource:]
either use fromURL(final URL url, final List<UrlType> urlTypes) or use the static setDefaultURLTypes(final List<UrlType> urlTypes) or addDefaultURLTypes(UrlType urlType) with your specialized UrlType.
at org.reflections8.vfs.Vfs.fromURL(Vfs.java:118)
at org.reflections8.vfs.Vfs.fromURL(Vfs.java:100)
at org.reflections8.Reflections.scan(Reflections.java:278)
at org.reflections8.Reflections.scan(Reflections.java:236)
at org.reflections8.Reflections.<init>(Reflections.java:155)
at org.reflections8.Reflections.<init>(Reflections.java:200)
at org.reflections8.Reflections.<init>(Reflections.java:173)
at java.lang.reflect.Constructor.newInstance(Constructor.java:490)
at xxx.proj.Main.main(Main.java:25)
[main] WARN org.reflections8.Reflections - could not create Vfs.Dir from url. ignoring the exception and continuing
org.reflections8.ReflectionsException: could not create Vfs.Dir from url, no matching UrlType was found [resource:]
either use fromURL(final URL url, final List<UrlType> urlTypes) or use the static setDefaultURLTypes(final List<UrlType> urlTypes) or addDefaultURLTypes(UrlType urlType) with your specialized UrlType.
at org.reflections8.vfs.Vfs.fromURL(Vfs.java:118)
at org.reflections8.vfs.Vfs.fromURL(Vfs.java:100)
at org.reflections8.Reflections.scan(Reflections.java:278)
at org.reflections8.Reflections.scan(Reflections.java:236)
at org.reflections8.Reflections.<init>(Reflections.java:155)
at org.reflections8.Reflections.<init>(Reflections.java:200)
at org.reflections8.Reflections.<init>(Reflections.java:173)
at java.lang.reflect.Constructor.newInstance(Constructor.java:490)
at xxx.proj.Main.main(Main.java:25)
So How to solve 2nd problem?
OK, I try native-image-agent now.
But I encounter some problems:
- the same error as #2998. And after I change to use graalvm-jdk11, it works.
org.reflections8.ReflectionsException: could not create Vfs.Dir from url, no matching UrlType was found [resource:]
Steps to reproduce the issue
java -agentlib:native-image-agent=config-output-dir=META-INF/native-image -jar debug.jar -m ant clean jar native-image -jar debug.jar -H:Name=debug -H:+ReportUnsupportedElementsAtRuntime -H:+ReportExceptionStackTraces -R:-RemoveNeverExecutedCode -H:-RemoveNeverExecutedCode -H:+AllowIncompleteClasspath ./debug -m
[main] WARN org.reflections8.Reflections - could not create Vfs.Dir from url. ignoring the exception and continuing org.reflections8.ReflectionsException: could not create Vfs.Dir from url, no matching UrlType was found [resource:] either use fromURL(final URL url, final List<UrlType> urlTypes) or use the static setDefaultURLTypes(final List<UrlType> urlTypes) or addDefaultURLTypes(UrlType urlType) with your specialized UrlType. at org.reflections8.vfs.Vfs.fromURL(Vfs.java:118) at org.reflections8.vfs.Vfs.fromURL(Vfs.java:100) at org.reflections8.Reflections.scan(Reflections.java:278) at org.reflections8.Reflections.scan(Reflections.java:236) at org.reflections8.Reflections.<init>(Reflections.java:155) at org.reflections8.Reflections.<init>(Reflections.java:200) at org.reflections8.Reflections.<init>(Reflections.java:173) at java.lang.reflect.Constructor.newInstance(Constructor.java:490) at xxx.proj.Main.main(Main.java:25) [main] WARN org.reflections8.Reflections - could not create Vfs.Dir from url. ignoring the exception and continuing org.reflections8.ReflectionsException: could not create Vfs.Dir from url, no matching UrlType was found [resource:] either use fromURL(final URL url, final List<UrlType> urlTypes) or use the static setDefaultURLTypes(final List<UrlType> urlTypes) or addDefaultURLTypes(UrlType urlType) with your specialized UrlType. at org.reflections8.vfs.Vfs.fromURL(Vfs.java:118) at org.reflections8.vfs.Vfs.fromURL(Vfs.java:100) at org.reflections8.Reflections.scan(Reflections.java:278) at org.reflections8.Reflections.scan(Reflections.java:236) at org.reflections8.Reflections.<init>(Reflections.java:155) at org.reflections8.Reflections.<init>(Reflections.java:200) at org.reflections8.Reflections.<init>(Reflections.java:173) at java.lang.reflect.Constructor.newInstance(Constructor.java:490) at xxx.proj.Main.main(Main.java:25)
So How to solve 2nd problem?
Corresponding to this code:
Reflections ref = new Reflections(scope);
it can not handle with scope
. Why?
How to solve it?
@cyw3 So you are getting error with Java 8 and not with Java 11
OK, I try native-image-agent now. But I encounter some problems:
- the same error as #2998. And after I change to use graalvm-jdk11, it works.
org.reflections8.ReflectionsException: could not create Vfs.Dir from url, no matching UrlType was found [resource:]
Steps to reproduce the issue
java -agentlib:native-image-agent=config-output-dir=META-INF/native-image -jar debug.jar -m ant clean jar native-image -jar debug.jar -H:Name=debug -H:+ReportUnsupportedElementsAtRuntime -H:+ReportExceptionStackTraces -R:-RemoveNeverExecutedCode -H:-RemoveNeverExecutedCode -H:+AllowIncompleteClasspath ./debug -m
[main] WARN org.reflections8.Reflections - could not create Vfs.Dir from url. ignoring the exception and continuing org.reflections8.ReflectionsException: could not create Vfs.Dir from url, no matching UrlType was found [resource:] either use fromURL(final URL url, final List<UrlType> urlTypes) or use the static setDefaultURLTypes(final List<UrlType> urlTypes) or addDefaultURLTypes(UrlType urlType) with your specialized UrlType. at org.reflections8.vfs.Vfs.fromURL(Vfs.java:118) at org.reflections8.vfs.Vfs.fromURL(Vfs.java:100) at org.reflections8.Reflections.scan(Reflections.java:278) at org.reflections8.Reflections.scan(Reflections.java:236) at org.reflections8.Reflections.<init>(Reflections.java:155) at org.reflections8.Reflections.<init>(Reflections.java:200) at org.reflections8.Reflections.<init>(Reflections.java:173) at java.lang.reflect.Constructor.newInstance(Constructor.java:490) at xxx.proj.Main.main(Main.java:25) [main] WARN org.reflections8.Reflections - could not create Vfs.Dir from url. ignoring the exception and continuing org.reflections8.ReflectionsException: could not create Vfs.Dir from url, no matching UrlType was found [resource:] either use fromURL(final URL url, final List<UrlType> urlTypes) or use the static setDefaultURLTypes(final List<UrlType> urlTypes) or addDefaultURLTypes(UrlType urlType) with your specialized UrlType. at org.reflections8.vfs.Vfs.fromURL(Vfs.java:118) at org.reflections8.vfs.Vfs.fromURL(Vfs.java:100) at org.reflections8.Reflections.scan(Reflections.java:278) at org.reflections8.Reflections.scan(Reflections.java:236) at org.reflections8.Reflections.<init>(Reflections.java:155) at org.reflections8.Reflections.<init>(Reflections.java:200) at org.reflections8.Reflections.<init>(Reflections.java:173) at java.lang.reflect.Constructor.newInstance(Constructor.java:490) at xxx.proj.Main.main(Main.java:25)
So How to solve 2nd problem?
Corresponding to this code:
Reflections ref = new Reflections(scope);
it can not handle with
scope
. Why? How to solve it?
@mcraj017
No, i also get this error with java 11.
@cyw3 please provide the reproducer means class or jar to reproduce this
@cyw3 just to confirm, if this application is working using java?
@cyw3 just to confirm, if this application is working using java?
Yes.
@mcraj017
Here is a demo with build.sh
.
#!/bin/bash
ant clean jar
java -agentlib:native-image-agent=config-output-dir=META-INF/native-image -jar release/test-debug.jar
ant clean jar
native-image -jar release/test-debug.jar -H:Name=test -H:+ReportUnsupportedElementsAtRuntime -H:+ReportExceptionStackTraces -R:-RemoveNeverExecutedCode -H:-RemoveNeverExecutedCode -H:+AllowIncompleteClasspath
./test
[main] WARN org.reflections8.Reflections - could not create Vfs.Dir from url. ignoring the exception and continuing
org.reflections8.ReflectionsException: could not create Vfs.Dir from url, no matching UrlType was found [resource:]
either use fromURL(final URL url, final List<UrlType> urlTypes) or use the static setDefaultURLTypes(final List<UrlType> urlTypes) or addDefaultURLTypes(UrlType urlType) with your specialized UrlType.
at org.reflections8.vfs.Vfs.fromURL(Vfs.java:118)
at org.reflections8.vfs.Vfs.fromURL(Vfs.java:100)
at org.reflections8.Reflections.scan(Reflections.java:278)
at org.reflections8.Reflections.scan(Reflections.java:236)
at org.reflections8.Reflections.<init>(Reflections.java:155)
at org.reflections8.Reflections.<init>(Reflections.java:200)
at org.reflections8.Reflections.<init>(Reflections.java:173)
at test.Main.main(Main.java:10)
@cyw3 Thanks for the reproducer
Hi, @christianwimmer . Any progress?
Hi, @mcraj017 , @christianwimmer Any progress?
@christianwimmer - was this resolved by any means or there is some known way to make it work for native image use case? Hitting similar issue today.
When I refactor your example Main
into this:
public class Main {
private static final Reflections ref = new Reflections("visitors");
public static void main(String[] args) {
for (Class<?> clz : ref.getTypesAnnotatedWith(VisitorAnnotation.class)) {
System.out.println(clz);
}
}
}
I can do this:
$ ant clean jar
$ native-image -jar release/test-debug.jar -g -H:Name=test -H:+ReportUnsupportedElementsAtRuntime -H:+ReportExceptionStackTraces -R:-RemoveNeverExecutedCode -H:-RemoveNeverExecutedCode -H:+AllowIncompleteClasspath --initialize-at-build-time=test.Main,org.reflections8.Reflections,org.slf4j
$ ./test
class visitors.TestVisitor
Also note that the binary is much smaller (18.38MB vs 45.33MB) now that org.reflections8.Reflections
is initialized at build-time.
@fniephaus - While original issue here looks to be solvable by the way you provided above - I have additional iteration on top of that still to clarify related aspect to Reflections and Vfs and resource:/
interaction.
Attached use case uses more recent org.reflections 0.10.2 and attempted to run using GraalVM 21.1 + JDK17
Initial steps:
$ mvn clean package
$ java -p target/libs:target/reflections-1.0-SNAPSHOT.jar --module com.example/com.example.Main
Such then produces output like such:
java -p target/libs:target/reflections-1.0-SNAPSHOT.jar --module com.example/com.example.Main
SLF4J: Failed to load class "org.slf4j.impl.StaticLoggerBinder".
SLF4J: Defaulting to no-operation (NOP) logger implementation
SLF4J: See http://www.slf4j.org/codes.html#StaticLoggerBinder for further details.
*** Getting reflections urls...
*** Conf urls: [jar:file:///dev/tmp/reflections/target/reflections-1.0-SNAPSHOT.jar!/]
*** Vfs.dir: /dev/tmp/reflections/target/reflections-1.0-SNAPSHOT.jar
*** Vfs.file: /dev/tmp/reflections/target/reflections-1.0-SNAPSHOT.jar!/META-INF/MANIFEST.MF
*** Vfs.file: /dev/tmp/reflections/target/reflections-1.0-SNAPSHOT.jar!/META-INF/native-image/proxy-config.json
*** Vfs.file: /dev/tmp/reflections/target/reflections-1.0-SNAPSHOT.jar!/META-INF/native-image/resource-config.json
*** Vfs.file: /dev/tmp/reflections/target/reflections-1.0-SNAPSHOT.jar!/META-INF/native-image/jni-config.json
*** Vfs.file: /dev/tmp/reflections/target/reflections-1.0-SNAPSHOT.jar!/META-INF/native-image/reflect-config.json
*** Vfs.file: /dev/tmp/reflections/target/reflections-1.0-SNAPSHOT.jar!/META-INF/native-image/serialization-config.json
*** Vfs.file: /dev/tmp/reflections/target/reflections-1.0-SNAPSHOT.jar!/META-INF/native-image/predefined-classes-config.json
*** Vfs.file: /dev/tmp/reflections/target/reflections-1.0-SNAPSHOT.jar!/META-INF/native-image/native-image.properties
*** Vfs.file: /dev/tmp/reflections/target/reflections-1.0-SNAPSHOT.jar!/com/example/visitors/VisitorAnnotation.class
*** Vfs.file: /dev/tmp/reflections/target/reflections-1.0-SNAPSHOT.jar!/com/example/model/ForVisit.class
*** Vfs.file: /dev/tmp/reflections/target/reflections-1.0-SNAPSHOT.jar!/com/example/Main.class
*** Vfs.file: /dev/tmp/reflections/target/reflections-1.0-SNAPSHOT.jar!/META-INF/maven/org.example/reflections/pom.xml
*** Vfs.file: /dev/tmp/reflections/target/reflections-1.0-SNAPSHOT.jar!/META-INF/maven/org.example/reflections/pom.properties
*** Vfs.file: /dev/tmp/reflections/target/reflections-1.0-SNAPSHOT.jar!/module-info.class
*** Visiting class: class com.example.model.ForVisit
Now if I build that to native-image like such:
native-image -cp ./target/libs/reflections-0.10.2.jar:./target/libs/slf4j-api-1.7.32.jar:./target/libs/javassist-3.28.0-GA.jar -jar target/reflections-1.0-SNAPSHOT.jar
and try to invoke resulting reflections executable - I'm getting this:
$ ./reflections
*** Getting reflections urls...
*** Conf urls: [resource:/]
org.reflections.ReflectionsException: could not create Vfs.Dir from url, no matching UrlType was found [resource:/]
either use fromURL(final URL url, final List<UrlType> urlTypes) or use the static setDefaultURLTypes(final List<UrlType> urlTypes) or addDefaultURLTypes(UrlType urlType) with your specialized UrlType.
at org.reflections.vfs.Vfs.fromURL(Vfs.java:113)
at org.reflections.vfs.Vfs.fromURL(Vfs.java:95)
at com.example.Main.lambda$checkUrls$0(Main.java:24)
at java.util.HashMap$KeySpliterator.forEachRemaining(HashMap.java:1707)
at java.util.stream.ReferencePipeline$Head.forEach(ReferencePipeline.java:762)
at com.example.Main.checkUrls(Main.java:21)
at com.example.Main.main(Main.java:35)
*** Visiting class: class com.example.model.ForVisit
To my understanding resource:
as protocol is supported by default within native-image. Do I need by some other means to make underlying reflections Vfs class/logic to be aware that such is handled, so it will not fail?
I refactored your example so that the Configuration
is also static and with that, it works as expected:
package com.example;
import org.reflections.Reflections;
import org.reflections.scanners.Scanners;
import org.reflections.util.ConfigurationBuilder;
import org.reflections.vfs.Vfs;
import com.example.visitors.VisitorAnnotation;
public class Main {
private static final Reflections ref = new Reflections("com.example.model",
Scanners.FieldsAnnotated, Scanners.TypesAnnotated);
private static final org.reflections.Configuration conf = ConfigurationBuilder.build("com.example.model",
Scanners.FieldsAnnotated, Scanners.TypesAnnotated);
private static void checkUrls() {
System.out.println("*** Getting reflections urls...");
var urls = conf.getUrls();
System.out.println("*** Conf urls: " + urls);
urls.stream().forEach(url -> {
Vfs.Dir dir = null;
try {
dir = Vfs.fromURL(url);
System.out.println("*** Vfs.dir: " + dir);
for (Vfs.File file : dir.getFiles()) {
System.out.println("*** Vfs.file: " + file);
}
} catch (Exception e) {
e.printStackTrace();
}});
}
public static void main(String[] args) {
checkUrls();
for (Class<?> clz : ref.getTypesAnnotatedWith(VisitorAnnotation.class)) {
System.out.println("*** Visiting class: " + clz);
}
}
}
Note that this will back the paths into your native executable, so this may reveal info about your build machine. I don't know what this reflections library is used for but it seems to be something that should be initialized at build-time. In this case, the binary size goes down from 284MB to 29MB when doing this. However, maybe there still is an issue with the virtual file system that provides these resources. Maybe @jovanstevanovic or @olpaw know more about that.
Proposed approach then changes such output line for native image case:
*** Conf urls: [jar:file:/dev/tmp/reflections/target/reflections-1.0-SNAPSHOT.jar!/]
which I'd still expect for native image to be in form of resource:/
reference as it was before proposed change.
Thanks for your proposal:
org.reflections8.Reflections
, org.reflections8.vfs.Vfs
and classes that use Reflections to --initialize-at-build-time
;static final
.For the second point, I still need to modify the source code. Is there a non-intrusive solution that does not require modifying the source code?
For the second point, I still need to modify the source code. Is there a non-intrusive solution that does not require modifying the source code?
If you cannot change source code, I don't think there's much you can do to fix this properly.
Describe the issue I use
org.reflections8.Reflections.getTypesAnnotatedWith()
to get class and do somethings. When I run this java code,org.reflections8.Reflections.getTypesAnnotatedWith()
return a list with lots of class.But after native-images,
org.reflections8.Reflections.getTypesAnnotatedWith()
return a empty list.Steps to reproduce the issue
[Debug:67713] classlist: 5,655.88 ms, 2.15 GB [Debug:67713] (cap): 1,181.31 ms, 2.15 GB [Debug:67713] setup: 2,607.21 ms, 2.23 GB [Debug:67713] (clinit): 362.57 ms, 2.48 GB [Debug:67713] (typeflow): 8,199.46 ms, 2.48 GB [Debug:67713] (objects): 9,683.31 ms, 2.48 GB [Debug:67713] (features): 1,071.99 ms, 2.48 GB [Debug:67713] analysis: 19,700.38 ms, 2.48 GB [Debug:67713] universe: 798.99 ms, 2.61 GB [Debug:67713] (parse): 1,545.43 ms, 2.61 GB [Debug:67713] (inline): 1,695.35 ms, 2.62 GB [Debug:67713] (compile): 14,076.83 ms, 3.22 GB [Debug:67713] compile: 18,250.54 ms, 3.22 GB [Debug:67713] image: 1,744.64 ms, 3.22 GB [Debug:67713] write: 745.69 ms, 3.22 GB [Debug:67713] [total]: 49,705.18 ms, 3.22 GB
I don't know How many classes relate to Reflection.
Describe GraalVM and your environment: