System.getProperty("java.class.path") does not reflect
changes made in DrJava's Extra Classpath.
I can add or remove directories and jar files, but
System.getProperty("java.class.path") remains the
same: <DrJava's jar>;<JDL's tools.jar>.
This is the case both when I examine System.getProperty
("java.class.path") in the interactions pane directly and
when I execute it within a program.
Logged In: YES
user_id=430590
This is not a bug. The standard class loader uses the value
of property java.class.path at the time the JVM is started.
Changing the value of this property has NO EFFECT on class
loading. DrJava uses a custom class loader to support the
dynamic modification of the class path. It is not clear to
me that changing the value of java.class.path to reflect the
behavior of the DrJava class loader is a good idea. I need
to hear arguments why updating the value of this property is
the "right thing" to do. I guess it makes it very easy to
determine the current class path. Simply type:
System.getProperty("java.lang.classpath")
in the interactions pane. But we already provide a command
in the Tools menu for this purpose. Is there any other
reason why we should modify the value of the
java.lang.classpath property? If a user manages to use the
default class loader within the interactions pane, they will
see a different class path than what the java.lang.classpath
property reports. Is this even possible? Is there anyway
for the user to get access to the default class loader?
I don't understand why this property is mutable in the JVM
since changing it has utterly no effect on any subsequent
computation (other than getting the value of the
java.class.path property. But if we can guarantee that the
user cannot access the default class loade then perhaps it
makes sense to update this property when we extend the
effective class path used by our custom class loader.
Logged In: YES
user_id=697810
Just a note, Dr. Cartwright made a couple of small typos
(substituted "java.lang.classpath" for "java.class.path").
Other than that, I would argue that this is in fact the
wrong thing to do. If we change the system property
"java.class.path" the user might mistakenly believe that
using the default class loader will be able to load the
classes that are dynamically available to our class loader.
It is also impossible to prevent a user from accessing the
default class loader: the static method
java.lang.Class.forName(String) will always use the default
class loader to load the requested class.
I have two suggestions, which the submitter of this report
could comment on. First, we could add a separate system
property, maybe "drjava.class.path" or something similar to
indicate the current DrJava classpath, perhaps for use in
someone's own custom class loader. However, it seems a bit
silly to tailor such custom code to the interactions pane.
The other option I can think of, which probably makes more
sense, would be to set the system classpath of the
interpreter JVM to the current DrJava classpath on a reset.
I'm not sure how feasible this is; however, it would make
sense in most situations, and would (after a reset) provide
access by the system classloader to at least the entries in
the "Extra Classpath" option, if not to all the most
recently opened files. Since the classpath never becomes
smaller (except at a reset), I can't think of any problems
this would cause.
Logged In: YES
user_id=1060117
Originator: NO
Recategorizing as a feature request.
It's an interesting idea. To avoid confusion, I think we must maintain the invariant that "ClassLoader.getSystemClassLoader()" returns a loader consistent with "System.getProperty("java.class.path")".
The problem with actually changing the application class path for the interpreter JVM is that there's an inherent conflict between the meta-language class path and the interpreted language class path: if a user defines a class that has a name clash with one of the interpreter's implementation classes (this occurs when editing the DynamicJava code or its dependencies in DrJava), how should we resolve the clash? In the meta-language (the JVM's system class path), the user's class must not shadow the implementation classes -- allowing that would allow users to arbitrarily change the interpreter's behavior. On the other hand, if the interpreted language's class path allows the user's classes to be shadowed, the user can't any longer see his own code. As a result, the two class paths -- meta an interpreted -- must be distinct.
So the other option is to modify the behavior of ClassLoader.getSystemClassLoader() so it returns a "system class loader" for the interpreted language, not the metalanguage. This is along the lines of other requests to make Class.forName() work as in compiled code. Going down that path -- trying to modify the behavior of library code to maintain the illusion that expressions in the interpreter are first-class, compiled code -- feels like opening a Pandora's box; but maybe it's reasonable in a few especially useful cases.