Skip to main content

jboss with embedded derby in network mode


Embedding derby into Jboss





In this post I want to show how you can
start jboss with an embedded derby network database.





The aim is, that when jboss starts:




  • it will start derby




  • open port 1527 for derby to receive
    jdbc calls




  • create a new database if there is
    none existing




  • create a datasource inside jboss




You can now use any derby jdbc client
to communicate with the database, and use derby datasource inside
jboss as well.





I had to implement three components:




  1. an mbean to start the derby network
    server




  2. a datasource to connect to derby
    database with option create=true




  3. an mbean that will get an initial
    connection so that database gets created







Jboss mbean


In Jboss you can deploy mbeans, which
automatically get started on deployment. The implementation of an
Mbean is very simple: you must create an interface that ends with
Mbean and has methods start() and stop(), and implement a class for
this interface that shares the same name without the Mbean part.


Then you create an xml with a reference
to the class implementation, and a name settings. For example:


style="margin-left: 0.5in; margin-bottom: 0in; page-break-before: auto;">
<?xml version="1.0"
encoding="UTF-8"?>


style="margin-left: 0.5in; margin-bottom: 0in; page-break-before: auto;">
<server>


style="margin-left: 0.5in; margin-bottom: 0in; page-break-before: auto;">
   
<mbean
code="jankester.com.derby.jboss.DerbyDatabase"


style="margin-left: 0.5in; margin-bottom: 0in; page-break-before: auto;">
   
    name="jboss.jdbc:service=DerbyDatabase">


style="margin-left: 0.5in; margin-bottom: 0in; page-break-before: auto;">
   
</mbean>


style="margin-left: 0.5in; margin-bottom: 0in; page-break-before: auto;">
face="Monospace"></server>


The deployment of an Mbean can be done
in several ways: you can create an xml file, drop it in the deploy
directory and make sure that the java classes are available in the
lib directory, or you can create a .sar file. The latter has the
advantage that you can do hot deployment, so I prefer it.


You must: create a jar file or
directory that ends in .sar (so that jboss recognizes it type on
deployment), and add a jar to this .sar file with the necessary
classes.





The network server Mbean


The interface for this mbean looks
like:


style="margin-left: 0.5in; margin-bottom: 0in; page-break-before: auto;">
package
com.jankester.derby.jboss;


style="margin-left: 0.5in; margin-bottom: 0in; page-break-before: auto;">



style="margin-left: 0.5in; margin-bottom: 0in; page-break-before: auto;">
public interface
DerbyDatabaseMBean


style="margin-left: 0.5in; margin-bottom: 0in; page-break-before: auto;">
{


style="margin-left: 0.5in; margin-bottom: 0in; page-break-before: auto;">
   
public void start()
throws Exception;


style="margin-left: 0.5in; margin-bottom: 0in; page-break-before: auto;">
   
public void stop()
throws Exception;


style="margin-left: 0.5in; margin-bottom: 0in; page-break-before: auto;">
}


The class implementing this interface
has following:


style="margin-left: 0.5in; margin-bottom: 0in; page-break-before: auto;">
package
com.jankester.derby.jboss;


style="margin-left: 0.5in; margin-bottom: 0in; page-break-before: auto;">
import
java.sql.DriverManager;


style="margin-left: 0.5in; margin-bottom: 0in; page-break-before: auto;">
import
java.sql.SQLException;


style="margin-left: 0.5in; margin-bottom: 0in; page-break-before: auto;">



style="margin-left: 0.5in; margin-bottom: 0in; page-break-before: auto;">
public class
DerbyDatabase implements DerbyDatabaseMBean


style="margin-left: 0.5in; margin-bottom: 0in; page-break-before: auto;">
{


style="margin-left: 0.5in; margin-bottom: 0in; page-break-before: auto;">
   
public static final
String START_NETWORK_SERVER = "derby.drda.startNetworkServer";


style="margin-left: 0.5in; margin-bottom: 0in; page-break-before: auto;">
   
public static final
String HOST = "localhost";


style="margin-left: 0.5in; margin-bottom: 0in; page-break-before: auto;">
   
public static final
String PORT_NUMBER = "1527";


style="margin-left: 0.5in; margin-bottom: 0in; page-break-before: auto;">
   
public static final
String DRIVER_CLASSNAME = "org.apache.derby.jdbc.EmbeddedDriver";


style="margin-left: 0.5in; margin-bottom: 0in; page-break-before: auto;">
   
public static final
String SHUTDOWN_URL = "jdbc:derby:;shutdown=true";


style="margin-left: 0.5in; margin-bottom: 0in; page-break-before: auto;">
   
public static final
String SHUTDOWN_MESSAGE = "Derby system shutdown.";


style="margin-left: 0.5in; margin-bottom: 0in; page-break-before: auto;">
   
public static final
String MSG_INIT_SUCCESS = "Derby JDBC driver loaded
successfully";


style="margin-left: 0.5in; margin-bottom: 0in; page-break-before: auto;">
   
public static final
String MSG_INIT_CLASS_NOT_FOUND = "The Derby JDBC driver ("


style="margin-left: 0.5in; margin-bottom: 0in; page-break-before: auto;">
+
DRIVER_CLASSNAME + ") could not be found. Make sure the
appropriate JAR"


style="margin-left: 0.5in; margin-bottom: 0in; page-break-before: auto;">
+ " files
are available.";


style="margin-left: 0.5in; margin-bottom: 0in; page-break-before: auto;">
   
public static final
String MSG_TERM_SUCCESS = "Derby shutdown was successful.";


style="margin-left: 0.5in; margin-bottom: 0in; page-break-before: auto;">
   
public static final
String MSG_TERM_FAILURE = "Unexpected Exception was caught from
the Derby shutdown.";


style="margin-left: 0.5in; margin-bottom: 0in; page-break-before: auto;">



style="margin-left: 0.5in; margin-bottom: 0in; page-break-before: auto;">
   
public void start()
throws Exception


style="margin-left: 0.5in; margin-bottom: 0in; page-break-before: auto;">
    {


style="margin-left: 0.5in; margin-bottom: 0in; page-break-before: auto;">
   
    setSystemProperties();


style="margin-left: 0.5in; margin-bottom: 0in; page-break-before: auto;">
   
    initializeCloudscape();


style="margin-left: 0.5in; margin-bottom: 0in; page-break-before: auto;">
    }


style="margin-left: 0.5in; margin-bottom: 0in; page-break-before: auto;">



style="margin-left: 0.5in; margin-bottom: 0in; page-break-before: auto;">
   
public void stop()
throws Exception


style="margin-left: 0.5in; margin-bottom: 0in; page-break-before: auto;">
    {


style="margin-left: 0.5in; margin-bottom: 0in; page-break-before: auto;">
   
    shutdownCloudscape();


style="margin-left: 0.5in; margin-bottom: 0in; page-break-before: auto;">
    }


style="margin-left: 0.5in; margin-bottom: 0in; page-break-before: auto;">



style="margin-left: 0.5in; margin-bottom: 0in; page-break-before: auto;">
   
private void
setSystemProperties()


style="margin-left: 0.5in; margin-bottom: 0in; page-break-before: auto;">
    {


style="margin-left: 0.5in; margin-bottom: 0in; page-break-before: auto;">
   
    String dataDir =
System.getProperty("jboss.server.data.dir");


style="margin-left: 0.5in; margin-bottom: 0in; page-break-before: auto;">
   
    System.out.println("jboss.server.data.dir="
+ dataDir);


style="margin-left: 0.5in; margin-bottom: 0in; page-break-before: auto;">
   
    System.setProperty(START_NETWORK_SERVER,
"true");


style="margin-left: 0.5in; margin-bottom: 0in; page-break-before: auto;">
   
    System.setProperty("derby.system.home",
dataDir);


style="margin-left: 0.5in; margin-bottom: 0in; page-break-before: auto;">
    }


style="margin-left: 0.5in; margin-bottom: 0in; page-break-before: auto;">



style="margin-left: 0.5in; margin-bottom: 0in; page-break-before: auto;">
   
private void
initializeCloudscape()


style="margin-left: 0.5in; margin-bottom: 0in; page-break-before: auto;">
    {


style="margin-left: 0.5in; margin-bottom: 0in; page-break-before: auto;">
   
    try


style="margin-left: 0.5in; margin-bottom: 0in; page-break-before: auto;">
    
   {


style="margin-left: 0.5in; margin-bottom: 0in; page-break-before: auto;">
   
        Class.forName(DRIVER_CLASSNAME);


style="margin-left: 0.5in; margin-bottom: 0in; page-break-before: auto;">
   
       
System.out.println(MSG_INIT_SUCCESS);


style="margin-left: 0.5in; margin-bottom: 0in; page-break-before: auto;">
    
   }


style="margin-left: 0.5in; margin-bottom: 0in; page-break-before: auto;">
    
   catch
(ClassNotFoundException varException)


style="margin-left: 0.5in; margin-bottom: 0in; page-break-before: auto;">
   
    {


style="margin-left: 0.5in; margin-bottom: 0in; page-break-before: auto;">
   
       
System.out.println(MSG_INIT_CLASS_NOT_FOUND);


style="margin-left: 0.5in; margin-bottom: 0in; page-break-before: auto;">
    
       varException.printStackTrace();


style="margin-left: 0.5in; margin-bottom: 0in; page-break-before: auto;">
   
    }


style="margin-left: 0.5in; margin-bottom: 0in; page-break-before: auto;">
    }


style="margin-left: 0.5in; margin-bottom: 0in; page-break-before: auto;">



style="margin-left: 0.5in; margin-bottom: 0in; page-break-before: auto;">
   
private void
shutdownCloudscape()


style="margin-left: 0.5in; margin-bottom: 0in; page-break-before: auto;">
    {


style="margin-left: 0.5in; margin-bottom: 0in; page-break-before: auto;">
   
    try


style="margin-left: 0.5in; margin-bottom: 0in; page-break-before: auto;">
   
    {


style="margin-left: 0.5in; margin-bottom: 0in; page-break-before: auto;">
   
       
DriverManager.getConnection(SHUTDOWN_URL);


style="margin-left: 0.5in; margin-bottom: 0in; page-break-before: auto;">
   
    }


style="margin-left: 0.5in; margin-bottom: 0in; page-break-before: auto;">
   
    catch
(SQLException varException)


style="margin-left: 0.5in; margin-bottom: 0in; page-break-before: auto;">
   
    {


style="margin-left: 0.5in; margin-bottom: 0in; page-break-before: auto;">
   
        System.out.println("message="
+         varException.getMessage());


style="margin-left: 0.5in; margin-bottom: 0in; page-break-before: auto;">
   
        System.out.println("sqlstate="
+     varException.getSQLState());


style="margin-left: 0.5in; margin-bottom: 0in; page-break-before: auto;">



style="margin-left: 0.5in; margin-bottom: 0in; page-break-before: auto;">
   
        if
(varException.getMessage().equals(SHUTDOWN_MESSAGE))


style="margin-left: 0.5in; margin-bottom: 0in; page-break-before: auto;">
   
        {


style="margin-left: 0.5in; margin-bottom: 0in; page-break-before: auto;">
   
           
System.out.println(MSG_TERM_SUCCESS);


style="margin-left: 0.5in; margin-bottom: 0in; page-break-before: auto;">
   
        }


style="margin-left: 0.5in; margin-bottom: 0in; page-break-before: auto;">
   
        else


style="margin-left: 0.5in; margin-bottom: 0in; page-break-before: auto;">
   
        {


style="margin-left: 0.5in; margin-bottom: 0in; page-break-before: auto;">
   
           
System.out.println(MSG_TERM_FAILURE);


style="margin-left: 0.5in; margin-bottom: 0in; page-break-before: auto;">
   
           
varException.printStackTrace();


style="margin-left: 0.5in; margin-bottom: 0in; page-break-before: auto;">
   
        }


style="margin-left: 0.5in; margin-bottom: 0in; page-break-before: auto;">
   
    }


style="margin-left: 0.5in; margin-bottom: 0in; page-break-before: auto;">
    }


style="margin-left: 0.5in; margin-bottom: 0in; page-break-before: auto;">
}


In initializeCloudscape() it loads the
driver class. Before, in system properties it sets system properties
that will be picked up by the driver class:




  • network mode is true




  • the root directory for derby
    database storage is the jboss server data dir.




The xml that belong to this mbean is:


style="margin-left: 0.5in; margin-bottom: 0in; page-break-before: auto;">
<?xml version="1.0"
encoding="UTF-8"?>


style="margin-left: 0.5in; margin-bottom: 0in; page-break-before: auto;">
<server>


style="margin-left: 0.5in; margin-bottom: 0in; page-break-before: auto;">
   
<mbean
code="jankester.com.derby.jboss.DerbyDatabase"


style="margin-left: 0.5in; margin-bottom: 0in; page-break-before: auto;">
name="jboss.jdbc:service=DerbyDatabase">


style="margin-left: 0.5in; margin-bottom: 0in; page-break-before: auto;">
   
</mbean>


style="margin-left: 0.5in; margin-bottom: 0in; page-break-before: auto;">
face="Monospace"></server>


The xml file must be renamed into
META-INF/jboss-service.xml, the classes added to a jar, and the jar
and META-INF directory together packed into a .sar file. You can now
deploy the file directly in the deploy dir of your server.





The datasource


To create a derby datasource, you can
use the samples that comes with jboss.


style="margin-left: 0.5in; margin-bottom: 0in; page-break-before: auto;">
<?xml version="1.0"
encoding="UTF-8"?>


style="margin-left: 0.5in; margin-bottom: 0in; page-break-before: auto;">
<datasources>


style="margin-left: 0.5in; margin-bottom: 0in; page-break-before: auto;">
   
<local-tx-datasource>


style="margin-left: 0.5in; margin-bottom: 0in; page-break-before: auto;">
  
   
<jndi-name>AuditTrail.DataSource</jndi-name>


style="margin-left: 0.5in; margin-bottom: 0in; page-break-before: auto;">   
 face="Courier, monospace"><connection-url>jdbc:derby:${jboss.server.data.dir}${/}carnot;create=true</connection-url>


style="margin-left: 0.5in; margin-bottom: 0in; page-break-before: auto;">
   
     
<driver-class>org.apache.derby.jdbc.EmbeddedDriver</driver-class>


style="margin-left: 0.5in; margin-bottom: 0in; page-break-before: auto;">
   
    <user-name>carnot</user-name>


style="margin-left: 0.5in; margin-bottom: 0in; page-break-before: auto;">
   
    <password>carnot</password>


style="margin-left: 0.5in; margin-bottom: 0in; page-break-before: auto;">
   
    <min-pool-size>5</min-pool-size>


style="margin-left: 0.5in; margin-bottom: 0in; page-break-before: auto;">
   
    <max-pool-size>20</max-pool-size>


style="margin-left: 0.5in; margin-bottom: 0in; page-break-before: auto;">
   
   
<idle-timeout-minutes>5</idle-timeout-minutes>


style="margin-left: 0.5in; margin-bottom: 0in; page-break-before: auto;">
   
    <track-statements/>


style="margin-left: 0.5in; margin-bottom: 0in; page-break-before: auto;">
   
   
<depends>jboss.jdbc:service=DerbyDatabase</depends>


style="margin-left: 0.5in; margin-bottom: 0in; page-break-before: auto;">
   
</local-tx-datasource>


style="margin-left: 0.5in; margin-bottom: 0in; page-break-before: auto;">
</datasources>


Important to note here, is, that the
connection url creates a new database if none is existing and uses
the jboss data directory as its basis for database data.


The datasource has a dependency on the
derbydatabase mbean that we just created. It will not load before
that mbean has been loaded.





The poolfiller MBean


This mbean is necessary as we must make
sure that the database gets created straight away on loading. If we
leave this out, we can have the scenario that an external jdbc client
calls derby, but that the database has not been created yet. The
database only gets created the first time the datasource connection
gets created. So, this mbean will create a connection and close it
again.


Here we an interface PoolFillerMbean:


style="margin-left: 0.5in; margin-bottom: 0in; page-break-before: auto;">
package
jankester.com.derby.jboss;


style="margin-left: 0.5in; margin-bottom: 0in; page-break-before: auto;">



style="margin-left: 0.5in; margin-bottom: 0in; page-break-before: auto;">
import
javax.management.ObjectName;


style="margin-left: 0.5in; margin-bottom: 0in; page-break-before: auto;">



style="margin-left: 0.5in; margin-bottom: 0in; page-break-before: auto;">
public interface
PoolFillerMBean


style="margin-left: 0.5in; margin-bottom: 0in; page-break-before: auto;">
{


style="margin-left: 0.5in; margin-bottom: 0in; page-break-before: auto;">
   
public void start()
throws Exception;


style="margin-left: 0.5in; margin-bottom: 0in; page-break-before: auto;">
   
public void stop()
throws Exception;


style="margin-left: 0.5in; margin-bottom: 0in; page-break-before: auto;">
   
public void
setConnectionManager(ObjectName cm);


style="margin-left: 0.5in; margin-bottom: 0in; page-break-before: auto;">
}


and a class PoolFiller:


style="margin-left: 0.5in; margin-bottom: 0in; page-break-before: auto;">
package
jankester.com.derby.jboss;


style="margin-left: 0.5in; margin-bottom: 0in; page-break-before: auto;">



style="margin-left: 0.5in; margin-bottom: 0in; page-break-before: auto;">
import
java.sql.Connection;


style="margin-left: 0.5in; margin-bottom: 0in; page-break-before: auto;">



style="margin-left: 0.5in; margin-bottom: 0in; page-break-before: auto;">
import
javax.management.ObjectName;


style="margin-left: 0.5in; margin-bottom: 0in; page-break-before: auto;">
import
javax.naming.InitialContext;


style="margin-left: 0.5in; margin-bottom: 0in; page-break-before: auto;">
import
javax.sql.DataSource;


style="margin-left: 0.5in; margin-bottom: 0in; page-break-before: auto;">



style="margin-left: 0.5in; margin-bottom: 0in; page-break-before: auto;">
import
org.jboss.system.ServiceMBeanSupport;


style="margin-left: 0.5in; margin-bottom: 0in; page-break-before: auto;">



style="margin-left: 0.5in; margin-bottom: 0in; page-break-before: auto;">
public class PoolFiller
extends ServiceMBeanSupport implements PoolFillerMBean


style="margin-left: 0.5in; margin-bottom: 0in; page-break-before: auto;">
{


style="margin-left: 0.5in; margin-bottom: 0in; page-break-before: auto;">
   
public void start()
throws Exception


style="margin-left: 0.5in; margin-bottom: 0in; page-break-before: auto;">
    {


style="margin-left: 0.5in; margin-bottom: 0in; page-break-before: auto;">
   
    System.out.println("Starting
PoolFiller");


style="margin-left: 0.5in; margin-bottom: 0in; page-break-before: auto;">
   
    startService();


style="margin-left: 0.5in; margin-bottom: 0in; page-break-before: auto;">
    }


style="margin-left: 0.5in; margin-bottom: 0in; page-break-before: auto;">



style="margin-left: 0.5in; margin-bottom: 0in; page-break-before: auto;">
   
public void stop()


style="margin-left: 0.5in; margin-bottom: 0in; page-break-before: auto;">
    {


style="margin-left: 0.5in; margin-bottom: 0in; page-break-before: auto;">
   
    System.out.println("Stopping
PoolFiller");


style="margin-left: 0.5in; margin-bottom: 0in; page-break-before: auto;">
    }


style="margin-left: 0.5in; margin-bottom: 0in; page-break-before: auto;">



style="margin-left: 0.5in; margin-bottom: 0in; page-break-before: auto;">
   
private ObjectName
cm;


style="margin-left: 0.5in; margin-bottom: 0in; page-break-before: auto;">



style="margin-left: 0.5in; margin-bottom: 0in; page-break-before: auto;">
   
public void
setConnectionManager(ObjectName cm)


style="margin-left: 0.5in; margin-bottom: 0in; page-break-before: auto;">
    {


style="margin-left: 0.5in; margin-bottom: 0in; page-break-before: auto;">
   
    this.cm = cm;


style="margin-left: 0.5in; margin-bottom: 0in; page-break-before: auto;">
    }


style="margin-left: 0.5in; margin-bottom: 0in; page-break-before: auto;">



style="margin-left: 0.5in; margin-bottom: 0in; page-break-before: auto;">
   
protected void
startService() throws Exception


style="margin-left: 0.5in; margin-bottom: 0in; page-break-before: auto;">
    {


style="margin-left: 0.5in; margin-bottom: 0in; page-break-before: auto;">
   
    String jndiName =
(String) server.getAttribute(cm, "BindName");


style="margin-left: 0.5in; margin-bottom: 0in; page-break-before: auto;">
   
    DataSource ds =
(DataSource) new InitialContext().lookup(jndiName);


style="margin-left: 0.5in; margin-bottom: 0in; page-break-before: auto;">
   
    System.out.println("Found
datasource for jndiname=" + jndiName);


style="margin-left: 0.5in; margin-bottom: 0in; page-break-before: auto;">
   
    Connection c =
ds.getConnection();


style="margin-left: 0.5in; margin-bottom: 0in; page-break-before: auto;">
   
    c.close();


style="margin-left: 0.5in; margin-bottom: 0in; page-break-before: auto;">
    }


style="margin-left: 0.5in; margin-bottom: 0in; page-break-before: auto;">
}


Here we had to add an extra method
setConnectionManager to load an existing mbean object. We have to
implement this method in class and interface, so that Jboss can find
it.


Further we extended ServiceMBeanSupport
so that we have access to the Mbean Server. We
need it to find our Mbean that holds the jndi name of our datasource.
With the jndi name, we can find the datasource, and retrieve a
connection. Now the database gets created.


The method BindName is an attribute of
the Mbean that gets passed into the setConnection method. If you use
a different version of Jboss (tested with 4.0.5), then look into
http://localhost:8080/jmx-console,
and find an Mbean that has an attribute that holds the jndi
reference.


The jboss-service.xml looks like:


style="margin-left: 0.5in; margin-bottom: 0in; page-break-before: auto;">
<?xml version="1.0"
encoding="UTF-8"?>


style="margin-left: 0.5in; margin-bottom: 0in; page-break-before: auto;">
<server>


style="margin-left: 0.5in; margin-bottom: 0in; page-break-before: auto;">
   
<mbean
code="ag.carnot.derby.jboss.PoolFiller"


style="margin-left: 0.5in; margin-bottom: 0in; page-break-before: auto;">
name="jboss.jdbc:service=PoolFiller">


style="margin-left: 0.5in; margin-bottom: 0in; page-break-before: auto;">
   
<depends
optional-attribute-name="ConnectionManager">jboss.jca:name=AuditTrail.DataSource,service=DataSourceBinding</depends>


style="margin-left: 0.5in; margin-bottom: 0in; page-break-before: auto;">
<!-- -->


style="margin-left: 0.5in; margin-bottom: 0in; page-break-before: auto;">
   
</mbean>


style="margin-left: 0.5in; margin-bottom: 0in; page-break-before: auto;">
face="Monospace"></server>





Deployment on jboss


The easiest is to make a copy of the
server/default directory, and create a server/derby directory.


Further you must put the derby.jar and
derbynet.jar files in server/derby/lib.


Copy the two mbeans and datasource.xml
of above in the deploy directory.





Checks


When you have started derby, you should
see that port 1527 got opened, and that the directory carnot has been
created under server/derby/data.





jdbc client


You can use the db2 driver db2jcc.jar,
db2jcc_license_c.jar.


The url looks like:
jdbc:derby:net://localhost/carnot







Comments

hi, good post, i'm trying now but seems like there's a lot of un-necessary html so it looks quite confusing...

Popular posts from this blog

SSL handshake failed: Secure connection truncated

Got this problem on Ubuntu 9.10 and 10.10. svn co --username=xx https:/yy zz “SSL handshake failed: Secure connection truncated” According to this link bug-ubuntu The solution is: sudo apt-get install libneon27 cd /usr/lib/ sudo rm libneon-gnutls.so.27 sudo ln -s /usr/lib/libneon.so.27 libneon-gnutls.so.27

Junit4 running parallel junit classes

To run junit testcases parallel, you can create your own class to run junit with: Add this tag to your class declaration. @RunWith(Parallelized.class) Implementation of this class looks like: package mypackage; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.TimeUnit; import org.junit.runners.Parameterized; import org.junit.runners.model.RunnerScheduler; public class Parallelized extends Parameterized {         private static class ThreadPoolScheduler implements RunnerScheduler     {         private ExecutorService executor;                 public ThreadPoolScheduler()         {             String threads = System.getProperty("junit.parallel.threads", "16");    ...

Create a groovy console and bind to selenium

Required groovy files In the previous posting we defined the pom file that we need for our build environment. Now we will setup some groovy files to get selenium and groovy running interactively. ConsoleWaiter.groovy The idea of Groovy Console I found on some other sides. Honour goes for instance too: http://josefbetancourt.wordpress.com/tag/eclipse-2/ I copied some code of this, and put it under src/test/groovy/com/jankester/selenium/test/utils: package com.jankester.selenium.test.utils /** * File: ConsoleWaiter.groovy */ import groovy.lang.Binding; import groovy.ui.Console; /** * Provides a wrapper for the console. * * Based on source by John Green * Adapted from: http://www.oehive.org/files/ConsoleWaiter.groovy * Released under the Eclipse Public License * http://www.eclipse.org/legal/epl-v10.html * * I added methods to allow use from Java. * * The run() method launches the console and causes this thread * to sleep until the console's window is closed....