Package de.netseeker.ejoe

Source Code of de.netseeker.ejoe.EJClassLoader

/*********************************************************************
* EJClassLoader.java
* created on 08.08.2004 by netseeker
* $Source: /cvsroot/ejoe/EJOE/src/de/netseeker/ejoe/EJClassLoader.java,v $
* $Date: 2007/03/22 21:01:35 $
* $Revision: 1.28 $
*
* ====================================================================
*
*  Copyright 2005-2006 netseeker aka Michael Manske
*
*  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.
* ====================================================================
*
* This file is part of the ejoe framework.
* For more information on the author, please see
* <http://www.manskes.de/>.
*
*********************************************************************/

package de.netseeker.ejoe;

import java.io.IOException;
import java.io.Serializable;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;

import de.netseeker.ejoe.adapter.ObjectStreamAdapter;
import de.netseeker.ejoe.cache.LRUMap;
import de.netseeker.ejoe.request.ClassloaderRequest;

/**
* A remote classloader using an EJClient instance (shared per EJServer) to retrieve class definitions from an EJServer.
* The last thousand retrieved classes are cached global over all instances of EJClassLoader. The used cache uses soft
* references.
*
* @author netseeker aka Michael Manske
* @since 0.3.0
*/
public class EJClassLoader extends ClassLoader implements Serializable
{
    private static final long    serialVersionUID = 1L;

    transient private static Map _classCache      = new LRUMap();

    private static Map           _clients         = Collections.synchronizedMap( new HashMap() );

    private String               _clientKey;

    /**
     * Creates a new instance of this classloader using the EJOE server on the given host and port for loading unknown
     * class definitions.
     *
     * @param host ip address or dns name where the EJOE classloader server is running
     * @param port port to which the EJOE classloader serve is listening
     */
    public EJClassLoader(String host, int port)
    {
        super();
        initEJClient( host, port );
    }

    /**
     * Creates a new instance of this classloader using the EJOE server on the given host and port for loading unknown
     * class definitions. The classloader will delegate calls first to the given parent classloader.
     *
     * @param parent parent classloader
     * @param host ip address or dns name where the EJOE classloader server is running
     * @param port port to which the EJOE classloader serve is listening
     */
    public EJClassLoader(ClassLoader parent, String host, int port)
    {
        super( parent );
        initEJClient( host, port );
    }

    /**
     * @param host
     * @param port
     */
    private void initEJClient( String host, int port )
    {
        _clientKey = host + ':' + port;

        if ( !_clients.containsKey( _clientKey ) )
        {
            _clients.put( _clientKey, new EJClient( host, port, new ObjectStreamAdapter() ) );
        }
    }

    /*
     * (non-Javadoc)
     *
     * @see java.lang.ClassLoader#loadClass(java.lang.String, boolean)
     */
    protected synchronized Class loadClass( String name, boolean resolve ) throws ClassNotFoundException
    {
        if ( _classCache == null )
        {
            _classCache = new LRUMap();
        }

        Class clazz = (Class) _classCache.get( name );

        if ( clazz == null )
        {
            // ----- Check with the primordial class loader
            try
            {
                clazz = super.findSystemClass( name );
                return clazz;
            }
            catch ( ClassNotFoundException e )
            {
                // do nothing, it's just not a system class
            }

            clazz = loadRemoteClass( name );
            _classCache.put( name, clazz );

            if ( resolve )
            {
                resolveClass( clazz );
            }
        }

        return clazz;
    }

    /*
     * (non-Javadoc)
     *
     * @see java.lang.ClassLoader#loadClass(java.lang.String)
     */
    public Class loadClass( String name ) throws ClassNotFoundException
    {
        return loadClass( name, true );
    }

    /**
     * @param name
     * @return
     * @throws IOException
     */
    private Class loadRemoteClass( String name ) throws ClassNotFoundException
    {
        Class result = null;
        EJClient client = (EJClient) _clients.get( _clientKey );

        try
        {
            byte[] classRaw = (byte[]) client.execute( new ClassloaderRequest( name ) );
            if ( classRaw == null )
            {
                throw new ClassNotFoundException( "Class " + name + " not found!" );
            }

            result = defineClass( name, classRaw, 0, classRaw.length );
        }
        catch ( Throwable e )
        {
            throw new ClassNotFoundException( e.getMessage(), e );
        }

        return result;
    }
}
TOP

Related Classes of de.netseeker.ejoe.EJClassLoader

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.