graalvm support for blackbird
ashraf-revo opened this issue ยท 17 comments
iam getting this errors when using blackbird
java.lang.InternalError: com.oracle.svm.core.jdk.UnsupportedFeatureError: Defining hidden classes at runtime is not supported. at java.base@17.0.5/java.lang.invoke.InnerClassLambdaMetafactory.generateInnerClass(InnerClassLambdaMetafactory.java:413) ~[na:na] at java.base@17.0.5/java.lang.invoke.InnerClassLambdaMetafactory.spinInnerClass(InnerClassLambdaMetafactory.java:315) ~[na:na] at java.base@17.0.5/java.lang.invoke.InnerClassLambdaMetafactory.buildCallSite(InnerClassLambdaMetafactory.java:228) ~[na:na] at java.base@17.0.5/java.lang.invoke.LambdaMetafactory.metafactory(LambdaMetafactory.java:341) ~[na:na] at com.fasterxml.jackson.module.blackbird.ser.BBSerializerModifier.createProperty(BBSerializerModifier.java:155) ~[na:na] at com.fasterxml.jackson.module.blackbird.ser.BBSerializerModifier.lambda$findProperties$0(BBSerializerModifier.java:67) ~[na:na] at com.fasterxml.jackson.module.blackbird.util.Unchecked.lambda$runnable$0(Unchecked.java:31) ~[na:na] at com.fasterxml.jackson.module.blackbird.ser.BBSerializerModifier.findProperties(BBSerializerModifier.java:68) ~[na:na] at com.fasterxml.jackson.module.blackbird.ser.BBSerializerModifier.changeProperties(BBSerializerModifier.java:52) ~[na:na] at com.fasterxml.jackson.databind.ser.BeanSerializerFactory.constructBeanOrAddOnSerializer(BeanSerializerFactory.java:415) ~[na:na] at com.fasterxml.jackson.databind.ser.BeanSerializerFactory.findBeanOrAddOnSerializer(BeanSerializerFactory.java:295) ~[na:na] at com.fasterxml.jackson.databind.ser.BeanSerializerFactory._createSerializer2(BeanSerializerFactory.java:240) ~[na:na] at com.fasterxml.jackson.databind.ser.BeanSerializerFactory.createSerializer(BeanSerializerFactory.java:174) ~[na:na] at com.fasterxml.jackson.databind.SerializerProvider._createUntypedSerializer(SerializerProvider.java:1501) ~[uxplore:2.14.1] at com.fasterxml.jackson.databind.SerializerProvider._createAndCacheUntypedSerializer(SerializerProvider.java:1449) ~[uxplore:2.14.1] at com.fasterxml.jackson.databind.SerializerProvider._findExplicitUntypedSerializer(SerializerProvider.java:1418) ~[uxplore:2.14.1] at com.fasterxml.jackson.databind.ser.DefaultSerializerProvider.hasSerializerFor(DefaultSerializerProvider.java:260) ~[uxplore:2.14.1] at com.fasterxml.jackson.databind.ObjectMapper.canSerialize(ObjectMapper.java:3468) ~[uxplore:2.14.1]
I wouldn't think either Afterburner or Blackbird could work with native images -- they both require use of dynamically generated byte code (serializer, deserializer classes) during runtime. Which I didn't think statically compiled images would allow doing.
I am currently facing the same problem. Graal offers a tracing agent which can be used to generate metadata about class generation und serialization. It seems to support anonymous classes but not hidden classes.
It is possible to use blackbird with anonymous classes instead of hidden ones (a performance penalty would not be an issue)
Hi, could you please expand a bit on why you would like to use Blackbird or Afterburner in a native-image environment?
I think your best bet is to get vanilla Jackson working. Since you say a performance penalty is ok, there would be no incentive to use code generation here, and it will add a lot of complexity to building your native-image.
At work i have to migrate a Spring Boot Project to Spring Native. Said Project uses blackbird.
Now we are using vanilla Jackson and it seems to work.
I am not terribly familiar with native-image, but if there is a way to make Blackbird and Afterburner automatically disable themselves in native-image, maybe that would be helpful.
@stevenschlansker I think that's a great idea. There have been contributors helping handle other GraalVM-related Jackson issues but now I'm drawing blank on how they were. But it should be possible to get some help here; let me ask on mailing list.
@cowtowncoder There is already native image detection in jackson-databind here: https://github.com/FasterXML/jackson-databind/blob/2.16/src/main/java/com/fasterxml/jackson/databind/util/NativeImageUtil.java
It should be as simple as exposing the RUNNING_IN_SVM flag. If it is set, we're running in native-image, either at build time or runtime, and afterburner/blackbird should be disabled.
@yawkat Thanks! I should have remember this; I remembered there was something somewhere but... :-)
Modules should be able to access it, although we have sort of two choices:
- Call existing public
needsReflectionConfiguration()
on per-class basis to disable functionality for most if not all things (some users might like this) - Make existing private
isRunningInNativeImage()
public
; and module can then just shut off in general.
For (2) module could allow override (always register regardless of Graal-ness) too I suppose.
At any rate, I think I'll do (2) now.
So, for that method: FasterXML/jackson-databind#4060
Is it sufficient to only disable BB and AB in "runtime"
SVM mode? RUNNING_IN_SVM
seems to be true
for any mode, but isRunningInNativeImage
only checks for "runtime"
mode. I am not sure whether this makes a big difference here.
isRunningInNativeImage (runtime only) will probably work for most purposes, but RUNNING_IN_SVM (runtime + build time) would be the safer choice.
I opened a PR #216 with this change. @ashraf-revo @yawkat @MaxiLambda , if you could check that this solves your problem, that would be great.
@cowtowncoder , I copied'n'pasted the code into BB and AB and left a comment to clean it up later. Do you think we should also make RUNNING_IN_SVM
public or add a getter to NativeImageUtil
?
I opened a PR #216 with this change. @ashraf-revo @yawkat @MaxiLambda , if you could check that this solves your problem, that would be great. @cowtowncoder , I copied'n'pasted the code into BB and AB and left a comment to clean it up later. Do you think we should also make
RUNNING_IN_SVM
public or add a getter toNativeImageUtil
?
Yeah I think adding a public getter would make sense.
Another link that might be useful (although I think we are good already): https://github.com/reactiverse/es4x/blob/develop/pm/src/main/java/io/reactiverse/es4x/cli/GraalVMVersion.java
@cowtowncoder querying the graal version wouldn't work, because graal also has a jit mode where blackbird/afterburner will work fine. only substratevm (i.e. native image) is the problem
FWIW, We run Blackbird in OpenJDK + Graal JVMCI JIT in production and have good results with it.
Thank you @yawkat -- I added link from a comment from mailing list, without thinking about it. But it makes sense that this wouldn't be useful for this purpose then.