Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Beanshell in Ant yielding, "Unable to create javax script engine for beanshell"

Greeting, I'm trying to put some Beanshell script in my Ant build.xml file. I've followed the Ant manual as well as I can but I keep getting "Unable to create javax script engine for beanshell" when I run Ant. Here is the test target I wrote mostly from examples in the Ant manual:

<target name="test-target">
    <script language="beanshell" setbeans="true">
        <classpath>
            <fileset dir="c:\TEMP" includes="*.jar" />
        </classpath>
        System.out.println("Hello world");
    </script>
</target>

My beanshell "bsh-2.0b4.jar" file is on the script task's classpath the way the manual recommended. Hope I have the right file. I'm working in c:\TEMP right now. I've been googling and trying for a while now. Any ideas would be greatly appreciated. Thanks.

like image 579
Vimes Avatar asked Apr 26 '10 20:04

Vimes


3 Answers

First, you need jsr-engines.zip from here:

https://scripting.dev.java.net/servlets/ProjectDocumentList

Inside, you'll find jsr223/beanshell/build/bsh-engine.jar. Some searching implied that you need to download bsh-2.05b.jar. I found it here:

http://beanshell.org/bsh-2.0b5.jar

The more easily findable bsh-2.0b4.jar also seemed to work, but it printed a message that implied it was experimental.

like image 103
Brett Kail Avatar answered Oct 06 '22 01:10

Brett Kail


Currently (2012) you need only 1 jar to fire the script task for BeanShell:

  • bsh-2.0b5.jar

Previously I also thought of the following, as mentioned by Ant Manual, Library Dependencies chapter:

  • bsf-2.4.0.jar
  • commons-logging-api-1.1.jar

But it looks like bsf is not needed for bsh, at least in my environment.

Once the jar is given to ant, the script task runs smoothly. There are 2 possible scenarios for getting the jars and making them available to ant.

Manual download way

Download the jars above. I provided the links from maven repository. Once you have all the jars downloaded, make them available to ant. There are at least 3 ways to do it:

  1. Put it in java library path
  2. Put it in ant library directory
  3. Give the correct classpath to script task.

I find the last method the best, because it is most easily ported between different systems. The ant file for the script task could look as follows:

<project default="t1" >
  <property name="bsh.path"
    location="/mnt/q/jarek/lang/java/ant/stackoverflow/bsh-2.0b5.jar" />
  <target name="t1">
    <script language="beanshell" classpath="${bsh.path}">
      javax.swing.JOptionPane.showMessageDialog(null, "Hello, Script!");
    </script>
  </target>
</project>

Automatic download method, employing Ivy

The manual method is not perfect when you want to distribute your build script. Then you would like a way to make sure the jars are present in the destination system. For distributing builds there's no better tool than ivy. Ivy will download the jars and put them in classpath for you. The problem is that there appears another dependency, which is ivy itself. But providing ivy.jar is quite easy and that is the last dependency we need to supply explicitly.

One may ask why to provide ivy.jar, while we could simply download bsh.jar in the same way. The answer is flexibility. When you have the ivy.jar, you get any jar you wish with a single step being adding it to the ivy.xml file. And there is an agreed universal location for the ivy.jar file, while for other file we would have to think of a suitable directory.

Below comes the full example that downloads ivy and then all the necessary dependencies. Ivy download script is based on Installation chapter of Ivy reference. Then a simple ivy.xml file is needed, which is given after the sample build.xml.

Original auto-download ivy script has a disadvantage of always checking the ivy url, even if ivy.jar is already in the expected location. This may be overriden by specifying -Doffline=true. I prefer to add another target to the build file and to do the http check only if we don't already have the ivy.jar. This is the way the script here works. To observe what ivy actually downloaded, set IVY_HOME environment variable to a directory of your choice. It will be created and filled with ivy stuff.

build.xml:

<project default="t1"
         xmlns:ivy="antlib:org.apache.ivy.ant" >

  <property name="ivy.install.version" value="2.2.0" />
  <property environment="env" />
  <condition property="ivy.home" value="${env.IVY_HOME}">
    <isset property="env.IVY_HOME" />
  </condition>
  <property name="ivy.home" value="${user.home}/.ant" />
  <property name="ivy.jar.dir" value="${ivy.home}/lib" />
  <property name="ivy.jar.file" value="${ivy.jar.dir}/ivy.jar" />

  <target name="check-ivy">
    <condition property="ivy.present">
      <available file="${ivy.jar.file}" type="file" />
    </condition>
  </target>

  <target name="download-ivy" unless="ivy.present">
      <mkdir dir="${ivy.jar.dir}"/>
      <!-- download Ivy from web site so that it can be used even without any special installation -->
      <get src="http://repo2.maven.org/maven2/org/apache/ivy/ivy/${ivy.install.version}/ivy-${ivy.install.version}.jar" 
           dest="${ivy.jar.file}" usetimestamp="true"/>
  </target>

  <target name="init-ivy" depends="check-ivy, download-ivy">
    <!-- try to load ivy here from ivy home, in case the user has not already dropped
            it into ant's lib dir (note that the latter copy will always take precedence).
            We will not fail as long as local lib dir exists (it may be empty) and
            ivy is in at least one of ant's lib dir or the local lib dir. -->
      <path id="ivy.lib.path">
          <fileset dir="${ivy.jar.dir}" includes="*.jar"/>
      </path>
      <taskdef resource="org/apache/ivy/ant/antlib.xml"
               uri="antlib:org.apache.ivy.ant" classpathref="ivy.lib.path"/>
  </target>

  <target name="ivy-libs" depends="init-ivy" >
    <ivy:cachepath pathid="path.from.ivy" log="download-only" />
  </target>

  <target name="t1" depends="ivy-libs" >
    <script language="beanshell" classpathref="path.from.ivy">
      javax.swing.JOptionPane.showMessageDialog(null, "Hello, Script!");
    </script>
  </target>

</project>

ivy.xml:

<?xml version="1.0" encoding="UTF-8"?>
<ivy-module version="2.0" 
            xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
            xsi:noNamespaceSchemaLocation=
                   "http://ant.apache.org/ivy/schemas/ivy.xsd">

<info organisation="example.com" module="testing-script-task" /> 

<dependencies>
  <dependency org="org.beanshell" name="bsh" rev="2.0b5" />
  <!--  <dependency org="bsf" name="bsf" rev="2.4.0" /> -->
</dependencies>

</ivy-module>
like image 43
Jarekczek Avatar answered Oct 06 '22 00:10

Jarekczek


The Ant plug-in "org.apache.ant_1.7.0.v200803061910" have all the jar files needed

like image 22
Supun Sameera Avatar answered Oct 05 '22 23:10

Supun Sameera