javaclassloaderbeanshelldynamic-class-loadersgroovyclassloader

Beanshell will not allow me to add jars to the "default" JRE classloader?


I have a question about Beanshell that I can't find an answer to anywhere. I am only able to run Beanshell scripts in 1 of 2 ways:

  1. Where Classpath is defined before invoking Beanshell and Beanshell uses the JRE default classloader.

  2. Where no classpath is defined at all before starting Beanshell and then I use addClassPath() and importCommands() to dynamically build the classpath within Beanshell's classloader. This method does not seem to inherit a jars that were part of the default JRE classloader.

After much experimentation, I have learned that I am unable to start a script with a pre-defined Classpath and then be able to add to the classpath by using addClassPath(). I don't know if this is as-designed or if I am doing something wrong?

It is very easy to see for yourself what my problem is. For example, here is the script:

::Test.bat (where bsh.jar exists in JRE/lib/ext directory)
@echo off
set JAVA_HOME=C:\JDK1.6.0_27
:: first invoke:  this first command works
%JAVA_HOME%\jre\bin\java.exe bsh.Interpreter Test.bsh
:: second invoke: this command fails
%JAVA_HOME%\jre\bin\java.exe -cp ant.jar bsh.Interpreter Test.bsh

The second invoke causes this error:

Evaluation Error: Sourced file: Test.bsh : Command not 
found: helloWorld() : at Line: 5 : in file: Test.bsh : helloWorld ( )

Test.bat launches this Beanshell script:

// Test.bsh
System.out.println("Trying to load commands at: " + "bin" );
addClassPath("bin");  
importCommands("bin");
helloWorld();

And, this is my helloWorld.bsh script:

// File: helloWorld.bsh
helloWorld() { 
    System.out.println("Hello World!");
}

Solution

  • Your Test.bsh has a slight error: importCommands looks for a directory called "bin" in the class path and loads all .bsh files from there, so what you should add to addClassPath is the current directory:

    // Test.bsh
    System.out.println("Trying to load commands at: " + "bin" );
    addClassPath(".");  // current directory
    importCommands("bin");
    helloWorld();
    

    The code you had works in the first case because the current directory is in the default system class path. The problem is that the -cp switch overrides the default class path, so importCommands no longer has any way to find the bin directory.

    Alternatively you can add . to the classpath on the JVM level:

    %JAVA_HOME%\jre\bin\java.exe -cp .;ant.jar bsh.Interpreter Test.bsh