Discussion:
[Beanshell-users] Controlling class loading
Tomasz Kowaltowski
2003-09-30 09:20:02 UTC
Permalink
I am a newcomer to BeanShell but I want to use it for scripting in an
application written in Java. I would appreciate an explanation about how
to prevent a BeanShell script from loading certain Java classes. Since
I am not an expert on Java either a simple example would be appreciated.

Thanks,

-- Tomasz Kowaltowski
Mike Baranczak
2003-09-30 11:35:07 UTC
Permalink
The way I did it before, was to subclass bsh.NameSpace, and then make
sure that all the Interpreter objects that were created used my
restricted namespace.

public class ThingNameSpace extends bsh.NameSpace {
public ThingNameSpace(NameSpace parent, String name) {
super(parent, name);
}

public ThingNameSpace(String name) {
super(name);
}

// snip //

/** Over-rides method in bsh.NameSpace. Only loads the requested
class if it's on the allowed list. */
public Class getClass(String str) throws bsh.ClassPathException {
Class c = super.getClass(str);
if (c == null)
return c;
String cName = c.getName();
// namesAllowed is a Vector containing the class names that may be
loaded. You can also do it the other way,
// and only specify which classes AREN'T allowed.
if (namesAllowed.contains( cName ))
return c;
else
throw new
ClassPathException("com.optimizer.data.ThingNameSpace can't load class:
" + cName);
}
}
Post by Tomasz Kowaltowski
I am a newcomer to BeanShell but I want to use it for scripting in an
application written in Java. I would appreciate an explanation about
how to prevent a BeanShell script from loading certain Java classes.
Since I am not an expert on Java either a simple example would be
appreciated.
Thanks,
-- Tomasz Kowaltowski
-------------------------------------------------------
This sf.net email is sponsored by:ThinkGeek
Welcome to geek heaven.
http://thinkgeek.com/sf
_______________________________________________
Beanshell-users mailing list
https://lists.sourceforge.net/lists/listinfo/beanshell-users
Tomasz Kowaltowski
2003-11-09 09:25:27 UTC
Permalink
I have a Java application which is loaded by a customized class loader.
One of the classes looks like:

----------------------------------------------
public class Global {
private static int global = 1000;
public static int getGlobal() {return global;}
public static void setGlobal(int k) {global=k;}
}
----------------------------------------------

Within the application I call a Beanshell which looks like:

-----------------------------
import global.*;
print getGlobal();
-----------------------------

(Notice that the Beanshell interpreter is also loaded by my customized
loader.)

My problem is that every time I execute the script it loads a new
version of the class "Global", without going through my class loader
(the same initial value 1000 appears even though it was modified). I
tried to use "interpreter.setClassLoader(myLoader)", but it did not make
any difference.

Running the application without using my loader everything works fine.

I did a similar test with another scripting language (Jython) and it
worked properly with and without the customized class loader.

Any hints will be appreciated.

-- Tomasz Kowaltowski

Shankar Unni
2003-09-30 11:48:13 UTC
Permalink
I would appreciate an explanation about how to prevent
a BeanShell script from loading certain Java classes.
I'm afraid you'll have to be a lot more precise about the requirement than
that.

If the goal is to make sure that that class can never be loaded into your
program under any circumstances (e.g. you want to make darned sure that no
graphics classes are ever loaded, because you know you don't have a
display), then the best way is to create a SecurityManager that explicitly
disallows access to whatever classes you want to disallow loading.

If you simply want your entire program, including your BeanShell objects, to
suffer from this restriction, this can be as simple as specifying an
appropriate "java.policy" file on the command line (java
-Djava.policy=/path/to/your/java.policy ...). Read the Java documentation
for the format of java.policy.

If you want more fine-grained access (i.e. you'd like your program itself to
be able to access java.awt.Frame, but not your scripts), then you'll have to
create a custom ProtectionDomain (and certainly load BeanShell using a
separate class loader), and at this point I'm stepping into deep waters and
need help myself :-/..
--
Shankar.
Tomasz Kowaltowski
2003-10-03 15:21:05 UTC
Permalink
Post by Shankar Unni
I'm afraid you'll have to be a lot more precise about the requirement than
that.
[...]
If you want more fine-grained access (i.e. you'd like your program itself to
be able to access java.awt.Frame, but not your scripts), then you'll have to
create a custom ProtectionDomain (and certainly load BeanShell using a
separate class loader), and at this point I'm stepping into deep waters and
need help myself :-/..
--
Shankar.
What I am trying to do is to prevent any script interpreted by the
BeanShell interpreter from loading any existing precompiled classes of
my system, i.e, "*.class" files. Loading source "*.java" files is OK. I
read the documentation and looked at the BeanShell source files and
tried the following solution (all source files are at the end of this
message):

(1) declared my own class loader which (for testing purposes) blocks any
loading;

(2) in my main program I set this class loader into the interpreter, and
then tried the execution of a very simple example of a (pure Java)
script SimpleClass.

(3) I tested my program with and without SimpleClass.class file present.
Without, the source version was loaded, with the interpreter printing,
as expected: "Loading class from source file: /SimpleClass.java".

With the SimpleClass.class present (with or without SimpleClass.java),
it was also loaded but without this message. It seems that the loader
ignored my "setClassLoader(new ClassLoaderNone());" statement :-(.

Any hints will be appreciated.

-- Tomasz

------------------------------------------------------
import bsh.*;
public class Test {
public static void main(String[] args) throws Exception {
Interpreter bi = new bsh.Interpreter();
bi.setClassLoader(new ClassLoaderNone());
SimpleInterface sc =
(SimpleInterface)(bi.eval("new SimpleClass()"));
System.out.println(sc.countParams(new String[]{}));
System.out.println(sc.countParams(new
String[]{"abc","123","def"}));

}
}
------------------------------------------
public class ClassLoaderNone extends ClassLoader {
public Class loadClass(String name) throws
ClassNotFoundException {
return this.loadClass(name,false);
}

public Class loadClass(String name, boolean resolve) throws
ClassNotFoundException {
throw new ClassNotFoundException();
}
}
------------------------------------------
public interface SimpleInterface {
public int countParams(String[] params);
}
-------------------------------------------
public class SimpleClass implements SimpleInterface {
public int countParams(String[] params) {
return params.length;
}
}
---------------------------------------------
Shankar Unni
2003-10-03 16:20:05 UTC
Permalink
I've found that a useful trick is to create your classloader, and then use
that to load the bsh classes too (so that their own classloader is your
classloader).

I.e. do

Class interpClass = yourClassLoader.loadClass("bsh.Interpreter");

And then do a newInstance() and call eval() by reflection.
-----Original Message-----
Behalf Of Tomasz Kowaltowski
Sent: Friday, October 03, 2003 10:20 AM
Subject: Re: [Beanshell-users] Controlling class loading
Post by Shankar Unni
I'm afraid you'll have to be a lot more precise about the
requirement
than
Post by Shankar Unni
that.
[...]
If you want more fine-grained access (i.e. you'd like your program
itself to
Post by Shankar Unni
be able to access java.awt.Frame, but not your scripts),
then you'll
have to
Post by Shankar Unni
create a custom ProtectionDomain (and certainly load
BeanShell using a > separate class loader), and at this
point I'm stepping into deep
waters and
Post by Shankar Unni
need help myself :-/..
--
Shankar.
What I am trying to do is to prevent any script interpreted by the
BeanShell interpreter from loading any existing precompiled
classes of
my system, i.e, "*.class" files. Loading source "*.java"
files is OK. I
read the documentation and looked at the BeanShell source files and
tried the following solution (all source files are at the end of this
(1) declared my own class loader which (for testing purposes)
blocks any
loading;
(2) in my main program I set this class loader into the
interpreter, and
then tried the execution of a very simple example of a (pure Java)
script SimpleClass.
(3) I tested my program with and without SimpleClass.class
file present.
Without, the source version was loaded, with the interpreter
printing,
as expected: "Loading class from source file: /SimpleClass.java".
With the SimpleClass.class present (with or without
SimpleClass.java),
it was also loaded but without this message. It seems that the loader
ignored my "setClassLoader(new ClassLoaderNone());" statement :-(.
Any hints will be appreciated.
-- Tomasz
------------------------------------------------------
import bsh.*;
public class Test {
public static void main(String[] args) throws Exception {
Interpreter bi = new bsh.Interpreter();
bi.setClassLoader(new ClassLoaderNone());
SimpleInterface sc =
(SimpleInterface)(bi.eval("new SimpleClass()"));
System.out.println(sc.countParams(new String[]{}));
System.out.println(sc.countParams(new
String[]{"abc","123","def"}));
}
}
------------------------------------------
public class ClassLoaderNone extends ClassLoader {
public Class loadClass(String name) throws
ClassNotFoundException {
return this.loadClass(name,false);
}
public Class loadClass(String name, boolean resolve) throws
ClassNotFoundException {
throw new ClassNotFoundException();
}
}
------------------------------------------
public interface SimpleInterface {
public int countParams(String[] params);
}
-------------------------------------------
public class SimpleClass implements SimpleInterface {
public int countParams(String[] params) {
return params.length;
}
}
---------------------------------------------
-------------------------------------------------------
This sf.net email is sponsored by:ThinkGeek
Welcome to geek heaven.
http://thinkgeek.com/sf
_______________________________________________
https://lists.sourceforge.net/lists/listinfo/beanshell-users
Loading...