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.
# 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
# 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!
# 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)
# 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
# 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.
# 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....
# 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 >

# 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.
# 10
Hmm, newInstance() seems to require the constructor to be public.
ejpa at 2007-7-8 23:58:14 >

# 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.....
# 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)
# 13
after some playing around, I've come to the conclusion that it's because the classes in question are in the default package