[Beanshell-dev] Report from JavaOne...

[Beanshell-dev] Report from JavaOne...

It's been an exciting JavaOne for BeanShell.

- Graham Hamilton announced at the keynote that we should have
BeanShell in Dolphin, the Java 1.7 release.

- Last night we had the BeanShell BOF. I think it was very
successful, though we didn't have nearly enough time to cover all of
the material and get feedback. We'll have to schedule more for next
year.

- I'm running into more and more vendors on the convention floor who
are using BeanShell in their products.

Looking forward to hearing from those of you who attended the
conference and got feedback on the project.

[Beanshell-dev] Distributed BeanShell Question

team,

i have developed a test automation
tool that essentially allows one BeanShell interpreter to call another
remote instance and request that it run a script. i presently subclass
the interpreter and use Object Serialization to send the request. on the
other side i unpack the request, spawn the interpreter, buffer the response,
and send it back. works nicely. i recently extended it to allow it to execute
BeanShell commands on the other side, rather than scripts (after all commands
are really just scripts anyway). i developed a hokey mechanism for doing
this:

1) send the command name over along
with a hashmap of the named arguments

2) set this variable names equal to
the values in the remote interpreter

3) dynamically build the method call
signature and execute it

i.e.

set x = 1;set y=2;

eval("foo(x, y););

it works, but there must be a more eleant
way to accomplish this. can anyone chime in if something more intellegent
comes to mind? i am an engineer in pursuit of excellence who is sometimes
poorly equipt :)

best regards all,

mp

here is my class. it has some unrelated
stuff in it, so please ignore that:

/* * Copyright (C) 2002 by Michael
Pitoniak ([hidden email]). * * This program is free software;
you can redistribute it and/or * modify it under the terms of
the GNU General Public License * as published by the Free Software
Foundation; either version 2 * of the License, or (at your
option) any later version. * * This program is distributed
in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without
even the implied warranty of * MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE. See the * GNU General Public License for
more details. * * You should have received a copy
of the GNU General Public License * along with this program; if
not, write to: * * The Free Software Foundation,
Inc., * 59 Temple Place - Suite
330 * Boston, MA 02111-1307 * USA */

case INITIALIZE:
initialize();
state = EVAL_CMD;
break;
case EVAL_CMD:
evalCMD(m_BeanShellCMD);
state = SCRIPT_COMPLETE;
break;
default:
writeError(ClassServices.getCurrentMethodName()
+ "Illegal State Machine State");
state = SCRIPT_COMPLETE;
}
} }catch(Error
error){
/*If any ThreadDeath Errors slip past we get them here before EventQue
An instance of ThreadDeath is thrown in the victim thread when the stop
method with zero arguments in class Thread is called. An application
should catch instances of this class only if it must clean up after being
terminated asynchronously. If ThreadDeath is caught by a method, it is
important that it be rethrown so that the thread actually dies.
The top-level error handler does not print out a message if ThreadDeath
is never caught. The class ThreadDeath is specifically a subclass of
Error rather than Exception, even though it is a "normal occurrence",
because many applications catch all occurrences of Exception and then
discard the exception.*/
writeError(ClassServices.getCurrentMethodName() + error);
writeError(error.getStackTrace()); }catch(Exception
e){
writeError(ClassServices.getCurrentMethodName(), e); }finally{
//ScriptManager tracks timeout if we never get here
if(m_BooleanLock != null){
m_BooleanLock.setValue(true);
}
//set System.out and System,.err back before
//exiting because Redicted Streams are persistent
cleanUp(); } } //If this fails we throw
an Exception and stop state machine protected void initialize()
throws Exception{ //reset
output buffers on each script execution try{
m_BooleanLock = new BooleanLock();
m_InetAddrName = InetAddress.getLocalHost().getHostName();
if(m_InetAddrName == null){
m_InetAddrName = "REMOTE";
}
//Set name for ThreadViewer Local/Remote Identification
if(m_RemoteParserInterface instanceof TestPanelInterface){
this.setName(ClassServices.getClassNameNoPackage(this.getClass().getName()));
}else{
this.setName("REMOTE_" + ClassServices.getClassNameNoPackage(this.getClass().getName()));
} }catch(Exception
e){
writeError(ClassServices.getCurrentMethodName(), e);
throw e; } }

/* Note: Additional local
namespace variables are initialized by * BeanShellInterptererThread.initializeBshInterpreterNameSpace() * Any additional
variables that need to be loaded by a script * can be achieved
by just sourcing a file with varables * defined in it.
That file should follow java syntax. * * If this fails
it throws an Exception and stops State Machine */ public void loadScriptArgs(Object
args) throws Exception{ m_BeanShellInterptererThread2.loadScriptArgs(args); } /* * NOTE: There are
multiple instances of bsh classes in the jar file mounts. Test Harness * BeanShell support
will not work unless the latest beanshell jar is found first. * The order in which
directories and archives appear in the Filesystems tabbed pane * can affect the
running and debugging of sources in the IDE. For example, if you have * Java files with
identical class and package names in different mounted filesystems, * the file in the
first mounted filesystem is always loaded during execution and debugging. * This happens even
if you have select the second class before calling the command. * To change the
order of mounted filesystems: * In the Explorer,
right-click the root Filesystems ( ) node and choose Customize. * Right-click the
Filesystems Settings node. Choose Change Order from the contextual menu. * In the Change
Order dialog box, select the filesystem you want to move. * Click the Move
Up button or the Move Down button to change the position * of the filesystem
relative to the other filesystems. */ //TODO this must be public
because intrinsics call it....fix that public void evalCMD(String
bshCmd){ try{
//build the bsh cmd to
evaluate
boolean bFirst = true;
StringBuffer bshCmdBuffer = new StringBuffer();
bshCmdBuffer.append(bshCmd + "(");

/* * By setting Interpreter's
parser and interpreter variables to null * when the Parser
completes, or times out, we insure that any script * spawned threads
that try to access the parser's methods after the * script completes,
or is stopped; will throw an exception and exit. * This prevents
unwanted Script spawned Threads executing after the * RemoteClient session
exits. * * Called at end
of ScriptManager.scriptStateMachine() * * */ public void disableParser(){ try{
m_BeanShellInterptererThread2.setInterpreterVar("parser", null);
m_BeanShellInterptererThread2.setInterpreterVar("interpreter",
null); }catch(Exception
e){
e.printStackTrace(); } } /* This method is Overridden
in derived subclasses to perform any parser * specific cleanup
required by that class. This is very usefull as "any" * syntax error in
a script will cause the beanshell interpreter to exit * without executing
any catch or finally in the script. This method ends * up being the only
way to implement finally() for the interpreter. */ protected void cleanUp(){ //override
for specific cleanup needs } /* This method is used
to initialize BeanShellInterpreter local varaibles " * before" scriptexecution. **/ public void setVariableValue(String
var, Object val){ try{
m_BeanShellInterptererThread2.setInterpreterVar(var, val); }catch(Exception
e){
writeError(ClassServices.getCurrentMethodName(), e); } }

//TODO can we consolidate
setVariableValue and this?? public void addResponseVar(String
var, Object value){ m_ResponseHashMap.put(var,
value); } //TODO deprecate? public void addResponseHashMap(HashMap
hashMap){ m_ResponseHashMap
= hashMap; } /*Scripts pass varaibles
back to RemoteClient Matser via addResponseVar() * ExecRemoteScriptRequest
constructs an ExecRemoteScriptResponse, and calls * getResponseHashMap()
to get the HashMap to pass back */ public HashMap getResponseHashMap(){ return m_ResponseHashMap; } //getParserStopped() is
used by scripts to determine in parser has been halted public boolean getParserStopped()
{ &n