GitHub user bobbai00 edited a discussion: Support Java 17 as runtime for Scala/Java based micro services
## Motivation Currently, Scala/Java based micro services run in Java 11. Compared to Java 11, Java 17 is better at both [language level](https://docs.oracle.com/en/java/javase/17/migrate/significant-changes-jdk-release.html?utm_source=chatgpt.com#GUID-327C39ED-C3FD-4637-906A-36C6697E85D5), [runtime & GC performance](https://openjdk.org/jeps/333?utm_source=chatgpt.com). Besides that, modern Java libraries usually require Java 17+, including some GenAI component like [mcp-java-sdk](https://github.com/modelcontextprotocol/java-sdk). If later we want to use these libraries, our existing Java/Scala code has to support Java 17. ## How hard it is to support Java 17 It turns out that it is **very easy** to support Java 17. During some testing, the only incompatibility I encountered is `org.ehcache.sizeOf` we used in `common/workflow-core/src/main/scala/org/apache/amber/core/tuple/Tuple.scala`: ```java case class Tuple @JsonCreator() ( @JsonProperty(value = "schema", required = true) schema: Schema, @JsonProperty(value = "fields", required = true) fieldVals: Array[Any] ) extends SeqTupleLike with Serializable { checkNotNull(schema) checkNotNull(fieldVals) checkSchemaMatchesFields(schema.getAttributes, fieldVals) override val inMemSize: Long = SizeOf.newInstance().deepSizeOf(this) ``` The incompatibility is because: Ehcache manages byte based cache limits by utilizing reflection, which is forbidden with Java 17. The error message is the following: ``` [2025-10-23 23:07:52,727] [WARN] [org.ehcache.sizeof.ObjectGraphWalker] [DP-thread] - The JVM is preventing Ehcache from accessing the subgraph beneath 'private final byte[] java.lang.String.value' - cache sizes may be underestimated as a result java.lang.reflect.InaccessibleObjectException: Unable to make field private final byte[] java.lang.String.value accessible: module java.base does not "opens java.lang" to unnamed module @5af5def9 at java.base/java.lang.reflect.AccessibleObject.checkCanSetAccessible(AccessibleObject.java:354) at java.base/java.lang.reflect.AccessibleObject.checkCanSetAccessible(AccessibleObject.java:297) at java.base/java.lang.reflect.Field.checkCanSetAccessible(Field.java:178) at java.base/java.lang.reflect.Field.setAccessible(Field.java:172) at org.ehcache.sizeof.ObjectGraphWalker.getAllFields(ObjectGraphWalker.java:245) at org.ehcache.sizeof.ObjectGraphWalker.getFilteredFields(ObjectGraphWalker.java:204) at org.ehcache.sizeof.ObjectGraphWalker.walk(ObjectGraphWalker.java:159) at org.ehcache.sizeof.SizeOf.deepSizeOf(SizeOf.java:74) at org.apache.amber.core.tuple.Tuple.<init>(Tuple.scala:55) at org.apache.amber.core.tuple.Tuple$Builder.build(Tuple.scala:236) at org.apache.amber.core.tuple.SeqTupleLike.enforceSchema(TupleLike.scala:64) at org.apache.amber.core.tuple.SeqTupleLike.enforceSchema$(TupleLike.scala:57) at org.apache.amber.core.tuple.TupleLike$$anon$6.enforceSchema(TupleLike.scala:141) at org.apache.amber.engine.architecture.worker.DataProcessor.outputOneTuple(DataProcessor.scala:184) at org.apache.amber.engine.architecture.worker.DataProcessor.continueDataProcessing(DataProcessor.scala:196) at org.apache.amber.engine.architecture.worker.DPThread.$anonfun$runDPThreadMainLogic$2(DPThread.scala:194) at org.apache.amber.engine.architecture.logreplay.ReplayLogManager.withFaultTolerant(ReplayLogManager.scala:77) at org.apache.amber.engine.architecture.logreplay.ReplayLogManager.withFaultTolerant$(ReplayLogManager.scala:71) at org.apache.amber.engine.architecture.logreplay.EmptyReplayLogManagerImpl.withFaultTolerant(ReplayLogManager.scala:87) at org.apache.amber.engine.architecture.worker.DPThread.org$apache$amber$engine$architecture$worker$DPThread$$runDPThreadMainLogic(DPThread.scala:192) at org.apache.amber.engine.architecture.worker.DPThread$$anon$1.run(DPThread.scala:95) at java.base/java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:539) at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:264) at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1136) at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:635) at java.base/java.lang.Thread.run(Thread.java:840) ``` To solve it, one simple solution is to set the `JAVA_OPTS` env variable as: ``` --add-opens=java.base/java.lang=ALL-UNNAMED --add-opens=java.base/java.io=ALL-UNNAMED --add-opens=java.base/java.util=ALL-UNNAMED --add-opens=java.base/java.util.concurrent=ALL-UNNAMED --add-opens=java.rmi/sun.rmi.transport=ALL-UNNAMED ``` ## Summary - We should support Java 17 as Java/Scala based micro services' runtime - It is very easy to make these services compatible with Java 17. Only minor change is needed GitHub link: https://github.com/apache/texera/discussions/4001 ---- This is an automatically sent email for [email protected]. To unsubscribe, please send an email to: [email protected]
