RMI client look up RMI registry for remote object's stub instance.
LicServer licServer = (LicServer) Naming.lookup("//localhost:1099/LicServerAPI");
It return an instance of LicServerImpl_Stub. In run time, client need the Stub class to resolve it. It obtains it from local classpath or codeBase (remote classpath). The codeBase approach is to download the class bytecode via http, by setting -Djava.rmi.server.codebase=http://hostname/locationOfClasses
In our system, the RMI client resides on the same machine as a web app in an embedded Tomcat launched by webnms. Hence, it is able to get the stub files by classpath.
The
Tomcat classloading has a hierarchy structure.
- Bootstrap: JVM classes
- System: based on system CLASSPATH, however, the default startup script catalia.bat ingore it and only pass in BootStrap.jar to start up.
- Common: shared by all web app and tomcat server's internal classes
- webapps: each web app has it own classloader. This web application classloader doesn't follow the common parent delegation model except those java.* classes according to servlet spec recommendation.
To add classpath to system classloader, we can modify the classpath in script, or when launching embeded tomcat, we can pass server's classpath to it by
Thread.currentThread().setContextClassLoader(getClass().getClassLoader());
Class class1 = Class.forName("org.apache.catalina.startup.Bootstrap");
Method method = class1.getMethod("main", aclass);
method.invoke(null, aobj);
Applications written in statically compiled programming languages, such as C and C++, are compiled into native, machine-specific instructions and saved as an executable file. The process of combining the code into an executable native code is called linking - the merging of separately compiled code with shared library code to create an executable application. This is different in dynamically compiled programming languages such as Java. In Java, the .class files generated by the Java compiler remain as-is until loaded into the Java Virtual Machine (JVM) -- in other words, the linking process is performed by the JVM at runtime. Classes are loaded into the JVM on an 'as needed' basis. And when a loaded class depends on another class, then that class is loaded as well.
It gives us the flexibility to control the class loading, e.g., apply security policy, loading from remote place, etc.