All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.hazelcast.internal.serialization.impl.SerializerHookLoader Maven / Gradle / Ivy

The newest version!
/*
 * Copyright (c) 2008-2024, Hazelcast, Inc. All Rights Reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.hazelcast.internal.serialization.impl;

import com.hazelcast.config.SerializationConfig;
import com.hazelcast.config.SerializerConfig;
import com.hazelcast.internal.nio.ClassLoaderUtil;
import com.hazelcast.internal.util.ExceptionUtil;
import com.hazelcast.internal.util.ServiceLoader;
import com.hazelcast.logging.Logger;
import com.hazelcast.nio.serialization.HazelcastSerializationException;
import com.hazelcast.nio.serialization.Serializer;
import com.hazelcast.nio.serialization.SerializerHook;

import java.lang.reflect.Constructor;
import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

/**
 * Loads auto registered serializers using { SerializerHook}
 * by reading in the file "META-INF/services/com.hazelcast.SerializerHook" and instantiating
 * the defined SerializerHooks.
* This system is meant to be internal code and is subject to change at any time. */ final class SerializerHookLoader { private static final String FACTORY_ID = "com.hazelcast.SerializerHook"; private final boolean useDefaultConstructorOnly = Boolean.getBoolean("hazelcast.compat.serializers.use.default.constructor.only"); private final Map serializers = new HashMap<>(); private final Collection serializerConfigs; private final ClassLoader classLoader; SerializerHookLoader(SerializationConfig serializationConfig, ClassLoader classLoader) { this.serializerConfigs = serializationConfig != null ? serializationConfig.getSerializerConfigs() : null; this.classLoader = classLoader; load(); } private void load() { try { final Iterator hooks = ServiceLoader.iterator(SerializerHook.class, FACTORY_ID, classLoader); while (hooks.hasNext()) { final SerializerHook hook = hooks.next(); final Class serializationType = hook.getSerializationType(); if (serializationType != null) { serializers.put(serializationType, hook); } } } catch (Exception e) { throw ExceptionUtil.rethrow(e); } if (serializerConfigs != null) { for (SerializerConfig serializerConfig : serializerConfigs) { Serializer serializer = serializerConfig.getImplementation(); Class serializationType = serializerConfig.getTypeClass(); if (serializationType == null) { try { serializationType = ClassLoaderUtil.loadClass(classLoader, serializerConfig.getTypeClassName()); } catch (ClassNotFoundException e) { throw new HazelcastSerializationException(e); } } if (serializer == null) { serializer = createSerializerInstance(serializerConfig, serializationType); } register(serializationType, serializer); } } } private Serializer createSerializerInstance(SerializerConfig serializerConfig, Class serializationType) { try { String className = serializerConfig.getClassName(); if (useDefaultConstructorOnly) { return ClassLoaderUtil.newInstance(classLoader, className); } else { return createSerializerInstanceWithFallback(serializationType, className); } } catch (Exception e) { throw new HazelcastSerializationException(e); } } private Serializer createSerializerInstanceWithFallback(Class serializationType, String className) throws Exception { Class clazz = ClassLoaderUtil.loadClass(classLoader, className); try { Constructor constructor = clazz.getDeclaredConstructor(Class.class); constructor.setAccessible(true); return (Serializer) constructor.newInstance(serializationType); } catch (NoSuchMethodException e) { //fallback to no-arg constructor Constructor constructor = clazz.getDeclaredConstructor(); constructor.setAccessible(true); return (Serializer) constructor.newInstance(); } } Map getSerializers() { return serializers; } private void register(Class serializationType, Serializer serializer) { final Object current = serializers.get(serializationType); if (current != null) { if (current.equals(serializer)) { Logger.getLogger(getClass()).warning("Serializer[" + serializationType.toString() + "] is already registered! Skipping " + serializer); } else if (current instanceof SerializerHook hook && hook.isOverwritable()) { serializers.put(serializationType, serializer); } else { throw new IllegalArgumentException("Serializer[" + serializationType.toString() + "] is already registered! " + current + " -> " + serializer); } } else { serializers.put(serializationType, serializer); } } }




© 2015 - 2025 Weber Informatics LLC | Privacy Policy