diff --git a/fst-graalvm-demo/README.md b/fst-graalvm-demo/README.md new file mode 100644 index 0000000..87f4c30 --- /dev/null +++ b/fst-graalvm-demo/README.md @@ -0,0 +1,94 @@ +# fst-graalvm-demo +Demo using Fast Serialization And GraalVM...\ +This is in conjunction with [github.com/vlingo](https://github.com/vlingo) and [vlingo.io](https://vlingo.io).\ +We encountered this issue when trying to run the native image of xoom-designer/xoom-schemata that use xoom-lattice which uses fast serialization in inter-node messaging in our cluster backed grid compute and data. + +## Maven Build +```bash +mvn install +``` + +## Generate native image resources Configs +```bash +java -agentlib:native-image-agent=config-output-dir=src/main/resources/META-INF/native-image -jar target/fst-graalvm-0.0.1-SNAPSHOT-jar-with-dependencies.jar +``` +## Adding Missing Serialization +```bash + { + "name": "java.lang.Object[]", + "customTargetConstructorClass": "java.lang.Object" + }, + { + "name": "java.lang.Object[][]", + "customTargetConstructorClass": "java.lang.Object" + }, + { + "name": "java.lang.Object[][][]", + "customTargetConstructorClass": "java.lang.Object" + }, + { + "name": "java.sql.Timestamp" + }, + { + "name": "java.lang.Object" + }, + { + "name": "java.lang.Boolean" + }, + { + "name": "java.lang.Character" + }, + { + "name": "java.lang.Double" + }, + { + "name": "java.lang.Float" + }, + { + "name": "java.lang.Long" + }, + { + "name": "java.lang.Integer" + }, + { + "name": "java.lang.Short" + }, + { + "name": "java.lang.Byte" + }, + { + "name": "java.lang.String" + }, +``` + +## Build the native image +```bash +mvn install -Pnative-image +``` + +## Run the native image +```bash +./target/fst-graalvm +``` +## Issue +```bash +./target/fst-graalvm +Exception in thread "main" com.oracle.svm.core.jdk.UnsupportedFeatureError: SerializationConstructorAccessor class not found for declaringClass: [Ljava.lang.Object; (targetConstructorClass: java.lang.Object). Usually adding [Ljava.lang.Object; to serialization-config.json fixes the problem. + at com.oracle.svm.core.util.VMError.unsupportedFeature(VMError.java:87) + at com.oracle.svm.reflect.serialize.SerializationSupport.getSerializationConstructorAccessor(SerializationSupport.java:132) + at jdk.internal.reflect.MethodAccessorGenerator.generateSerializationConstructor(MethodAccessorGenerator.java:48) + at jdk.internal.reflect.ReflectionFactory.generateConstructor(ReflectionFactory.java:514) + at jdk.internal.reflect.ReflectionFactory.newConstructorForSerialization(ReflectionFactory.java:427) + at sun.reflect.ReflectionFactory.newConstructorForSerialization(ReflectionFactory.java:103) + at org.nustaq.serialization.FSTDefaultClassInstantiator.findConstructorForSerializable(FSTDefaultClassInstantiator.java:110) + at org.nustaq.serialization.FSTClazzInfo.(FSTClazzInfo.java:137) + at org.nustaq.serialization.FSTClazzInfoRegistry.getCLInfo(FSTClazzInfoRegistry.java:129) + at org.nustaq.serialization.FSTClazzNameRegistry.addClassMapping(FSTClazzNameRegistry.java:98) + at org.nustaq.serialization.FSTClazzNameRegistry.registerClassNoLookup(FSTClazzNameRegistry.java:85) + at org.nustaq.serialization.FSTClazzNameRegistry.registerClass(FSTClazzNameRegistry.java:81) + at org.nustaq.serialization.FSTConfiguration.addDefaultClazzes(FSTConfiguration.java:845) + at org.nustaq.serialization.FSTConfiguration.initDefaultFstConfigurationInternal(FSTConfiguration.java:478) + at org.nustaq.serialization.FSTConfiguration.createDefaultConfiguration(FSTConfiguration.java:473) + at org.nustaq.serialization.FSTConfiguration.createDefaultConfiguration(FSTConfiguration.java:465) + at io.vlingo.xoom.experimental.fst.BootstrapApp.main(BootstrapApp.java:7) +``` diff --git a/fst-graalvm-demo/pom.xml b/fst-graalvm-demo/pom.xml new file mode 100644 index 0000000..d642be7 --- /dev/null +++ b/fst-graalvm-demo/pom.xml @@ -0,0 +1,96 @@ + + 4.0.0 + io.vlingo.xoom.experimental + fst-graalvm + 0.0.1-SNAPSHOT + fst-graalvm + + + UTF-8 + 1.8 + 1.8 + io.vlingo.xoom.experimental.fst.BootstrapApp + 21.1.0 + + + + + maven-assembly-plugin + + + + ${exec.mainClass} + + + + jar-with-dependencies + + + + + make-assembly + package + + single + + + + + + + + + + junit + junit + 4.13.1 + test + + + de.ruedigermoeller + fst + 2.57 + + + org.graalvm.sdk + graal-sdk + ${graalvm.version} + provided + + + + + + native-image + + + + org.graalvm.nativeimage + native-image-maven-plugin + ${graalvm.version} + + + + native-image + + package + + + + ${project.name} + ${exec.mainClass} + + --no-fallback --no-server --enable-url-protocols=http -H:+AllowIncompleteClasspath + -H:ReflectionConfigurationFiles=classes/META-INF/native-image/reflect-config.json + -H:ResourceConfigurationFiles=classes/META-INF/native-image/resource-config.json + -H:SerializationConfigurationFiles=classes/META-INF/native-image/serialization-config.json + --initialize-at-run-time=io.netty + --allow-incomplete-classpath + + + + + + + + diff --git a/fst-graalvm-demo/src/main/java/io/vlingo/xoom/experimental/fst/BootstrapApp.java b/fst-graalvm-demo/src/main/java/io/vlingo/xoom/experimental/fst/BootstrapApp.java new file mode 100644 index 0000000..b8b3785 --- /dev/null +++ b/fst-graalvm-demo/src/main/java/io/vlingo/xoom/experimental/fst/BootstrapApp.java @@ -0,0 +1,11 @@ +package io.vlingo.xoom.experimental.fst; + +import org.nustaq.serialization.FSTConfiguration; + +public class BootstrapApp { + public static void main(String... args) { + final FSTConfiguration conf = FSTConfiguration.createDefaultConfiguration(); + + System.out.println("Hello Demo..."); + } +} diff --git a/fst-graalvm-demo/src/main/resources/META-INF/native-image/jni-config.json b/fst-graalvm-demo/src/main/resources/META-INF/native-image/jni-config.json new file mode 100644 index 0000000..0d4f101 --- /dev/null +++ b/fst-graalvm-demo/src/main/resources/META-INF/native-image/jni-config.json @@ -0,0 +1,2 @@ +[ +] diff --git a/fst-graalvm-demo/src/main/resources/META-INF/native-image/proxy-config.json b/fst-graalvm-demo/src/main/resources/META-INF/native-image/proxy-config.json new file mode 100644 index 0000000..0d4f101 --- /dev/null +++ b/fst-graalvm-demo/src/main/resources/META-INF/native-image/proxy-config.json @@ -0,0 +1,2 @@ +[ +] diff --git a/fst-graalvm-demo/src/main/resources/META-INF/native-image/reflect-config.json b/fst-graalvm-demo/src/main/resources/META-INF/native-image/reflect-config.json new file mode 100644 index 0000000..88a353b --- /dev/null +++ b/fst-graalvm-demo/src/main/resources/META-INF/native-image/reflect-config.json @@ -0,0 +1,431 @@ +[ +{ + "name":"byte[]", + "allDeclaredFields":true +}, +{ + "name":"byte[][]", + "allDeclaredFields":true +}, +{ + "name":"char[]", + "allDeclaredFields":true +}, +{ + "name":"char[][]", + "allDeclaredFields":true +}, +{ + "name":"double[]", + "allDeclaredFields":true +}, +{ + "name":"double[][]", + "allDeclaredFields":true +}, +{ + "name":"float[]", + "allDeclaredFields":true +}, +{ + "name":"float[][]", + "allDeclaredFields":true +}, +{ + "name":"int[]", + "allDeclaredFields":true +}, +{ + "name":"int[][]", + "allDeclaredFields":true +}, +{ + "name":"java.lang.AbstractStringBuilder", + "allDeclaredFields":true, + "fields":[ + {"name":"coder", "allowUnsafeAccess":true}, + {"name":"count", "allowUnsafeAccess":true}, + {"name":"value", "allowUnsafeAccess":true} + ], + "methods":[{"name":"","parameterTypes":[] }] +}, +{ + "name":"java.lang.Boolean", + "allDeclaredFields":true, + "fields":[{"name":"value", "allowUnsafeAccess":true}] +}, +{ + "name":"java.lang.Byte", + "allDeclaredFields":true, + "fields":[{"name":"value", "allowUnsafeAccess":true}] +}, +{ + "name":"java.lang.Character", + "allDeclaredFields":true, + "fields":[{"name":"value", "allowUnsafeAccess":true}] +}, +{ + "name":"java.lang.Double", + "allDeclaredFields":true, + "fields":[{"name":"value", "allowUnsafeAccess":true}] +}, +{ + "name":"java.lang.Float", + "allDeclaredFields":true, + "fields":[{"name":"value", "allowUnsafeAccess":true}] +}, +{ + "name":"java.lang.Integer", + "allDeclaredFields":true, + "fields":[{"name":"value", "allowUnsafeAccess":true}] +}, +{ + "name":"java.lang.Long", + "allDeclaredFields":true, + "fields":[{"name":"value", "allowUnsafeAccess":true}] +}, +{ + "name":"java.lang.Number", + "allDeclaredFields":true +}, +{ + "name":"java.lang.Object", + "allDeclaredFields":true, + "methods":[{"name":"","parameterTypes":[] }] +}, +{ + "name":"java.lang.Object[]", + "allDeclaredFields":true +}, +{ + "name":"java.lang.Object[][]", + "allDeclaredFields":true +}, +{ + "name":"java.lang.Object[][][]", + "allDeclaredFields":true +}, +{ + "name":"java.lang.Short", + "allDeclaredFields":true, + "fields":[{"name":"value", "allowUnsafeAccess":true}] +}, +{ + "name":"java.lang.String", + "allDeclaredFields":true, + "fields":[ + {"name":"coder", "allowUnsafeAccess":true}, + {"name":"hash", "allowUnsafeAccess":true}, + {"name":"value", "allowUnsafeAccess":true} + ] +}, +{ + "name":"java.lang.StringBuffer", + "allDeclaredFields":true, + "methods":[ + {"name":"readObject","parameterTypes":["java.io.ObjectInputStream"] }, + {"name":"writeObject","parameterTypes":["java.io.ObjectOutputStream"] } + ] +}, +{ + "name":"java.lang.StringBuilder", + "allDeclaredFields":true, + "methods":[ + {"name":"readObject","parameterTypes":["java.io.ObjectInputStream"] }, + {"name":"writeObject","parameterTypes":["java.io.ObjectOutputStream"] } + ] +}, +{ + "name":"java.math.BigDecimal", + "allDeclaredFields":true, + "fields":[ + {"name":"intVal", "allowUnsafeAccess":true}, + {"name":"scale", "allowUnsafeAccess":true} + ], + "methods":[ + {"name":"readObject","parameterTypes":["java.io.ObjectInputStream"] }, + {"name":"writeObject","parameterTypes":["java.io.ObjectOutputStream"] } + ] +}, +{ + "name":"java.math.BigInteger", + "allDeclaredFields":true, + "fields":[ + {"name":"bitCountPlusOne", "allowUnsafeAccess":true}, + {"name":"bitLengthPlusOne", "allowUnsafeAccess":true}, + {"name":"firstNonzeroIntNumPlusTwo", "allowUnsafeAccess":true}, + {"name":"lowestSetBitPlusTwo", "allowUnsafeAccess":true}, + {"name":"mag", "allowUnsafeAccess":true}, + {"name":"signum", "allowUnsafeAccess":true} + ], + "methods":[ + {"name":"readObject","parameterTypes":["java.io.ObjectInputStream"] }, + {"name":"writeObject","parameterTypes":["java.io.ObjectOutputStream"] } + ] +}, +{ + "name":"java.net.URL", + "allDeclaredFields":true, + "fields":[ + {"name":"authority", "allowUnsafeAccess":true}, + {"name":"file", "allowUnsafeAccess":true}, + {"name":"hashCode", "allowUnsafeAccess":true}, + {"name":"host", "allowUnsafeAccess":true}, + {"name":"port", "allowUnsafeAccess":true}, + {"name":"protocol", "allowUnsafeAccess":true}, + {"name":"ref", "allowUnsafeAccess":true} + ], + "methods":[ + {"name":"readObject","parameterTypes":["java.io.ObjectInputStream"] }, + {"name":"readResolve","parameterTypes":[] }, + {"name":"writeObject","parameterTypes":["java.io.ObjectOutputStream"] } + ] +}, +{ + "name":"java.sql.Date", + "allDeclaredFields":true +}, +{ + "name":"java.sql.Timestamp", + "allDeclaredFields":true, + "fields":[{"name":"nanos", "allowUnsafeAccess":true}] +}, +{ + "name":"java.text.DateFormat", + "allDeclaredFields":true, + "fields":[ + {"name":"calendar", "allowUnsafeAccess":true}, + {"name":"numberFormat", "allowUnsafeAccess":true} + ] +}, +{ + "name":"java.text.Format", + "allDeclaredFields":true +}, +{ + "name":"java.text.SimpleDateFormat", + "allDeclaredFields":true, + "fields":[ + {"name":"defaultCenturyStart", "allowUnsafeAccess":true}, + {"name":"formatData", "allowUnsafeAccess":true}, + {"name":"locale", "allowUnsafeAccess":true}, + {"name":"pattern", "allowUnsafeAccess":true}, + {"name":"serialVersionOnStream", "allowUnsafeAccess":true} + ], + "methods":[{"name":"readObject","parameterTypes":["java.io.ObjectInputStream"] }] +}, +{ + "name":"java.util.AbstractCollection", + "allDeclaredFields":true +}, +{ + "name":"java.util.AbstractList", + "allDeclaredFields":true, + "methods":[{"name":"","parameterTypes":[] }] +}, +{ + "name":"java.util.AbstractMap", + "allDeclaredFields":true, + "methods":[{"name":"","parameterTypes":[] }] +}, +{ + "name":"java.util.AbstractSequentialList", + "allDeclaredFields":true, + "methods":[{"name":"","parameterTypes":[] }] +}, +{ + "name":"java.util.AbstractSet", + "allDeclaredFields":true, + "methods":[{"name":"","parameterTypes":[] }] +}, +{ + "name":"java.util.ArrayList", + "allDeclaredFields":true, + "fields":[{"name":"size", "allowUnsafeAccess":true}], + "methods":[ + {"name":"readObject","parameterTypes":["java.io.ObjectInputStream"] }, + {"name":"writeObject","parameterTypes":["java.io.ObjectOutputStream"] } + ] +}, +{ + "name":"java.util.BitSet", + "allDeclaredFields":true, + "fields":[{"name":"words", "allowUnsafeAccess":true}], + "methods":[ + {"name":"readObject","parameterTypes":["java.io.ObjectInputStream"] }, + {"name":"writeObject","parameterTypes":["java.io.ObjectOutputStream"] } + ] +}, +{ + "name":"java.util.Calendar", + "allDeclaredFields":true, + "fields":[ + {"name":"areFieldsSet", "allowUnsafeAccess":true}, + {"name":"fields", "allowUnsafeAccess":true}, + {"name":"firstDayOfWeek", "allowUnsafeAccess":true}, + {"name":"isSet", "allowUnsafeAccess":true}, + {"name":"isTimeSet", "allowUnsafeAccess":true}, + {"name":"lenient", "allowUnsafeAccess":true}, + {"name":"minimalDaysInFirstWeek", "allowUnsafeAccess":true}, + {"name":"nextStamp", "allowUnsafeAccess":true}, + {"name":"serialVersionOnStream", "allowUnsafeAccess":true}, + {"name":"time", "allowUnsafeAccess":true}, + {"name":"zone", "allowUnsafeAccess":true} + ], + "methods":[ + {"name":"readObject","parameterTypes":["java.io.ObjectInputStream"] }, + {"name":"writeObject","parameterTypes":["java.io.ObjectOutputStream"] } + ] +}, +{ + "name":"java.util.Date", + "allDeclaredFields":true, + "methods":[ + {"name":"readObject","parameterTypes":["java.io.ObjectInputStream"] }, + {"name":"writeObject","parameterTypes":["java.io.ObjectOutputStream"] } + ] +}, +{ + "name":"java.util.Dictionary", + "allDeclaredFields":true, + "methods":[{"name":"","parameterTypes":[] }] +}, +{ + "name":"java.util.GregorianCalendar", + "allDeclaredFields":true, + "fields":[{"name":"gregorianCutover", "allowUnsafeAccess":true}], + "methods":[{"name":"readObject","parameterTypes":["java.io.ObjectInputStream"] }] +}, +{ + "name":"java.util.HashMap", + "allDeclaredFields":true, + "fields":[ + {"name":"loadFactor", "allowUnsafeAccess":true}, + {"name":"threshold", "allowUnsafeAccess":true} + ], + "methods":[ + {"name":"readObject","parameterTypes":["java.io.ObjectInputStream"] }, + {"name":"writeObject","parameterTypes":["java.io.ObjectOutputStream"] } + ] +}, +{ + "name":"java.util.Hashtable", + "allDeclaredFields":true, + "fields":[ + {"name":"loadFactor", "allowUnsafeAccess":true}, + {"name":"threshold", "allowUnsafeAccess":true} + ], + "methods":[ + {"name":"readObject","parameterTypes":["java.io.ObjectInputStream"] }, + {"name":"writeObject","parameterTypes":["java.io.ObjectOutputStream"] } + ] +}, +{ + "name":"java.util.LinkedList", + "allDeclaredFields":true, + "methods":[ + {"name":"readObject","parameterTypes":["java.io.ObjectInputStream"] }, + {"name":"writeObject","parameterTypes":["java.io.ObjectOutputStream"] } + ] +}, +{ + "name":"java.util.Locale", + "allDeclaredFields":true, + "methods":[ + {"name":"readObject","parameterTypes":["java.io.ObjectInputStream"] }, + {"name":"readResolve","parameterTypes":[] }, + {"name":"writeObject","parameterTypes":["java.io.ObjectOutputStream"] } + ] +}, +{ + "name":"java.util.SimpleTimeZone", + "allDeclaredFields":true, + "fields":[ + {"name":"dstSavings", "allowUnsafeAccess":true}, + {"name":"endDay", "allowUnsafeAccess":true}, + {"name":"endDayOfWeek", "allowUnsafeAccess":true}, + {"name":"endMode", "allowUnsafeAccess":true}, + {"name":"endMonth", "allowUnsafeAccess":true}, + {"name":"endTime", "allowUnsafeAccess":true}, + {"name":"endTimeMode", "allowUnsafeAccess":true}, + {"name":"monthLength", "allowUnsafeAccess":true}, + {"name":"rawOffset", "allowUnsafeAccess":true}, + {"name":"serialVersionOnStream", "allowUnsafeAccess":true}, + {"name":"startDay", "allowUnsafeAccess":true}, + {"name":"startDayOfWeek", "allowUnsafeAccess":true}, + {"name":"startMode", "allowUnsafeAccess":true}, + {"name":"startMonth", "allowUnsafeAccess":true}, + {"name":"startTime", "allowUnsafeAccess":true}, + {"name":"startTimeMode", "allowUnsafeAccess":true}, + {"name":"startYear", "allowUnsafeAccess":true}, + {"name":"useDaylight", "allowUnsafeAccess":true} + ], + "methods":[ + {"name":"readObject","parameterTypes":["java.io.ObjectInputStream"] }, + {"name":"writeObject","parameterTypes":["java.io.ObjectOutputStream"] } + ] +}, +{ + "name":"java.util.TimeZone", + "allDeclaredFields":true, + "fields":[{"name":"ID", "allowUnsafeAccess":true}] +}, +{ + "name":"java.util.TreeMap", + "allDeclaredFields":true, + "fields":[{"name":"comparator", "allowUnsafeAccess":true}], + "methods":[ + {"name":"readObject","parameterTypes":["java.io.ObjectInputStream"] }, + {"name":"writeObject","parameterTypes":["java.io.ObjectOutputStream"] } + ] +}, +{ + "name":"java.util.TreeSet", + "allDeclaredFields":true, + "methods":[ + {"name":"readObject","parameterTypes":["java.io.ObjectInputStream"] }, + {"name":"writeObject","parameterTypes":["java.io.ObjectOutputStream"] } + ] +}, +{ + "name":"java.util.Vector", + "allDeclaredFields":true, + "fields":[ + {"name":"capacityIncrement", "allowUnsafeAccess":true}, + {"name":"elementCount", "allowUnsafeAccess":true}, + {"name":"elementData", "allowUnsafeAccess":true} + ], + "methods":[ + {"name":"readObject","parameterTypes":["java.io.ObjectInputStream"] }, + {"name":"writeObject","parameterTypes":["java.io.ObjectOutputStream"] } + ] +}, +{ + "name":"java.util.concurrent.ConcurrentHashMap", + "allDeclaredFields":true, + "methods":[ + {"name":"readObject","parameterTypes":["java.io.ObjectInputStream"] }, + {"name":"writeObject","parameterTypes":["java.io.ObjectOutputStream"] } + ] +}, +{ + "name":"long[]", + "allDeclaredFields":true +}, +{ + "name":"long[][]", + "allDeclaredFields":true +}, +{ + "name":"short[]", + "allDeclaredFields":true +}, +{ + "name":"short[][]", + "allDeclaredFields":true +}, +{ + "name":"sun.misc.Unsafe", + "fields":[{"name":"theUnsafe"}] +} +] diff --git a/fst-graalvm-demo/src/main/resources/META-INF/native-image/resource-config.json b/fst-graalvm-demo/src/main/resources/META-INF/native-image/resource-config.json new file mode 100644 index 0000000..791ea0f --- /dev/null +++ b/fst-graalvm-demo/src/main/resources/META-INF/native-image/resource-config.json @@ -0,0 +1,5 @@ +{ + "resources":{ + "includes":[]}, + "bundles":[] +} diff --git a/fst-graalvm-demo/src/main/resources/META-INF/native-image/serialization-config.json b/fst-graalvm-demo/src/main/resources/META-INF/native-image/serialization-config.json new file mode 100644 index 0000000..136d1a3 --- /dev/null +++ b/fst-graalvm-demo/src/main/resources/META-INF/native-image/serialization-config.json @@ -0,0 +1,125 @@ +[ + { + "name": "java.lang.Object[]", + "customTargetConstructorClass": "java.lang.Object" + }, + { + "name": "java.lang.Object[][]", + "customTargetConstructorClass": "java.lang.Object" + }, + { + "name": "java.lang.Object[][][]", + "customTargetConstructorClass": "java.lang.Object" + }, + { + "name": "java.sql.Timestamp" + }, + { + "name": "java.lang.Object" + }, + { + "name": "java.lang.Boolean" + }, + { + "name": "java.lang.Character" + }, + { + "name": "java.lang.Double" + }, + { + "name": "java.lang.Float" + }, + { + "name": "java.lang.Long" + }, + { + "name": "java.lang.Integer" + }, + { + "name": "java.lang.Short" + }, + { + "name": "java.lang.Byte" + }, + { + "name": "java.lang.String" + }, + { + "name":"java.text.Format" + }, + { + "name":"java.util.Date" + }, + { + "name":"java.net.URL" + }, + { + "name":"java.text.SimpleDateFormat" + }, + { + "name":"java.util.HashMap" + }, + { + "name":"java.util.TreeSet" + }, + { + "name":"java.util.ArrayList" + }, + { + "name":"java.math.BigDecimal" + }, + { + "name":"java.util.Calendar" + }, + { + "name":"java.util.Vector" + }, + { + "name":"java.util.Locale" + }, + { + "name":"java.lang.StringBuffer" + }, + { + "name":"java.math.BigInteger" + }, + { + "name":"java.util.LinkedList" + }, + { + "name":"java.lang.Number" + }, + { + "name":"java.text.DateFormat" + }, + { + "name":"java.util.Hashtable" + }, + { + "name":"java.util.GregorianCalendar" + }, + { + "name":"java.util.TimeZone" + }, + { + "name":"java.sql.Timestamp" + }, + { + "name":"java.util.concurrent.ConcurrentHashMap" + }, + { + "name":"java.sql.Date" + }, + { + "name":"java.util.TreeMap" + }, + { + "name":"java.lang.StringBuilder" + }, + { + "name":"java.util.BitSet" + }, + { + "name":"java.util.SimpleTimeZone" + } +]