From 3dc374e008d7330c5c4e5b8853e393ec2296fda0 Mon Sep 17 00:00:00 2001 From: hg-ms <53219833+hg-ms@users.noreply.github.com> Date: Wed, 6 Nov 2024 13:36:10 +0100 Subject: [PATCH 1/5] fixing android issues #325 and #326 serializer parts --- .../monitoring/MonitoringManager.java | 41 ++++++- .../reference/LazyReferenceManager.java | 2 +- .../org/eclipse/serializer/util/VMInfo.java | 113 ++++++++++++++++++ .../binary/types/BinaryPersistence.java | 22 +++- 4 files changed, 172 insertions(+), 6 deletions(-) create mode 100644 base/src/main/java/org/eclipse/serializer/util/VMInfo.java diff --git a/base/src/main/java/org/eclipse/serializer/monitoring/MonitoringManager.java b/base/src/main/java/org/eclipse/serializer/monitoring/MonitoringManager.java index ab752bb9..44ba21e5 100644 --- a/base/src/main/java/org/eclipse/serializer/monitoring/MonitoringManager.java +++ b/base/src/main/java/org/eclipse/serializer/monitoring/MonitoringManager.java @@ -63,7 +63,7 @@ public interface MonitoringManager * * @return a MonitoringManager.JMX instance */ - public static MonitoringManager New() + public static MonitoringManager JMX() { return new JMX(); } @@ -75,14 +75,28 @@ public static MonitoringManager New() * * @return a MonitoringManager.JMX instance */ - public static MonitoringManager New(final String name) + public static MonitoringManager JMX(final String name) { return new JMX(name); } - + + /** + * Provides a new instance of the disabled monitor manager implementation + * + * @return a MonitoringManager.Disabled instance + */ + public static MonitoringManager Disabled() + { + return new MonitoringManager.Disabled(); + } + /** * MonitoringManager implementation using the java management extension to provide * metrics and monitoring data. + * + * Please be aware that not all Java implementations may provide JMX support + * e.g. Android. + * */ public class JMX implements MonitoringManager { @@ -174,4 +188,25 @@ private ObjectName createObjectName(final MetricMonitor metric) throws Malformed } + /** + * Disabled Monitoring Manager implementation. + * This implementation disables the monitoring by not registering + * MetricMonitors. + */ + public class Disabled implements MonitoringManager + { + @Override + public void registerMonitor(MetricMonitor metrics) + { + //NoOp + } + + @Override + public void shutdown() + { + //NoOp + } + + } + } diff --git a/base/src/main/java/org/eclipse/serializer/reference/LazyReferenceManager.java b/base/src/main/java/org/eclipse/serializer/reference/LazyReferenceManager.java index 12e36c27..dacd12b3 100644 --- a/base/src/main/java/org/eclipse/serializer/reference/LazyReferenceManager.java +++ b/base/src/main/java/org/eclipse/serializer/reference/LazyReferenceManager.java @@ -152,7 +152,7 @@ public static LazyReferenceManager New( checker, _longReference.New(milliTimeCheckInterval), _longReference.New(nanoTimeBudget) , - MonitoringManager.New(null) + MonitoringManager.JMX(null) ); } diff --git a/base/src/main/java/org/eclipse/serializer/util/VMInfo.java b/base/src/main/java/org/eclipse/serializer/util/VMInfo.java new file mode 100644 index 00000000..20294f7a --- /dev/null +++ b/base/src/main/java/org/eclipse/serializer/util/VMInfo.java @@ -0,0 +1,113 @@ +package org.eclipse.serializer.util; + +/** + * Helper class to identify the current VM + */ +public interface VMInfo +{ + /** + * Returns true if the current jvm is the default jvm. + * that supports all java features. + * + * @return true if default jvm + */ + public boolean isStandardJava(); + + /** + * Returns true if the current jvm is a default android jvm. + * + * @return true if default android + */ + public boolean isStandardAndroid(); + + /** + * Returns true if the current jvm a GraalVm native image. + * + * @return if GraalVm native image. + */ + public boolean isGraalVmNativeImage(); + + /** + * Returns true if the current jvm any kind if android. + * + * @return true if any android. + */ + public boolean isAnyAndroid(); + + public static VMInfo New() + { + return new VMInfo.Default(); + } + + public static class Default implements VMInfo + { + private static final String ANY_ANDROID_VENDOR = "android"; + private static final String DEFAULT_ANDROID_VENDOR = "The Android Project"; + + private static final String JAVA_VENDOR = System.getProperty("java.vendor", "").toLowerCase(); + private static final String JAVA_VM_VENDOR = System.getProperty("java.vm.vendor", "").toLowerCase(); + private static final String ORG_GRAALVM_NATIVEIMAGE_IMAGECODE = System.getProperty("org.graalvm.nativeimage.imagecode","").toLowerCase(); + + private static final boolean ANY_ANDROID = checkAnyAndroid(); + private static final boolean GRAALVM_NATIVEIMAGE = checkGraalVMNativeImage(); + private static final boolean DEFAULT_ANDROID = checkStandardAndroid(); + private static final boolean DEFAULT_JAVA = checkStandardJavaVM(); + + + @Override + public final boolean isStandardJava() + { + return DEFAULT_JAVA; + } + + @Override + public final boolean isAnyAndroid() + { + return ANY_ANDROID; + } + + @Override + public final boolean isGraalVmNativeImage() + { + return GRAALVM_NATIVEIMAGE; + } + + @Override + public final boolean isStandardAndroid() + { + return DEFAULT_ANDROID; + } + + private static boolean checkStandardJavaVM() + { + return + !checkStandardAndroid() && + !checkAnyAndroid() && + !checkGraalVMNativeImage() + ; + } + + private static boolean checkStandardAndroid() + { + return + JAVA_VENDOR.equalsIgnoreCase(DEFAULT_ANDROID_VENDOR) || + JAVA_VM_VENDOR.equalsIgnoreCase(DEFAULT_ANDROID_VENDOR) + ; + } + + private static boolean checkAnyAndroid() + { + return + JAVA_VENDOR.contains(ANY_ANDROID_VENDOR) || + JAVA_VM_VENDOR.contains(ANY_ANDROID_VENDOR) + ; + } + + private static boolean checkGraalVMNativeImage() + { + return !ORG_GRAALVM_NATIVEIMAGE_IMAGECODE.isBlank(); + } + + } + +} diff --git a/persistence/binary/src/main/java/org/eclipse/serializer/persistence/binary/types/BinaryPersistence.java b/persistence/binary/src/main/java/org/eclipse/serializer/persistence/binary/types/BinaryPersistence.java index 60d0cf10..8ebd8f14 100644 --- a/persistence/binary/src/main/java/org/eclipse/serializer/persistence/binary/types/BinaryPersistence.java +++ b/persistence/binary/src/main/java/org/eclipse/serializer/persistence/binary/types/BinaryPersistence.java @@ -20,6 +20,7 @@ import java.util.Optional; import org.eclipse.serializer.afs.types.AFile; +import org.eclipse.serializer.collections.BulkList; import org.eclipse.serializer.collections.ConstList; import org.eclipse.serializer.collections.types.XGettingCollection; import org.eclipse.serializer.collections.types.XGettingSequence; @@ -128,6 +129,7 @@ import org.eclipse.serializer.reference.Referencing; import org.eclipse.serializer.reference.Swizzling; import org.eclipse.serializer.typing.XTypes; +import org.eclipse.serializer.util.VMInfo; public final class BinaryPersistence extends Persistence { @@ -169,6 +171,7 @@ public static final PersistenceCustomTypeHandlerRegistry createDefaultCu .registerTypeHandlers(nativeHandlersReferencingTypes) .registerTypeHandlers(defaultCustomHandlers(controller)) .registerTypeHandlers(lazyCollectionsHandlers()) + .registerTypeHandlers(platformDependentHandlers()) .registerTypeHandlers(customHandlers) ; @@ -331,8 +334,7 @@ static final void initializeNativeTypeId( BinaryHandlerArrayDeque.New() , BinaryHandlerConcurrentSkipListMap.New(), BinaryHandlerConcurrentSkipListSet.New(), - BinaryHandlerSetFromMap.New(), - + // JDK 1.7 collections BinaryHandlerConcurrentLinkedDeque.New(), @@ -388,6 +390,22 @@ static final void initializeNativeTypeId( return lazyCollectionsHandlers; } + + @SuppressWarnings("unchecked") + public static final XGettingSequence> platformDependentHandlers() + { + VMInfo vmInfo = new VMInfo.Default(); + + final BulkList platformDependentHandlers = BulkList.New(); + + if(!vmInfo.isAnyAndroid()) + { + platformDependentHandlers.add(BinaryHandlerSetFromMap.New()); + } + + return (XGettingSequence>) platformDependentHandlers; + } + public static final long resolveFieldBinaryLength(final Class fieldType) { From 5bdbf9dcf674ad7d52fe6099ba0101ed5395ddab Mon Sep 17 00:00:00 2001 From: hg-ms <53219833+hg-ms@users.noreply.github.com> Date: Wed, 6 Nov 2024 13:40:14 +0100 Subject: [PATCH 2/5] added license text --- .../java/org/eclipse/serializer/util/VMInfo.java | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/base/src/main/java/org/eclipse/serializer/util/VMInfo.java b/base/src/main/java/org/eclipse/serializer/util/VMInfo.java index 20294f7a..13b691cb 100644 --- a/base/src/main/java/org/eclipse/serializer/util/VMInfo.java +++ b/base/src/main/java/org/eclipse/serializer/util/VMInfo.java @@ -1,5 +1,19 @@ package org.eclipse.serializer.util; +/*- + * #%L + * Eclipse Serializer Base + * %% + * Copyright (C) 2023 - 2024 MicroStream Software + * %% + * This program and the accompanying materials are made + * available under the terms of the Eclipse Public License 2.0 + * which is available at https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * #L% + */ + /** * Helper class to identify the current VM */ From 03f7cc2d5b8d96d4d9a7a400bcc5edad4f7494cc Mon Sep 17 00:00:00 2001 From: hg-ms <53219833+hg-ms@users.noreply.github.com> Date: Wed, 6 Nov 2024 14:53:00 +0100 Subject: [PATCH 3/5] reworked BinaryHandlerSetFromMap generics --- .../java/util/BinaryHandlerSetFromMap.java | 21 ++++++++++--------- .../binary/types/BinaryPersistence.java | 4 ++-- 2 files changed, 13 insertions(+), 12 deletions(-) diff --git a/persistence/binary/src/main/java/org/eclipse/serializer/persistence/binary/java/util/BinaryHandlerSetFromMap.java b/persistence/binary/src/main/java/org/eclipse/serializer/persistence/binary/java/util/BinaryHandlerSetFromMap.java index 5ddb1f87..705d4aba 100644 --- a/persistence/binary/src/main/java/org/eclipse/serializer/persistence/binary/java/util/BinaryHandlerSetFromMap.java +++ b/persistence/binary/src/main/java/org/eclipse/serializer/persistence/binary/java/util/BinaryHandlerSetFromMap.java @@ -17,6 +17,7 @@ import java.util.Collections; import java.util.HashMap; import java.util.Map; +import java.util.Set; import org.eclipse.serializer.memory.XMemory; import org.eclipse.serializer.persistence.binary.types.AbstractBinaryHandlerCustom; @@ -29,26 +30,27 @@ /** * Binary Handler for private class "java.util.Collections$SetFromMap" */ -public class BinaryHandlerSetFromMap extends AbstractBinaryHandlerCustom +public class BinaryHandlerSetFromMap extends AbstractBinaryHandlerCustom> { private static long offsetMap; private static long offsetSet; - - public static BinaryHandlerSetFromMap New() + + @SuppressWarnings({ "rawtypes", "unchecked" }) + public static BinaryHandlerSetFromMap New() { Class clazz = XReflect.getDeclaredNestedClass(Collections.class, "java.util.Collections$SetFromMap"); offsetMap = XMemory.objectFieldOffset(XReflect.getAnyField(clazz, "m")); offsetSet = XMemory.objectFieldOffset(XReflect.getAnyField(clazz, "s")); - return new BinaryHandlerSetFromMap<>(clazz); + return new BinaryHandlerSetFromMap(clazz); } /////////////////////////////////////////////////////////////////////////// // constructors // ///////////////// - protected BinaryHandlerSetFromMap(final Class type) + protected BinaryHandlerSetFromMap(Class> type) { super(type, CustomFields( @@ -67,7 +69,7 @@ public void iterateLoadableReferences(final Binary data, final PersistenceRefere } @Override - public void updateState(final Binary data, T instance, final PersistenceLoadHandler handler) + public void updateState(final Binary data, Set instance, final PersistenceLoadHandler handler) { final Map hashmap = (Map) handler.lookupObject(data.read_long(0)); @@ -76,7 +78,7 @@ public void updateState(final Binary data, T instance, final PersistenceLoadHand } @Override - public void store(final Binary data, final T instance, final long objectId, final PersistenceStoreHandler handler) + public void store(final Binary data, final Set instance, final long objectId, final PersistenceStoreHandler handler) { data.storeEntityHeader(Binary.referenceBinaryLength(1), this.typeId(), objectId); @@ -84,11 +86,10 @@ public void store(final Binary data, final T instance, final long objectId, fina data.storeReference(0, handler, mapInstance); } - @SuppressWarnings("unchecked") @Override - public T create(final Binary data, final PersistenceLoadHandler handler) + public Set create(final Binary data, final PersistenceLoadHandler handler) { - return (T) Collections.newSetFromMap(new HashMap()); + return Collections.newSetFromMap(new HashMap()); } } diff --git a/persistence/binary/src/main/java/org/eclipse/serializer/persistence/binary/types/BinaryPersistence.java b/persistence/binary/src/main/java/org/eclipse/serializer/persistence/binary/types/BinaryPersistence.java index 8ebd8f14..a4ccd780 100644 --- a/persistence/binary/src/main/java/org/eclipse/serializer/persistence/binary/types/BinaryPersistence.java +++ b/persistence/binary/src/main/java/org/eclipse/serializer/persistence/binary/types/BinaryPersistence.java @@ -396,14 +396,14 @@ static final void initializeNativeTypeId( { VMInfo vmInfo = new VMInfo.Default(); - final BulkList platformDependentHandlers = BulkList.New(); + final BulkList> platformDependentHandlers = BulkList.New(); if(!vmInfo.isAnyAndroid()) { platformDependentHandlers.add(BinaryHandlerSetFromMap.New()); } - return (XGettingSequence>) platformDependentHandlers; + return platformDependentHandlers; } From 80f000e2268af8939fec5ba0fbc47b69650b1c7b Mon Sep 17 00:00:00 2001 From: hg-ms <53219833+hg-ms@users.noreply.github.com> Date: Thu, 7 Nov 2024 09:15:15 +0100 Subject: [PATCH 4/5] LazyReferenceManager Monitor Initialization Android aware --- .../org/eclipse/serializer/reference/LazyReferenceManager.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/base/src/main/java/org/eclipse/serializer/reference/LazyReferenceManager.java b/base/src/main/java/org/eclipse/serializer/reference/LazyReferenceManager.java index dacd12b3..f38fd541 100644 --- a/base/src/main/java/org/eclipse/serializer/reference/LazyReferenceManager.java +++ b/base/src/main/java/org/eclipse/serializer/reference/LazyReferenceManager.java @@ -21,6 +21,7 @@ import org.eclipse.serializer.monitoring.LazyReferenceManagerMonitor; import org.eclipse.serializer.monitoring.MonitoringManager; import org.eclipse.serializer.time.XTime; +import org.eclipse.serializer.util.VMInfo; import org.eclipse.serializer.util.logging.Logging; import org.slf4j.Logger; @@ -152,7 +153,7 @@ public static LazyReferenceManager New( checker, _longReference.New(milliTimeCheckInterval), _longReference.New(nanoTimeBudget) , - MonitoringManager.JMX(null) + VMInfo.New().isAnyAndroid() ? MonitoringManager.Disabled() : MonitoringManager.JMX(null) ); } From b1e48ce87d30bdecb6f3d1d9a6cca94a06c62004 Mon Sep 17 00:00:00 2001 From: hg-ms <53219833+hg-ms@users.noreply.github.com> Date: Fri, 8 Nov 2024 10:10:04 +0100 Subject: [PATCH 5/5] Moved platform dependent init into MonitoringManager --- .../monitoring/MonitoringManager.java | 27 +++++++++++++++++++ .../reference/LazyReferenceManager.java | 3 +-- 2 files changed, 28 insertions(+), 2 deletions(-) diff --git a/base/src/main/java/org/eclipse/serializer/monitoring/MonitoringManager.java b/base/src/main/java/org/eclipse/serializer/monitoring/MonitoringManager.java index 44ba21e5..3ba5e74b 100644 --- a/base/src/main/java/org/eclipse/serializer/monitoring/MonitoringManager.java +++ b/base/src/main/java/org/eclipse/serializer/monitoring/MonitoringManager.java @@ -28,6 +28,7 @@ import javax.management.ObjectInstance; import javax.management.ObjectName; +import org.eclipse.serializer.util.VMInfo; import org.eclipse.serializer.util.logging.Logging; import org.slf4j.Logger; @@ -58,6 +59,32 @@ public interface MonitoringManager */ void shutdown(); + + /** + * Provide a platform dependent MonitoringManager. + * This is either the "JMX" implementation or the "Disabled" implementation + * on android systems. + * + * @param name a user defined name used to distinguish different instances. + * if null the Manager chooses a name internaly. + * + * @return a platform dependent MonitoringManage instance + */ + public static MonitoringManager PlatformDependent(final String name) + { + if(VMInfo.New().isAnyAndroid()) + { + return Disabled(); + } + + if(name != null) + { + return JMX(name); + } + + return JMX(); + } + /** * Provides a new instance of the default JMX MonitoringManager implementation. * diff --git a/base/src/main/java/org/eclipse/serializer/reference/LazyReferenceManager.java b/base/src/main/java/org/eclipse/serializer/reference/LazyReferenceManager.java index f38fd541..217dce2b 100644 --- a/base/src/main/java/org/eclipse/serializer/reference/LazyReferenceManager.java +++ b/base/src/main/java/org/eclipse/serializer/reference/LazyReferenceManager.java @@ -21,7 +21,6 @@ import org.eclipse.serializer.monitoring.LazyReferenceManagerMonitor; import org.eclipse.serializer.monitoring.MonitoringManager; import org.eclipse.serializer.time.XTime; -import org.eclipse.serializer.util.VMInfo; import org.eclipse.serializer.util.logging.Logging; import org.slf4j.Logger; @@ -153,7 +152,7 @@ public static LazyReferenceManager New( checker, _longReference.New(milliTimeCheckInterval), _longReference.New(nanoTimeBudget) , - VMInfo.New().isAnyAndroid() ? MonitoringManager.Disabled() : MonitoringManager.JMX(null) + MonitoringManager.PlatformDependent(null) ); }