Re: alternative to my ClassLoader hack
Steven Simpson wrote:
public class MyClassLoader {
public static void main(String... args) throws Exception {
// Using subdir of current directory as example.
File curDir = new File(System.getProperty("user.dir"));
curDir = new File(curDir, "subdir").getCanonicalFile();
URL[] urls = { curDir.toURI().toURL() };
ClassLoader cl = new URLClassLoader(urls);
Class<?> main = Class.forName("TheRealMainClass", true, cl);
Method mth = main.getMethod("main", args.getClass());
mth.invoke(null, (Object[]) args);
}
}
Just for the record, this runs, but gets an exception. I'm not sure
100% why. I'll try to clean it up then make it use your method. The
code below must be executed as a jar file or it won't reproduce the error.
$ java -jar test.jar
String name: /fubar/MyClassLoader.class
URL:
jar:file:/C:/Users/Brenden/Dev/misc/fubar/build/classes/test.jar!/fubar/MyClassLoader.class
path to jar file:/C:/Users/Brenden/Dev/misc/fubar/build/classes/test.jar
making FubarLoader:
Classloader: fubar.FubarLoader@addbf1
finding fubar.Launcher
trying super class...
findClass got it
Exception in thread "main" java.lang.IllegalAccessException: Class
fubar.MyClass
Loader can not access a member of class fubar.Launcher with modifiers ""
at sun.reflect.Reflection.ensureMemberAccess(Unknown Source)
at java.lang.Class.newInstance0(Unknown Source)
at java.lang.Class.newInstance(Unknown Source)
at fubar.MyClassLoader.main(MyClassLoader.java:53)
/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
package fubar;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLClassLoader;
public class MyClassLoader
{
public static void main( String... args )
throws ClassNotFoundException, InstantiationException,
IllegalAccessException, MalformedURLException
{
URL[] urls = new URL[1];
String classResource = "/" +
MyClassLoader.class.getName().replaceAll( "\\.", "/" )
+ ".class";
System.out.println( "String name: " + classResource );
URL myClass =
MyClassLoader.class.getResource( classResource );
System.out.println( "URL: " + myClass );
String pathToClass = myClass.toString();
int index = pathToClass.indexOf( '!' );
pathToClass = pathToClass.substring( 4, index );
System.out.println( "path to jar " + pathToClass );
URL jarURL = new URL( pathToClass );
urls[0] = jarURL;
System.out.println( "making FubarLoader:" );
URLClassLoader cl = new FubarLoader( urls );
System.out.println( "Classloader: " + cl );
@SuppressWarnings( "unchecked" )
Class<Launcher> main = (Class<Launcher>) cl.loadClass(
"fubar.Launcher" );
Launcher mcl = main.newInstance();
mcl.launch();
}
private void startApplication( Class<?> c )
{
System.out.println( "Class files are equal: " + (c ==
MyClassLoader.class) );
System.out.println( "Classloader: " + getClass().
getClassLoader() );
// everything else here
}
}
class Launcher
{
public void launch()
{
System.out.println( "Classloader: " + getClass().
getClassLoader() );
}
}
/*
* classloader call trace:
*
* I. loadClass( String )
*
* II. loadClass( String, false )
* 3. findLoadedClass prot
* A. FindLoadClass0 -- native -- PRIVATE
* 4. loadClass (String) on parent
* 5. findBootstrapClass0 PRIVATE
* 6. findClass prot
* 7. resolveClass prot
* A. resolveClass -- native -- PRIVATE
*
*/
class FubarLoader extends URLClassLoader {
public FubarLoader( URL[] urls )
{
super( urls );
}
@Override
public Class<?> loadClass( String className )
throws ClassNotFoundException
{
if( className.startsWith( "fubar" ) ) {
System.out.println( "finding " + className );
Class<?> c = null;
try {
c = findClass( className );
}
catch( ClassNotFoundException ex ) {
}
if( c != null ) {
System.out.println( "findClass got it" );
return c;
}
}
System.out.println( "trying super class..." );
return super.loadClass( className );
}
}