Supporting org.apache.xml.security in graalVM
When working today at out european trusted lists feature $DAY_JOB we had an issue which was coming from org.apache.xml.security when trying to run our testsuite natively compiled with graalVM.
java.util.MissingResourceException: Can't find bundle for base name org/apache/xml/security/resource/xmlsecurity locale en_USThis indicates that the required resource bundles are not available in the generated binary.
So what is happening here? When GraalVM is compiling it does something called dead code elementation. Not getting to technical, but this means it will remove Types which it deems unused. In code bases not relying on reflection most of the times it's smart enough to get it right. But if you have a big complicated project which uses a bunch of relfection sometimes GraalVM thinks a certain Type is not used while it fact it actually is. Leading to issues at runtime as you can see.
To fix this we need to add the following to our build arguments when building the native test executable.
-H:IncludeResourceBundles=org.apache.xml.security.resource.xmlsecurityWhen we add this and try compiling + running the tests once again, we now encounter the following issue:
org.apache.xml.security.signature.XMLSignatureException: The requested algorithm http://www.w3.org/2000/09/xmldsig#dsa-sha1 does not exist. Original Message was: org.apache.xml.security.algorithms.implementations.SignatureDSA Original Exception was java.lang.InstantiationException: org.apache.xml.security.algorithms.implementations.SignatureDSASo now the resource bundles are loaded, but it can't find any of the hashing algoritms we need, probably also being trimmed out of the native binary because they get instaniated with the usage of reflection. So GraalVM has an option to define we require in a configuration called reflect-config.json you can pass it as following: -H:ReflectionConfigurationFiles=${basedir}/path/to/reflect-config.json And in that file we need to add the required type we need to make sure GraalVM add's to the native binary
Something like this:
[ { "name": "org.apache.xml.security.algorithms.implementations.SignatureECDSA$SignatureECDSASHA1", "allDeclaredConstructors": true } ]When we run again we get a different error related to ECDSASHA256 so that means we have to add that type as well.
You guys and girls reading this are pretty smart so will already have guessed that we need to add all those hashing implementations to the configuration file. Next to this we also need to add some other config Types that I found by trial and error.
See full config below to copy paste into your application
Making this configuration available for everyone
GraalVM has an option to provide these config files in the
GraalVM Reachability Metadata
Repository.
This way not all users of the library have to provide it themselves but can be loaded automatically.
So the next blog post is gonna be about how we officially get test support level 1 on
GraalVM supported frameworks
Questions, remarks, comments? Send mail a mail or whatsapp!
Guust