IllegalAccessException on using newInstance()

Am trying to understand some concepts related to class loading but when I

try to executing the code below I get an IllegalAccessException. This

exception is thrown from the newInstance line. Any help in clearing this

would be great!

import java.io.*;

import java.lang.reflect.*;

publicclass MainLoaderextends ClassLoader{

public Class loadClass(String name)throws ClassNotFoundException{

if (name.startsWith("Loaded")){

return findClass(name);

}else{

return super.loadClass(name);

}

}

public Class findClass(String name)throws ClassNotFoundException{

try{

// we load the class from current directory

File f =new File(name.replace(".","/") +".class");

int len = (int) f.length();

byte[] buf =newbyte[len];

FileInputStream fis =new FileInputStream(f);

fis.read(buf);

System.out.println("Loading..." + name);

return defineClass(name, buf, 0, buf.length);

}catch (Exception exp){

thrownew ClassNotFoundException(exp.getMessage());

}

}

publicstaticvoid main(String[] args)throws Exception{

MainLoader loader =new MainLoader();

Class myLoad = loader.loadClass("LoadedClass");

Class appLoad = Class.forName("LoadedClass");

if(myLoad == appLoad)

System.out.println("They are equal");

else

System.out.println("They are not equal");

myLoad.newInstance();

System.out.println(myLoad.getClassLoader());

System.out.println(LoadedClass.class.getClassLoader());

System.out.println(appLoad.getClassLoader());

}

}

class LoadedClass{

String name;

int age;

LoadedChild lc;

LoadedClass(){

System.out.println("Empty ctor");

}

void setName(String s){

name = s;

}

String getName(){

return name;

}

void setAge(int age){

this.age = age;

}

int getAge(){

return this.age;

}

}

class LoadedChild{

String address;

void setAddress(String s){

address = s;

}

String getAddress(){

return address;

}

}

[4803 byte] By [krishy5a] at [2007-11-26 17:30:17]
# 1
Hi,I'm using 1.6.0-b105 JVM version and i don't ave any Exception.Can you please, post the stack trace and JVM version .Laurent.
lbaudeta at 2007-7-8 23:58:14 > top of Java-index,Core,Core APIs...
# 2

the Constructor isn't accessible, probably for some obscure security reason. there's a workaround:

package my.pkg;

import java.io.*;

import java.lang.reflect.*;

public class MainLoader extends ClassLoader{

public Class loadClass(String name) throws ClassNotFoundException {

if (name.startsWith("Loaded")) {

return findClass(name);

} else {

return super.loadClass(name);

}

}

public Class findClass(String name) throws ClassNotFoundException {

try {

// we load the class from current directory

File f = new File(name.replace(".", "/") + ".class");

int len = (int) f.length();

byte[] buf = new byte[len];

FileInputStream fis = new FileInputStream(f);

fis.read(buf);

System.out.println("Loading..." + name);

return defineClass(name, buf, 0, buf.length);

} catch (Exception exp) {

throw new ClassNotFoundException(exp.getMessage());

}

}

public static void main(String[] args) throws Exception {

MainLoader loader = new MainLoader();

Class myLoad = loader.loadClass("LoadedClass");

Class appLoad = Class.forName("LoadedClass");

if(myLoad == appLoad)

System.out.println("They are equal");

else

System.out.println("They are not equal");

// here I'm using the Constructor instead of the class

// and making it accessible, since that's the problem

Constructor con = myLoad.getConstructor(new Class[0]);

con.setAccessible(true);

con.newInstance();

// myLoad.newInstance();

System.out.println(myLoad.getClassLoader());

System.out.println(LoadedClass.class.getClassLoader());

System.out.println(appLoad.getClassLoader());

}

}

class LoadedClass{

String name;

int age;

LoadedChild lc;

public LoadedClass(){

System.out.println("Empty ctor");

}

void setName(String s){

name = s;

}

String getName(){

return name;

}

void setAge(int age){

this.age = age;

}

int getAge(){

return this.age;

}

}

class LoadedChild{

String address;

void setAddress(String s){

address = s;

}

String getAddress(){

return address;

}

}

notice I've instantiated using a Constructor, rather than the class object, and set it to be accessible, first

georgemca at 2007-7-8 23:58:14 > top of Java-index,Core,Core APIs...
# 3

> Hi,

>

> I'm using 1.6.0-b105 JVM version and i don't ave any

> Exception.

>

> Can you please, post the stack trace and JVM version

Here they are...

C:\Java>java MainLoader

Loading...LoadedClass

They are not equal

Exception in thread "main" java.lang.IllegalAccessException: Class MainLoader can not access a member of class LoadedClass with modifiers ""at sun.reflect.Reflection.ensureMemberAccess(Unknown Source)

at java.lang.Class.newInstance0(Unknown Source)

at java.lang.Class.newInstance(Unknown Source)

at MainLoader.main(MainLoader.java:38)

C:\Java>java -version

java version "1.5.0_10"

Java(TM) 2 Runtime Environment, Standard Edition (build 1.5.0_10-b03)

Java HotSpot(TM) Client VM (build 1.5.0_10-b03, mixed mode, sharing)

Thanks for the effort!

krishy5a at 2007-7-8 23:58:14 > top of Java-index,Core,Core APIs...
# 4

> notice I've instantiated using a Constructor, rather

> than the class object, and set it to be accessible,

> first

For some reason I cannot understand this is what happens when I try

using the ctor approach:

C:\Java>java MainLoader

Loading...LoadedClass

They are not equal

Exception in thread "main" java.lang.NoSuchMethodException: LoadedClass.<init>()

at java.lang.Class.getConstructor0(Unknown Source)

at java.lang.Class.getConstructor(Unknown Source)

at MainLoader.main(MainLoader.java:39)

krishy5a at 2007-7-8 23:58:14 > top of Java-index,Core,Core APIs...
# 5

> > notice I've instantiated using a Constructor,

> rather

> > than the class object, and set it to be

> accessible,

> > first

>

> For some reason I cannot understand this is what

> happens when I try

> using the ctor approach:

> [code]

> C:\Java>java MainLoader

> Loading...LoadedClass

> They are not equal

> Exception in thread "main"

> java.lang.NoSuchMethodException:

> LoadedClass.<init>()

> at java.lang.Class.getConstructor0(Unknown

> Source)

> at java.lang.Class.getConstructor(Unknown

> Source)

>at MainLoader.main(MainLoader.java:39)

it's looking for a constructor that doesn't exist, by the look of it. are you running the exact code I posted, or have you adapted it to your real project? could be the actual class doesn't have a default, no-args constructor

georgemca at 2007-7-8 23:58:14 > top of Java-index,Core,Core APIs...
# 6
Sorry, didn't notice that you have changed the access of the ctor to public!Did that and it works now. Any clue to finding the reasons why newInstance()doesn't work? What are the security restrictions that could be coming in the way?Thanks for the help.
krishy5a at 2007-7-8 23:58:14 > top of Java-index,Core,Core APIs...
# 7
not really given it too much thought, to be honest, just worked around it! possibly a bug, given the above poster's experience, but unlikely. I also thought it was down to using the default package, but it's not. I bet there's a really simple explanation I'm missing....
georgemca at 2007-7-8 23:58:14 > top of Java-index,Core,Core APIs...
# 8
newInstance didn't work because the constructor wasn't public. Just as new XXX() wouldn't have worked either. Same rules.
ejpa at 2007-7-8 23:58:14 > top of Java-index,Core,Core APIs...
# 9
> newInstance didn't work because the constructor> wasn't public. Just as new XXX() wouldn't have worked> either. Same rules.Actually, new LoadedClass() works fine. It's just the newInstance() that doesn't.
krishy5a at 2007-7-8 23:58:14 > top of Java-index,Core,Core APIs...
# 10
Hmm, newInstance() seems to require the constructor to be public.
ejpa at 2007-7-8 23:58:14 > top of Java-index,Core,Core APIs...
# 11
> Hmm, newInstance() seems to require the constructor> to be public.it's odder than that. even declaring the constructor as public doesn't stop the exception. no idea why, but I've got a nagging feeling theres something blindingly obvious I'm missing.....
georgemca at 2007-7-8 23:58:14 > top of Java-index,Core,Core APIs...
# 12

> Hmm, newInstance() seems to require the constructor

> to be public.

Not really. Having the ctor public seems to have no effect. If the it is

public this is the error I get:

Exception in thread "main" java.lang.IllegalAccessException: Class MainLoader can not access a member of class LoadedClass with modifiers "public"

at sun.reflect.Reflection.ensureMemberAccess(Reflection.java:65)

at java.lang.Class.newInstance0(Class.java:344)

at java.lang.Class.newInstance(Class.java:303)

at MainLoader.main(MainLoader.java:38)

krishy5a at 2007-7-8 23:58:14 > top of Java-index,Core,Core APIs...
# 13
after some playing around, I've come to the conclusion that it's because the classes in question are in the default package
georgemca at 2007-7-8 23:58:14 > top of Java-index,Core,Core APIs...