Skip to content

Commit 5dca988

Browse files
committed
38282554 - [38277648->25.09] GraalVM Add Coherence GraalVM native feature
(merge main -> ce/main 118394) [git-p4: depot-paths = "//dev/coherence-ce/main/": change = 118397]
1 parent 33b84a7 commit 5dca988

File tree

63 files changed

+1013
-146
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

63 files changed

+1013
-146
lines changed

prj/coherence-bedrock/coherence-bedrock/src/main/java/com/oracle/bedrock/runtime/coherence/CoherenceCluster.java

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -454,8 +454,16 @@ public boolean test(CoherenceCluster cluster)
454454
{
455455
for (CoherenceClusterMember member : cluster)
456456
{
457-
if (!member.invoke(new IsCoherenceRunning(f_setNames)))
457+
try
458458
{
459+
if (!member.invoke(new IsCoherenceRunning(f_setNames)))
460+
{
461+
return false;
462+
}
463+
}
464+
catch (Exception e)
465+
{
466+
e.printStackTrace();
459467
return false;
460468
}
461469
}

prj/coherence-bedrock/coherence-bedrock/src/main/java/com/oracle/bedrock/runtime/coherence/profiles/NativeImageProfile.java

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
import com.oracle.bedrock.runtime.java.ClassPath;
2424

2525
import com.oracle.bedrock.runtime.java.JavaApplication;
26+
import com.oracle.bedrock.runtime.java.options.SystemProperty;
2627
import com.oracle.bedrock.runtime.options.Executable;
2728

2829
/**
@@ -54,8 +55,16 @@ public NativeImageProfile(String nativeImage)
5455
@Override
5556
public void onLaunching(Platform platform, MetaClass metaClass, OptionsByType options)
5657
{
57-
options.add(Executable.named(f_nativeImage));
58-
options.remove(ClassPath.class);
58+
if (metaClass instanceof JavaApplication.MetaClass || metaClass instanceof CoherenceClusterMember.MetaClass)
59+
{
60+
options.add(Executable.named(f_nativeImage));
61+
options.remove(ClassPath.class);
62+
String serialConfig = System.getProperty("helidon.serialFilter.pattern");
63+
if (serialConfig != null && !serialConfig.isBlank())
64+
{
65+
options.add(SystemProperty.of("helidon.serialFilter.pattern", serialConfig));
66+
}
67+
}
5968
}
6069

6170
@Override

prj/coherence-core-components/src/main/java/com/tangosol/coherence/graal/CoherenceNativeImageFeature.java

Lines changed: 88 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -48,8 +48,11 @@
4848
import com.tangosol.io.pof.PortableObject;
4949
import com.tangosol.io.pof.schema.annotation.PortableType;
5050

51+
import com.tangosol.license.LicensedObject;
5152
import com.tangosol.net.AbstractInvocable;
53+
import com.tangosol.net.ClusterPermission;
5254
import com.tangosol.net.Coherence;
55+
import com.tangosol.net.MemberEvent;
5356
import com.tangosol.net.MemberIdentityProvider;
5457
import com.tangosol.net.SessionConfiguration;
5558
import com.tangosol.net.SessionProvider;
@@ -69,17 +72,27 @@
6972
import com.tangosol.run.xml.XmlSerializable;
7073

7174
import com.tangosol.util.AbstractSparseArray;
75+
import com.tangosol.util.AnyEvent;
76+
import com.tangosol.util.CacheCollator;
7277
import com.tangosol.util.HealthCheck;
7378

79+
import com.tangosol.util.Listeners;
7480
import com.tangosol.util.LongArray;
81+
import com.tangosol.util.NullImplementation;
82+
import com.tangosol.util.SafeHashMap;
83+
import com.tangosol.util.SimpleLongArray;
84+
import com.tangosol.util.SimpleMapEntry;
7585
import com.tangosol.util.WrapperCollections;
7686
import com.tangosol.util.WrapperException;
7787
import com.tangosol.util.extractor.AbstractExtractor;
88+
import com.tangosol.util.filter.LikeFilter;
89+
import org.graalvm.nativeimage.hosted.RuntimeProxyCreation;
7890
import org.graalvm.nativeimage.hosted.RuntimeReflection;
7991
import org.graalvm.nativeimage.hosted.RuntimeResourceAccess;
8092
import org.graalvm.nativeimage.hosted.RuntimeSerialization;
8193

8294
import javax.management.Descriptor;
95+
import javax.management.MBeanException;
8396
import javax.management.MBeanFeatureInfo;
8497
import javax.management.MBeanInfo;
8598
import javax.management.openmbean.OpenMBeanConstructorInfoSupport;
@@ -92,12 +105,25 @@
92105
import java.math.BigInteger;
93106
import java.nio.file.Path;
94107

108+
import java.security.Permission;
109+
import java.security.Principal;
110+
import java.security.SignedObject;
111+
import java.security.cert.CertPath;
112+
import java.security.cert.Certificate;
113+
import java.security.cert.X509Certificate;
114+
import java.util.ArrayList;
115+
import java.util.Collection;
95116
import java.util.Collections;
117+
import java.util.HashMap;
118+
import java.util.HashSet;
119+
import java.util.LinkedList;
96120
import java.util.List;
121+
import java.util.Map;
97122
import java.util.Set;
98123
import java.util.TreeMap;
99124
import java.util.TreeSet;
100125
import java.util.concurrent.ConcurrentHashMap;
126+
import java.util.concurrent.RejectedExecutionException;
101127
import java.util.function.BiConsumer;
102128

103129
/**
@@ -139,20 +165,40 @@ public void beforeAnalysis(BeforeAnalysisAccess access)
139165
ClassLoader imageClassLoader = access.getApplicationClassLoader();
140166
List<Path> classPath = access.getApplicationClassPath();
141167

142-
// Find all the classes that are Coherence functional interfaces,
143-
// basically any class under a Coherence package annotated with @FunctionalInterface
144168
scan(imageClassLoader, classPath, classInfo ->
145169
{
146170
try
147171
{
148172
var clazz = Class.forName(classInfo.getName(), false, imageClassLoader);
149173
String packageName = clazz.getPackageName();
150174

151-
if (clazz.isAnnotationPresent(FunctionalInterface.class)
152-
&& Serializable.class.isAssignableFrom(clazz)
153-
&& (packageName.startsWith("com.oracle.coherence") || packageName.startsWith("com.tangosol")))
175+
if (packageName.startsWith("com.oracle.coherence") || packageName.startsWith("com.tangosol"))
154176
{
155-
access.registerSubtypeReachabilityHandler(LambdaReachableTypeHandler.INSTANCE, clazz);
177+
// this is a Coherence class
178+
179+
// Find all the classes that are Coherence functional interfaces,
180+
// basically any class under a Coherence package annotated with @FunctionalInterface
181+
if (clazz.isAnnotationPresent(FunctionalInterface.class) && Serializable.class.isAssignableFrom(clazz))
182+
{
183+
access.registerSubtypeReachabilityHandler(LambdaReachableTypeHandler.INSTANCE, clazz);
184+
}
185+
186+
// Assume any Coherence interface with a name ending MBean needs to be proxied
187+
if (clazz.isInterface() && clazz.getSimpleName().endsWith("MBean"))
188+
{
189+
RuntimeProxyCreation.register(clazz);
190+
}
191+
192+
if (Collection.class.isAssignableFrom(clazz) && Serializable.class.isAssignableFrom(clazz))
193+
{
194+
// this is a Coherence serializable collection so register it
195+
RuntimeSerialization.register(clazz);
196+
}
197+
else if (Map.class.isAssignableFrom(clazz) && Serializable.class.isAssignableFrom(clazz))
198+
{
199+
// this is a Coherence serializable map so register it
200+
RuntimeSerialization.register(clazz);
201+
}
156202
}
157203
}
158204
catch (ClassNotFoundException | NoClassDefFoundError e)
@@ -171,7 +217,18 @@ public void beforeAnalysis(BeforeAnalysisAccess access)
171217
RuntimeSerialization.register(WrapperException.class);
172218
RuntimeSerialization.register(ReflectiveOperationException.class);
173219
RuntimeSerialization.register(InvocationTargetException.class);
220+
RuntimeSerialization.register(RejectedExecutionException.class);
221+
RuntimeSerialization.register(MBeanException.class);
222+
223+
RuntimeSerialization.register(LicensedObject.class);
224+
RuntimeSerialization.register(Permission.class);
225+
registerAllElements(Permission.class);
226+
RuntimeSerialization.register(ClusterPermission.class);
227+
registerAllElements(ClusterPermission.class);
228+
RuntimeSerialization.register(SignedObject.class);
229+
174230
RuntimeSerialization.register(MBeanAccessor.QueryBuilder.ParsedQuery.class);
231+
registerAllElements(MBeanAccessor.QueryBuilder.ParsedQuery.class);
175232

176233
RuntimeSerialization.register(BigDecimal.class);
177234
RuntimeSerialization.register(BigInteger.class);
@@ -181,13 +238,24 @@ public void beforeAnalysis(BeforeAnalysisAccess access)
181238
RuntimeSerialization.register(TreeSet.class);
182239
RuntimeSerialization.register(TreeMap.class);
183240

184-
// Coherence may return empty collections from some calls, so
241+
RuntimeSerialization.register(SafeHashMap.class);
242+
RuntimeSerialization.register(SimpleLongArray.class);
243+
244+
// Coherence may return collections from some calls, so
185245
// ensure these classes are registered for serialization
186246
// just in case the default serializer is in use
247+
RuntimeSerialization.register(LinkedList.class);
248+
registerAllElements(LinkedList.class);
249+
RuntimeSerialization.register(Collections.unmodifiableList(new ArrayList<>()).getClass());
250+
registerAllElements(Collections.unmodifiableList(new ArrayList<>()).getClass());
187251
RuntimeSerialization.register(Collections.EMPTY_LIST.getClass());
188252
registerAllElements(Collections.EMPTY_LIST.getClass());
253+
RuntimeSerialization.register(Collections.unmodifiableMap(new HashMap<>()).getClass());
254+
registerAllElements(Collections.unmodifiableMap(new HashMap<>()).getClass());
189255
RuntimeSerialization.register(Collections.EMPTY_MAP.getClass());
190256
registerAllElements(Collections.EMPTY_MAP.getClass());
257+
RuntimeSerialization.register(Collections.unmodifiableSet(new HashSet<>()).getClass());
258+
registerAllElements(Collections.unmodifiableSet(new HashSet<>()).getClass());
191259
RuntimeSerialization.register(Collections.EMPTY_SET.getClass());
192260
registerAllElements(Collections.EMPTY_SET.getClass());
193261

@@ -259,6 +327,7 @@ public void accept(DuringAnalysisAccess access, Class<?> clazz)
259327
MapJsonBodyHandler.class,
260328
MemberIdentityProvider.class,
261329
MetricsRegistryAdapter.class,
330+
MemberEvent.class,
262331
Model.class,
263332
NamespaceHandler.class,
264333
OperationalConfigNamespaceHandler.Extension.class,
@@ -284,19 +353,30 @@ public void accept(DuringAnalysisAccess access, Class<?> clazz)
284353
AbstractExtractor.class, // <-- Serializable but not Ext'Lite nor POF and some subclasses are not either
285354
ExternalizableLite.class,
286355
PortableException.class,
356+
Certificate.class,
357+
Principal.class,
358+
CertPath.class,
359+
Component.class,
287360
LongArray.class,
288361
AbstractSparseArray.class,
289362
AbstractSparseArray.Node.class,
290363
AbstractInvocable.class,
291364
TopicException.class,
292365
TopicPublisherException.class,
293-
Number.class,
366+
MemberEvent.class,
294367
Model.class,
368+
Number.class,
369+
PropertyAdapter.class,
370+
Listeners.class,
371+
AnyEvent.class,
372+
NullImplementation.NullSet.class,
373+
CacheCollator.class,
295374
SerializedLambda.class, // lambdas
296375
MBeanInfo.class, // MBeans
297376
MBeanFeatureInfo.class, // MBeans
298377
Descriptor.class, // MBeans
299378
SerializationSupport.class,
379+
SimpleMapEntry.class,
300380
WrapperCollections.AbstractWrapperCollection.class,
301381
WrapperCollections.AbstractWrapperEntry.class,
302382
WrapperCollections.AbstractWrapperMap.class);

prj/coherence-core/src/main/resources/META-INF/native-image/com.oracle.coherence/coherence/reachability-metadata.json

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1140,6 +1140,37 @@
11401140
}
11411141
]
11421142
},
1143+
{
1144+
"type": "java.security.cert.CertPath",
1145+
"serializable": true,
1146+
"allDeclaredFields": true,
1147+
"methods": [
1148+
{
1149+
"name": "<init>",
1150+
"parameterTypes": []
1151+
}
1152+
]
1153+
},
1154+
{
1155+
"type": "java.security.cert.CertPath$CertPathRep",
1156+
"serializable": true,
1157+
"allDeclaredFields": true,
1158+
"methods": [
1159+
{
1160+
"name": "<init>",
1161+
"parameterTypes": []
1162+
}
1163+
]
1164+
},
1165+
{
1166+
"type": "sun.security.provider.ConfigFile",
1167+
"methods": [
1168+
{
1169+
"name": "<init>",
1170+
"parameterTypes": []
1171+
}
1172+
]
1173+
},
11431174
{
11441175
"type": "sun.security.provider.DSAParameters",
11451176
"methods": [
@@ -1183,6 +1214,9 @@
11831214
{
11841215
"glob": "META-INF/pof.idx"
11851216
},
1217+
{
1218+
"glob": "META-INF/helidon/serial-config.properties"
1219+
},
11861220
{
11871221
"glob": "cache-factory-builder-config.xml"
11881222
},

prj/test/functional/concurrent-cdi/pom.xml

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
<?xml version="1.0"?>
22
<!--
3-
Copyright (c) 2000, 2022, Oracle and/or its affiliates.
3+
Copyright (c) 2000, 2025, Oracle and/or its affiliates.
44
55
Licensed under the Universal Permissive License v 1.0 as shown at
66
https://oss.oracle.com/licenses/upl.
@@ -23,6 +23,10 @@
2323
<module.name>concurrent.cdi.testing</module.name>
2424
<testClassesDirectory>${project.build.outputDirectory}</testClassesDirectory>
2525

26+
<!-- Currently fails native image testing -->
27+
<skip.native.build>true</skip.native.build>
28+
<skip.native.tests>true</skip.native.tests>
29+
2630
<failsafe.modules.argline>
2731
${default.failsafe.modules.argline}
2832
--add-reads com.oracle.coherence.cdi=ALL-UNNAMED

prj/test/functional/concurrent/pom.xml

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
<?xml version="1.0"?>
22
<!--
3-
Copyright (c) 2000, 2024, Oracle and/or its affiliates.
3+
Copyright (c) 2000, 2025, Oracle and/or its affiliates.
44
55
Licensed under the Universal Permissive License v 1.0 as shown at
66
https://oss.oracle.com/licenses/upl.
@@ -22,6 +22,9 @@
2222
<properties>
2323
<module.name>concurrent.testing</module.name>
2424
<testClassesDirectory>${project.build.outputDirectory}</testClassesDirectory>
25+
<!-- Currently fails native image testing -->
26+
<skip.native.build>true</skip.native.build>
27+
<skip.native.tests>true</skip.native.tests>
2528
</properties>
2629

2730
<dependencies>

prj/test/functional/concurrent/src/main/java/concurrent/AbstractClusteredRemoteSemaphoreExtendIT.java

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2000, 2022, Oracle and/or its affiliates.
2+
* Copyright (c) 2000, 2025, Oracle and/or its affiliates.
33
*
44
* Licensed under the Universal Permissive License v 1.0 as shown at
55
* https://oss.oracle.com/licenses/upl.
@@ -278,8 +278,7 @@ void shouldAcquirePermitHeldByFailedMember(CoherenceClusterMember member1, Coher
278278
member2.submit(new ClusteredRemoteSemaphoreIT.AcquirePermit(sSemaphoreName, 1, Duration.ofSeconds(5)));
279279

280280
// Kill first member
281-
RemoteCallable<Void> exit = new RemoteCallableStaticMethod<>("java.lang.System", "exit", 1);
282-
member1.submit(exit);
281+
member1.close();
283282

284283
// wait for the permit acquired event from the second member
285284
listener2.awaitAcquired(Duration.ofMinutes(1));

prj/test/functional/concurrent/src/main/java/concurrent/AbstractClusteredRemoteSemaphoreExtendProxyIT.java

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2000, 2022, Oracle and/or its affiliates.
2+
* Copyright (c) 2000, 2025, Oracle and/or its affiliates.
33
*
44
* Licensed under the Universal Permissive License v 1.0 as shown at
55
* https://oss.oracle.com/licenses/upl.
@@ -173,8 +173,7 @@ private CoherenceClusterMember killProxyForMember(CoherenceClusterMember member)
173173
.orElseThrow();
174174

175175
// Kill proxy
176-
RemoteCallable<Void> exit = new RemoteCallableStaticMethod<>("java.lang.System", "exit", 1);
177-
proxy.submit(exit);
176+
proxy.close();
178177
Eventually.assertDeferred(() ->
179178
{
180179
try

prj/test/functional/concurrent/src/main/java/concurrent/locks/AbstractClusteredRemoteLockExtendIT.java

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2000, 2022, Oracle and/or its affiliates.
2+
* Copyright (c) 2000, 2025, Oracle and/or its affiliates.
33
*
44
* Licensed under the Universal Permissive License v 1.0 as shown at
55
* https://oss.oracle.com/licenses/upl.
@@ -244,8 +244,7 @@ void shouldAcquireLockHeldByFailedMember(CoherenceClusterMember member1, Coheren
244244
member2.submit(new AcquireLock(sLockName, Duration.ofSeconds(5)));
245245

246246
// Kill first member
247-
RemoteCallable<Void> exit = new RemoteCallableStaticMethod<>("java.lang.System", "exit", 1);
248-
member1.submit(exit);
247+
member1.close();
249248

250249
// wait for the lock acquired event from the second member
251250
listener2.awaitAcquired(Duration.ofMinutes(1));

prj/test/functional/concurrent/src/main/java/concurrent/locks/AbstractClusteredRemoteLockExtendProxyIT.java

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2000, 2022, Oracle and/or its affiliates.
2+
* Copyright (c) 2000, 2025, Oracle and/or its affiliates.
33
*
44
* Licensed under the Universal Permissive License v 1.0 as shown at
55
* https://oss.oracle.com/licenses/upl.
@@ -137,8 +137,7 @@ void shouldNotAcquireLockHeldByExtendClientThroughFailedProxy(CoherenceClusterMe
137137
.orElseThrow();
138138

139139
// Kill proxy
140-
RemoteCallable<Void> exit = new RemoteCallableStaticMethod<>("java.lang.System", "exit", 1);
141-
proxy.submit(exit);
140+
proxy.close();
142141

143142
// Wait for proxy to stop
144143
Eventually.assertDeferred(() -> {

0 commit comments

Comments
 (0)