/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You 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 org.apache.ignite.internal.managers.deployment;
import java.lang.reflect.Field;
import java.util.Map;
import org.apache.ignite.IgniteCheckedException;
import org.apache.ignite.IgniteLogger;
import org.apache.ignite.compute.ComputeTask;
import org.apache.ignite.internal.GridKernalContext;
import org.apache.ignite.internal.util.typedef.internal.S;
import org.apache.ignite.spi.deployment.DeploymentSpi;
import org.jetbrains.annotations.Nullable;
/**
* Adapter for all store implementations.
*/
abstract class GridDeploymentStoreAdapter implements GridDeploymentStore {
/** Logger. */
protected final IgniteLogger log;
/** Deployment SPI. */
protected final DeploymentSpi spi;
/** Kernal context. */
protected final GridKernalContext ctx;
/** Deployment communication. */
protected final GridDeploymentCommunication comm;
/**
* @param spi Underlying SPI.
* @param ctx Grid kernal context.
* @param comm Deployment communication.
*/
GridDeploymentStoreAdapter(DeploymentSpi spi, GridKernalContext ctx, GridDeploymentCommunication comm) {
assert spi != null;
assert ctx != null;
assert comm != null;
this.spi = spi;
this.ctx = ctx;
this.comm = comm;
log = ctx.log(getClass());
}
/**
* @return Startup log message.
*/
protected final String startInfo() {
return "Deployment store started: " + this;
}
/**
* @return Stop log message.
*/
protected final String stopInfo() {
return "Deployment store stopped: " + this;
}
/** {@inheritDoc} */
@Override public void onKernalStart() throws IgniteCheckedException {
if (log.isDebugEnabled())
log.debug("Ignoring kernel started callback: " + this);
}
/** {@inheritDoc} */
@Override public void onKernalStop() {
/* No-op. */
}
/** {@inheritDoc} */
@Nullable @Override public GridDeployment explicitDeploy(Class<?> cls, ClassLoader clsLdr) throws IgniteCheckedException {
if (log.isDebugEnabled())
log.debug("Ignoring explicit deploy [cls=" + cls + ", clsLdr=" + clsLdr + ']');
return null;
}
/**
* @param ldr Class loader.
* @return User version.
*/
protected final String userVersion(ClassLoader ldr) {
return ctx.userVersion(ldr);
}
/**
* @param cls Class to check.
* @return {@code True} if class is task class.
*/
protected final boolean isTask(Class<?> cls) {
return ComputeTask.class.isAssignableFrom(cls);
}
/**
* Clears serialization caches to avoid PermGen memory leaks.
* This method should be called on each undeployment.
* <p>
* For more information: http://www.szegedi.org/articles/memleak3.html.
*/
protected final void clearSerializationCaches() {
try {
clearSerializationCache(Class.forName("java.io.ObjectInputStream$Caches"), "subclassAudits");
clearSerializationCache(Class.forName("java.io.ObjectOutputStream$Caches"), "subclassAudits");
clearSerializationCache(Class.forName("java.io.ObjectStreamClass$Caches"), "localDescs");
clearSerializationCache(Class.forName("java.io.ObjectStreamClass$Caches"), "reflectors");
}
catch (ClassNotFoundException e) {
if (log.isDebugEnabled())
log.debug("Class not found: " + e.getMessage());
}
catch (NoSuchFieldException e) {
if (log.isDebugEnabled())
log.debug("Field not found: " + e.getMessage());
}
catch (IllegalAccessException e) {
if (log.isDebugEnabled())
log.debug("Field can't be accessed: " + e.getMessage());
}
}
/**
* @param cls Class name.
* @param fieldName Field name.
* @throws IllegalAccessException If field can't be accessed.
* @throws NoSuchFieldException If class can't be found.
*/
private void clearSerializationCache(Class cls, String fieldName)
throws NoSuchFieldException, IllegalAccessException {
Field f = cls.getDeclaredField(fieldName);
f.setAccessible(true);
((Map)f.get(null)).clear();
}
/** {@inheritDoc} */
@Override public String toString() {
return S.toString(GridDeploymentStoreAdapter.class, this);
}
}