Skip to content

Commit

Permalink
Allow classes to be loaded via plugin loader
Browse files Browse the repository at this point in the history
When a plugin is used, additional RMI classes may be added to the
codebase. These need to be taken into account when loading remote
objects from the RMI registry.
  • Loading branch information
qtc-de committed Mar 26, 2024
1 parent af1c521 commit 454a9fd
Show file tree
Hide file tree
Showing 3 changed files with 76 additions and 15 deletions.
84 changes: 72 additions & 12 deletions src/eu/tneitzel/rmg/internal/CodebaseCollector.java
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
import java.util.HashSet;
import java.util.Set;

import eu.tneitzel.rmg.plugin.PluginSystem;
import eu.tneitzel.rmg.utils.RMGUtils;
import javassist.CannotCompileException;
import javassist.NotFoundException;
Expand Down Expand Up @@ -87,18 +88,42 @@ public class CodebaseCollector extends RMIClassLoaderSpi
*/
public Class<?> loadClass(String codebase, String name, ClassLoader defaultLoader) throws MalformedURLException, ClassNotFoundException
{
Class<?> resolvedClass = null;
long serialVersionUID = RMGOption.SERIAL_VERSION_UID.getValue();

addCodebase(codebase, name);
codebase = null;

long serialVersionUID = RMGOption.SERIAL_VERSION_UID.getValue();

if (serialVersionUIDMap.containsKey(name))
{
serialVersionUID = serialVersionUIDMap.get(name);
name = "_" + name;
}

else
{
try
{
// attempt to load the class directly
return originalLoader.loadClass(codebase, name, defaultLoader);
}

catch (ClassNotFoundException e) {}

if (PluginSystem.pluginLoader != null)
{
try
{
// if a plugin is used attempt to load the class via the plugin loader
return originalLoader.loadClass(codebase, name, PluginSystem.pluginLoader);
}

catch (ClassNotFoundException e) {}
}
}

// class could neither be loaded directly nor via plugin. Dynamic creation is required.
Class<?> resolvedClass = null;

try
{
if (name.endsWith("_Stub"))
Expand Down Expand Up @@ -147,19 +172,47 @@ else if (name.contains("SocketFactory") || name.endsWith("Factory") || name.ends
*/
public Class<?> loadProxyClass(String codebase, String[] interfaces, ClassLoader defaultLoader) throws MalformedURLException, ClassNotFoundException
{
for (String intf : interfaces)
{
addCodebase(codebase, intf);
}

codebase = null;
Class<?> resolvedClass = null;

try {
try
{
// attempt to load the class directly without dynamic class creation
return originalLoader.loadProxyClass(codebase, interfaces, defaultLoader);
}

catch (ClassNotFoundException e) {}

if (PluginSystem.pluginLoader != null)
{
try
{
// if a plugin is used, attempt to load the class from the plugin loader
return originalLoader.loadProxyClass(codebase, interfaces, PluginSystem.pluginLoader);
}

catch (ClassNotFoundException e) {}
}

for(String intf : interfaces) {
try
{
// the class could neither be loaded directly nor via plugin. Dynamic creation is required
for (String intf : interfaces)
{
RMGUtils.makeInterface(intf);
addCodebase(codebase, intf);
}

codebase = null;
resolvedClass = originalLoader.loadProxyClass(codebase, interfaces, defaultLoader);

} catch (CannotCompileException e) {
}

catch (CannotCompileException e)
{
ExceptionHandler.internalError("loadProxyClass", "Unable to compile unknown interface class.");
}

Expand Down Expand Up @@ -235,17 +288,24 @@ public static void addSerialVersionUID(String className, long serialVersionUID)
*/
private void addCodebase(String codebase, String className)
{
if( codebase == null )
if (codebase == null)
{
return;
}

if( className.startsWith("java.") || className.startsWith("[Ljava") || className.startsWith("javax.") )
if (className.startsWith("java.") || className.startsWith("[Ljava") || className.startsWith("javax."))
{
codebases.putIfAbsent(codebase, new HashSet<String>());
}

else if( codebases.containsKey(codebase) ) {
else if (codebases.containsKey(codebase))
{
Set<String> classNames = codebases.get(codebase);
classNames.add(className);
}

} else {
else
{
Set<String> classNames = new HashSet<String>();
classNames.add(className);
codebases.put(codebase, classNames);
Expand Down
2 changes: 1 addition & 1 deletion src/eu/tneitzel/rmg/networking/RMIRegistryEndpoint.java
Original file line number Diff line number Diff line change
Expand Up @@ -219,7 +219,7 @@ public Remote lookup(String boundName) throws UnmarshalException
ExceptionHandler.notBoundException(e, boundName);
}

catch( Exception e )
catch (Exception e)
{
Throwable cause = ExceptionHandler.getCause(e);

Expand Down
5 changes: 3 additions & 2 deletions src/eu/tneitzel/rmg/plugin/PluginSystem.java
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@
public class PluginSystem
{
private static String manifestAttribute = "RmgPluginClass";
public static URLClassLoader pluginLoader = null;

private static IActionProvider actionProvider = null;
private static IPayloadProvider payloadProvider = null;
Expand Down Expand Up @@ -115,8 +116,8 @@ private static void loadPlugin(String pluginPath)

try
{
URLClassLoader ucl = new URLClassLoader(new URL[] {pluginFile.toURI().toURL()});
Class<?> pluginClass = Class.forName(pluginClassName, true, ucl);
pluginLoader = new URLClassLoader(new URL[] {pluginFile.toURI().toURL()});
Class<?> pluginClass = Class.forName(pluginClassName, true, pluginLoader);
pluginInstance = pluginClass.newInstance();
}

Expand Down

0 comments on commit 454a9fd

Please sign in to comment.