ClassLoader

D

daniel.w.gelder

I'd like to take a stab at implementing one of my favorite scripting
languages. Instead of writing an interpreter, I'd like to just use
Java's compiler, by translating script into Java. Is it possible to
just use ClassLoader as in this psuedocode, or am I smoking too much of
the weed?

// define a type of object that does work

abstract class RunSomeCode {
public runItNow();
}

// confect some code that I made by translating some script on the fly

static String codeToLoad = "public class Hello implements RunSomeCode {
public runItNow() { System.out.println('Hello World')";

// open the confected code

RunSomeCode myCrazyClass = new ClassLoader() {
public findClass() { return codeToLoad; }
}

// call the code

myCrazyClass.runItNow();
 
H

Heiner Kücker

(e-mail address removed)
I'd like to take a stab at implementing one of my favorite scripting
languages. Instead of writing an interpreter, I'd like to just use
Java's compiler, by translating script into Java. Is it possible to
just use ClassLoader as in this psuedocode, or am I smoking too much of
the weed?

// define a type of object that does work

abstract class RunSomeCode {
public runItNow();
}

// confect some code that I made by translating some script on the fly

static String codeToLoad = "public class Hello implements RunSomeCode {
public runItNow() { System.out.println('Hello World')";

You have to compile the given code

Try
http://jakarta.apache.org/commons/sandbox/jci/

You need a Technoligie like Tomcat JSP Compiler
(Jasper).
// open the confected code

RunSomeCode myCrazyClass = new ClassLoader() {
public findClass() { return codeToLoad; }
}

// call the code

myCrazyClass.runItNow();

For Java 6 (Mustang) is a default interface
to the compiler scheduled.
 
D

daniel.w.gelder

I looked at that. It might be simpler to just run javac from the
command line.

I hardly need any java features in my language, so perhaps I should
look into writing my own bytecode compiler.

If I do put together a block of memory that is in the .class format,
can I load it in an applet?
 
R

Roedy Green

If I do put together a block of memory that is in the .class format,
can I load it in an applet?

You just write a classloader that takes the ram image of the class.
see http://mindprod.com/jgloss/jasm.html

It is even simpler than a standard class loader since it does not need
to do any looking or i/o to get the class file image.
 
M

Mandar Amdekar

Haven't thought about compiling and loading Java sources at runtime
using a custom ClassLoader, but I have certainly written custom
classloaders to load class files from a filesystem, JAR, or from a
directory on the filesystem (looking for all JARs, files etc.).

Makes for a pretty good customization / plugin mechanism.
 
C

castillo.bryan

Roedy said:
You just write a classloader that takes the ram image of the class.
see http://mindprod.com/jgloss/jasm.html

It is even simpler than a standard class loader since it does not need
to do any looking or i/o to get the class file image.

The link to mindprod.com says you can use defineClass on
java.lang.ClassLoader, but that method is protected. Did I read
something wrong somwhere? Or is the link saying you should call it
through reflection after calling method.setAccessible(true)? :)
 
R

Roedy Green

The link to mindprod.com says you can use defineClass on
java.lang.ClassLoader, but that method is protected. Did I read
something wrong somwhere? Or is the link saying you should call it
through reflection after calling method.setAccessible(true)? :)

Here is one I wrote a long time ago in the days of Netscape 4. The key
is to get at a protected method, you must extend its class. I found
this is my EXPER directory, so it is not production code, but a
prototype experiment. But it might be enough to give you the idea.


import java.io.File;
import java.io.InputStream;
import java.util.Hashtable;
import java.util.zip.ZipFile;

/**
* ClassLoader to let us find class files preinstalled in
*
C:\Program_Files\Netscape\Communicator\program\java\classes\pcclock.jar
*/

public class LocalClassLoader extends ClassLoader
{

private Hashtable cache = new Hashtable();

/**
* This is a simple version for external clients since they
* will always want the class resolved before it is returned
* to them.
*/
public Class loadClass(String className) throws
ClassNotFoundException {
return(loadClass(className, true));
}

/**
* get bytes for class from a specific jar file.
*/
private byte[] loadClassData(String name) throws
ClassNotFoundException{
String jarname =
"\\Program_Files\\Netscape\\Communicator\\program\\java\\classes\\pcclock.jar";
File jar = null;
InputStream is = null;
ZipFile zip = null;
try
{

jar = new File("C:" + jarname);
if ( !jar.exists() )
{
jar = new File("D:" + jarname);
}
if ( !jar.exists() )
{
throw new java.lang.ClassNotFoundException("missing jar "
+ jarname);
}

zip = new ZipFile(jar);
if ( zip == null )
{
throw new java.lang.ClassNotFoundException("corrupt jar "
+ jarname);
}
is = zip.getInputStream(zip.getEntry(name));
if ( is == null )
{
throw new java.lang.ClassNotFoundException("class " + name
+ " not found in jar " + jarname);
}
int bytesToRead = is.available();
byte[] b = new byte[bytesToRead];
int bytesRead = is.read(b);
if ( bytesRead != bytesToRead )
{
throw new java.lang.ClassNotFoundException("class " + name
+ " corrupt in jar " + jarname);
}
if ( is != null )
{
is.close();
}
if ( zip != null )
{
zip.close();
}

return b;

}
catch ( java.io.IOException e )
{
throw new java.lang.ClassNotFoundException("corrupt jar " +
jarname);
}
} // end loadClassData

/**
* load class from
*
C:\Program_Files\Netscape\Communicator\program\java\classes\pcclock.jar
* @param className fully qualified name of class to load.
* @param true if you want the class resolved, ready to use.
* @return class object.
*/
protected synchronized Class loadClass(String className,
boolean resolve)
throws ClassNotFoundException
{
Class c = (Class)cache.get(className);
if ( c == null )
{
/* Check with the primordial class loader */
try
{
c = super.findSystemClass(className);
}
catch ( ClassNotFoundException e )
{

}
if ( c == null )
{
// primordial did not have it, look in jar.
// loadClassData will throw ClassNotFoundException if it
does not have it.
byte[] data = loadClassData(className);
c = defineClass(data, 0, data.length);
cache.put(className, c);
}
}
if ( resolve )
{
// prepare class for use
resolveClass(c);
}
return c;
} //end loadClass

} // end LocalClassLoader
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,767
Messages
2,569,570
Members
45,045
Latest member
DRCM

Latest Threads

Top