-
Notifications
You must be signed in to change notification settings - Fork 926
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
Generate GraalVM native image config #5005
Conversation
53e05a3
to
f476714
Compare
-PnativeImageConfig
99a3460
to
bead3b3
Compare
07587ae
to
3fc921f
Compare
e9449a3
to
5f6cff1
Compare
5f6cff1
to
1087aac
Compare
Codecov ReportPatch coverage has no change and project coverage change:
Additional details and impacted files@@ Coverage Diff @@
## main #5005 +/- ##
============================================
+ Coverage 74.30% 74.32% +0.01%
- Complexity 19598 19605 +7
============================================
Files 1682 1682
Lines 72252 72252
Branches 9241 9241
============================================
+ Hits 53690 53703 +13
+ Misses 14221 14216 -5
+ Partials 4341 4333 -8 ☔ View full report in Codecov by Sentry. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Left some questions but looks good overall. Thanks @trustin 🙇 👍 🚀
|
||
// Remove 'jetty-alpn-agent' and add 'native-image-agent'. | ||
jvmArgs = jvmArgs.stream().filter { | ||
!(it.startsWith('-javaagent:') && it.endsWith('jetty-alpn-agent.jar')) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit; I believe this isn't needed following #5060
relocatedProjects.each { p -> | ||
if (projectsWithNativeImageSupport.contains(p)) { | ||
p.tasks.getByName('nativeImageTrace').configure { | ||
classpath += p.files(p.configurations.getByName('shadedJarTestRuntime').resolve()) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I see, I understood we have to add this here in a separate afterEvaluate
because the shadedJarTestRuntime
configuration itself is evaluated in a afterEvaluate
.
|
||
private val resourceRegex = """^(?:[._a-zA-Z0-9:]*)\\Q(.*)\\E$""".toRegex() | ||
|
||
private fun filterResources(fileName: String, obj: JsonNode, baseResourcePatterns: Iterable<Regex>) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Question) I don't think I understood the intention of baseResourceConfigFile
😅 Wouldn't the file be used eventually in the nativeImageConfig
task anyways?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You're correct, but they are meant for being used when our 'user' builds a native image. We just use the same set of rules to filter out irrelevant and/or duplicate resource configurations in our native image config.
`GenerateNativeImageTrace` with [`native-image-agent`](https://www.graalvm.org/latest/reference-manual/native-image/metadata/AutomaticMetadataCollection/). | ||
|
||
``` | ||
$ ../gradlew nativeImageConfig |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
When running from my local env. I found the following logs:
Warning: Error processing trace entry map(size=5, {(tracer,reflect),(function,getEnclosingMethod),(caller_class,org.awaitility.core.AssertionCondition),(result,false),(args,[])}): java.lang.StringIndexOutOfBoundsException: begin 0, end -1, length 5
at java.base/java.lang.String.checkBoundsBeginEnd(String.java:4606)
at java.base/java.lang.String.substring(String.java:2709)
at org.graalvm.nativeimage.configure/com.oracle.svm.configure.trace.ReflectionProcessor.addFullyQualifiedDeclaredMethod(ReflectionProcessor.java:293)
at org.graalvm.nativeimage.configure/com.oracle.svm.configure.trace.ReflectionProcessor.processEntry(ReflectionProcessor.java:247)
at org.graalvm.nativeimage.configure/com.oracle.svm.configure.trace.TraceProcessor.processEntry(TraceProcessor.java:87)
at org.graalvm.nativeimage.configure/com.oracle.svm.configure.trace.TraceProcessor.processTrace(TraceProcessor.java:63)
at org.graalvm.nativeimage.configure/com.oracle.svm.configure.trace.TraceProcessor.process(TraceProcessor.java:58)
at org.graalvm.nativeimage.configure/com.oracle.svm.configure.command.ConfigurationGenerateCommand.generate(ConfigurationGenerateCommand.java:293)
at org.graalvm.nativeimage.configure/com.oracle.svm.configure.command.ConfigurationGenerateCommand.apply(ConfigurationGenerateCommand.java:60)
at org.graalvm.nativeimage.configure/com.oracle.svm.configure.ConfigurationTool.main(ConfigurationTool.java:84)
Just want to make sure this is normal/expected
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It was reported to oracle/graal#6980
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
They seem to be harmless although they look scary. 😅
@@ -75,7 +79,7 @@ allprojects { | |||
// `disallow` in Java 18. | |||
// - https://openjdk.org/jeps/411 | |||
// - https://bugs.openjdk.org/browse/JDK-8270380 | |||
if (project.ext.testJavaVersion >= 17) { | |||
if (project.ext.testJavaVersion >= 17 || it.name == 'nativeImageTrace') { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Optional) What do you think of setting testJavaVersion
of nativeImageTrace
to 17?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
testJavaVersion
is specified on per-project basis rather than on per-task basis, so I guess that's not possible? (nativeImageTrace
is a task that is created for each project.) Please correct me if I'm wrong.
`GenerateNativeImageTrace` with [`native-image-agent`](https://www.graalvm.org/latest/reference-manual/native-image/metadata/AutomaticMetadataCollection/). | ||
|
||
``` | ||
$ ../gradlew nativeImageConfig |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It was reported to oracle/graal#6980
Side note: I failed to build our SAML example as a native image due to the following exception:
After digging into the issue, it turned out that the scheme of armeria/examples/saml-service-provider/src/main/java/example/armeria/server/saml/sp/Main.java Lines 96 to 97 in 5ed3cac
I was able to run the SAML example after fixing the code to use InputStream .
.tls(Main.class.getClassLoader().getResourceAsStream("localhost.crt"),
Main.class.getClassLoader().getResourceAsStream("localhost.key")) |
Co-authored-by: jrhee17 <guins_j@guins.org>
@ikhoon wrote:
Do you think we should update the example, then? 🤔 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Look great and left a small suggestion. 👍
newCommandLine += "generate" | ||
nativeImageTraceFiles.forEach { | ||
if (Files.exists(it)) { | ||
newCommandLine += "--trace-input=$it" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Shouldn't we also add the files to inputs?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Task input must be specified at configuration time, but we only know whether the trace file exists at execution time, so we cannot add every one of them at configuration time. (Gradle will error when we add a missing file as an input unfortunately.) Instead, I added the directory that contains the trace files as an input, so all trace files in the directory are hashed.
native-image-config/build.gradle.kts
Outdated
} | ||
} | ||
|
||
abstract class CleanupNativeImageConfigTask : DefaultTask() { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
perhaps FilterAndCopyNativeImageConfigTask
?
For me, the word clean
in a Gradle task means removing the generated files. 🤔
Not today. 😆 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks, @trustin! 🚀🚀
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks, @trustin! 🚀🚀
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks, @trustin! 🚀 👍 💯
Let me merge this after the build passes AND I confirm the native image configuration actually works manually. |
Motivation:
Armeria and its dependencies (e.g. Netty, JCTools and Caffeine) use
fair amount of reflections, JNI and other advanced features of JVM,
which require explicit configuration when building a native image with
GraalVM. We should provide native image configuration in our artifacts
so that a user can easily build a native image out of the box.
Modifications:
native
. For a project withnative
flag,we add a task
nativeImageTrace
that runs select test cases annotatedwith a
GenerateNativeImageTrace
to collect the trace files generatedby
native-image-agent
.:native-image-config
, which:META-INF/native-image/com.linecorp.armeria/armeria
.in the native image config
Result:
different platforms automatically (macOS, Linux epoll, Linux io_uring
and Windows).
annotations.