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]

Reply via email to