You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@tomee.apache.org by rm...@apache.org on 2012/01/18 18:24:23 UTC
svn commit: r1232963 - in /openejb/trunk/openejb/server: ./
openejb-common-cli/ openejb-common-cli/src/ openejb-common-cli/src/main/
openejb-common-cli/src/main/java/ openejb-common-cli/src/main/java/org/
openejb-common-cli/src/main/java/org/apache/ op...
Author: rmannibucau
Date: Wed Jan 18 17:24:22 2012
New Revision: 1232963
URL: http://svn.apache.org/viewvc?rev=1232963&view=rev
Log:
implementing the ssh test
Added:
openejb/trunk/openejb/server/openejb-common-cli/
openejb/trunk/openejb/server/openejb-common-cli/pom.xml
openejb/trunk/openejb/server/openejb-common-cli/src/
openejb/trunk/openejb/server/openejb-common-cli/src/main/
openejb/trunk/openejb/server/openejb-common-cli/src/main/java/
openejb/trunk/openejb/server/openejb-common-cli/src/main/java/org/
openejb/trunk/openejb/server/openejb-common-cli/src/main/java/org/apache/
openejb/trunk/openejb/server/openejb-common-cli/src/main/java/org/apache/openejb/
openejb/trunk/openejb/server/openejb-common-cli/src/main/java/org/apache/openejb/server/
openejb/trunk/openejb/server/openejb-common-cli/src/main/java/org/apache/openejb/server/cli/
openejb/trunk/openejb/server/openejb-common-cli/src/main/java/org/apache/openejb/server/cli/CliRunnable.java
openejb/trunk/openejb/server/openejb-common-cli/src/main/java/org/apache/openejb/server/cli/CliRuntimeException.java
openejb/trunk/openejb/server/openejb-ssh/src/test/key/
openejb/trunk/openejb/server/openejb-ssh/src/test/key/ssh-key.ser (with props)
Modified:
openejb/trunk/openejb/server/openejb-ssh/pom.xml
openejb/trunk/openejb/server/openejb-ssh/src/main/java/org/apache/openejb/server/ssh/OpenEJBCommands.java
openejb/trunk/openejb/server/openejb-ssh/src/test/java/org/apache/openejb/server/ssh/SSHServerTest.java
openejb/trunk/openejb/server/pom.xml
Added: openejb/trunk/openejb/server/openejb-common-cli/pom.xml
URL: http://svn.apache.org/viewvc/openejb/trunk/openejb/server/openejb-common-cli/pom.xml?rev=1232963&view=auto
==============================================================================
--- openejb/trunk/openejb/server/openejb-common-cli/pom.xml (added)
+++ openejb/trunk/openejb/server/openejb-common-cli/pom.xml Wed Jan 18 17:24:22 2012
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ <parent>
+ <artifactId>server</artifactId>
+ <groupId>org.apache.openejb</groupId>
+ <version>4.0.0-beta-2-SNAPSHOT</version>
+ </parent>
+ <modelVersion>4.0.0</modelVersion>
+
+ <artifactId>openejb-common-cli</artifactId>
+ <name>OpenEJB :: Server :: Common CLI</name>
+
+ <dependencies>
+ <dependency>
+ <groupId>${project.groupId}</groupId>
+ <artifactId>openejb-groovy</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>jline</groupId>
+ <artifactId>jline</artifactId>
+ <version>0.9.94</version>
+ </dependency>
+ </dependencies>
+</project>
Added: openejb/trunk/openejb/server/openejb-common-cli/src/main/java/org/apache/openejb/server/cli/CliRunnable.java
URL: http://svn.apache.org/viewvc/openejb/trunk/openejb/server/openejb-common-cli/src/main/java/org/apache/openejb/server/cli/CliRunnable.java?rev=1232963&view=auto
==============================================================================
--- openejb/trunk/openejb/server/openejb-common-cli/src/main/java/org/apache/openejb/server/cli/CliRunnable.java (added)
+++ openejb/trunk/openejb/server/openejb-common-cli/src/main/java/org/apache/openejb/server/cli/CliRunnable.java Wed Jan 18 17:24:22 2012
@@ -0,0 +1,211 @@
+package org.apache.openejb.server.cli;
+
+import jline.ConsoleReader;
+import org.apache.commons.lang3.builder.ToStringBuilder;
+import org.apache.commons.lang3.builder.ToStringStyle;
+import org.apache.openejb.assembler.classic.OpenEjbConfiguration;
+import org.apache.openejb.assembler.classic.cmd.Info2Properties;
+import org.apache.openejb.loader.SystemInstance;
+import org.apache.openejb.server.groovy.OpenEJBGroovyShell;
+import org.apache.openejb.util.helper.CommandHelper;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.io.OutputStreamWriter;
+import java.io.PrintStream;
+import java.util.Collection;
+
+public class CliRunnable implements Runnable {
+ public static final String EXIT_COMMAND = "exit";
+ private static final String GROOVY_PREFIX = "G ";
+ private static final String LIST_CMD = "list";
+ private static final String PROPERTIES_CMD = "properties";
+ private static final String WELCOME = "Welcome on your $bind:$port $name server";
+ public static final String LINE_SEP = "\r\n"; // don't use line.separator (sshd use this one)
+ public static final String OS_LINE_SEP = System.getProperty("line.separator");
+ private static final String NAME;
+ public static final String PROMPT = "openejb> ";
+
+ static {
+ System.setProperty("line.separator", LINE_SEP);
+ try {
+ // just to force the loading of this class with the set line.separator
+ // because ConsoleReader.CR is a constant and we need sometimes another value
+ // not a big issue but keeping this as a workaround
+ new ConsoleReader();
+ } catch (IOException ignored) {
+ // no-op
+ } finally {
+ System.setProperty("line.separator", OS_LINE_SEP);
+ }
+
+ String name = "OpenEJB";
+ try {
+ CliRunnable.class.getClassLoader().loadClass("org.apache.tomee.loader.TomcatHook");
+ name = "TomEE";
+ } catch (ClassNotFoundException cnfe) {
+ // ignored, we are using a simple OpenEJB server
+ }
+ NAME = name;
+ }
+
+ private OpenEJBGroovyShell shell;
+ private OutputStreamWriter serr;
+ private OutputStreamWriter sout;
+ private OutputStream out;
+ private InputStream sin;
+ private String bind;
+ private int port;
+
+
+ public CliRunnable(String bind, int port) {
+ this.bind = bind;
+ this.port = port;
+ }
+
+ public void setInputStream(InputStream in) {
+ sin = in;
+ }
+
+ public void setOutputStream(OutputStream out) {
+ this.out = out;
+ sout = new OutputStreamWriter(out);
+ }
+
+ public void setErrorStream(OutputStream err) {
+ serr = new OutputStreamWriter(err);
+ }
+
+ public void start() throws IOException {
+ shell = new OpenEJBGroovyShell();
+ new Thread(this, "OpenEJB Cli").start();
+ }
+
+ public void destroy() {
+ shell.resetLoadedClasses();
+ }
+
+ public void run() {
+ try {
+ final ConsoleReader reader = new ConsoleReader(sin, sout);
+ // TODO : add completers with method names...?
+
+ String line;
+ write(sout, WELCOME // simple replace for now, if it is mandatory we could bring velocity to do it
+ .replace("$bind", bind)
+ .replace("$port", Integer.toString(port))
+ .replace("$name", NAME));
+ while ((line = reader.readLine(PROMPT)) != null) {
+ if (EXIT_COMMAND.equals(line)) {
+ break;
+ }
+
+ if (line.startsWith(GROOVY_PREFIX)) {
+ try {
+ write(sout, result(line.substring(GROOVY_PREFIX.length())));
+ } catch (CliRuntimeException sshEx) {
+ write((Exception) sshEx.getCause());
+ }
+ } else if (LIST_CMD.equals(line)) {
+ list();
+ } else if (PROPERTIES_CMD.equals(line)) {
+ properties();
+ } else {
+ write(sout, "sorry i don't understand '" + line + "'");
+ }
+ }
+ } catch (IOException e) {
+ throw new CliRuntimeException(e);
+ }
+ }
+
+ private void properties() {
+ final OpenEjbConfiguration config = SystemInstance.get().getComponent(OpenEjbConfiguration.class);
+ Info2Properties.printConfig(config, new PrintStream(out), LINE_SEP);
+ }
+
+ private void list() {
+ try {
+ CommandHelper.listEJBs(LINE_SEP).print(new PrintStream(out));
+ } catch (Exception e) {
+ write(e);
+ }
+ }
+
+ private static void write(final OutputStreamWriter writer, final String s) {
+ for (String l : s.split(LINE_SEP)) {
+ try {
+ writer.write(l);
+ writer.write(LINE_SEP);
+ writer.flush();
+ } catch (IOException e) {
+ // ignored
+ }
+ }
+ }
+
+ private void write(Exception e) {
+ if (e.getStackTrace() == null) {
+ write(serr, e.getMessage());
+ } else {
+ final StringBuilder error = new StringBuilder();
+ for (StackTraceElement elt : e.getStackTrace()) {
+ error.append(elt.toString()).append(LINE_SEP);
+ }
+ write(serr, error.toString());
+ }
+ }
+
+ private String result(final String value) {
+ Object out;
+ try {
+ out = shell.evaluate(value);
+ } catch (Exception e) {
+ throw new CliRuntimeException(e);
+ }
+
+ if (out == null) {
+ return "null";
+ }
+ if (out instanceof Collection) {
+ final StringBuilder builder = new StringBuilder();
+ for (Object o : (Collection) out) {
+ builder.append(string(o)).append(LINE_SEP);
+ }
+ return builder.toString();
+ }
+ return string(out);
+ }
+
+ private static String string(Object out) {
+ if (!out.getClass().getName().startsWith("java")) {
+ return ToStringBuilder.reflectionToString(out, ToStringStyle.SHORT_PREFIX_STYLE);
+ }
+ return out.toString();
+ }
+
+ public OutputStream getOut() {
+ return out;
+ }
+
+ public OutputStreamWriter getSerr() {
+ return serr;
+ }
+
+ public OutputStreamWriter getSout() {
+ return sout;
+ }
+
+ public InputStream getSin() {
+ return sin;
+ }
+
+ public String getBind() {
+ return bind;
+ }
+
+ public int getPort() {
+ return port;
+ }
+}
Added: openejb/trunk/openejb/server/openejb-common-cli/src/main/java/org/apache/openejb/server/cli/CliRuntimeException.java
URL: http://svn.apache.org/viewvc/openejb/trunk/openejb/server/openejb-common-cli/src/main/java/org/apache/openejb/server/cli/CliRuntimeException.java?rev=1232963&view=auto
==============================================================================
--- openejb/trunk/openejb/server/openejb-common-cli/src/main/java/org/apache/openejb/server/cli/CliRuntimeException.java (added)
+++ openejb/trunk/openejb/server/openejb-common-cli/src/main/java/org/apache/openejb/server/cli/CliRuntimeException.java Wed Jan 18 17:24:22 2012
@@ -0,0 +1,9 @@
+package org.apache.openejb.server.cli;
+
+import java.io.IOException;
+
+public class CliRuntimeException extends RuntimeException {
+ public CliRuntimeException(Exception e) {
+ super(e);
+ }
+}
Modified: openejb/trunk/openejb/server/openejb-ssh/pom.xml
URL: http://svn.apache.org/viewvc/openejb/trunk/openejb/server/openejb-ssh/pom.xml?rev=1232963&r1=1232962&r2=1232963&view=diff
==============================================================================
--- openejb/trunk/openejb/server/openejb-ssh/pom.xml (original)
+++ openejb/trunk/openejb/server/openejb-ssh/pom.xml Wed Jan 18 17:24:22 2012
@@ -47,6 +47,11 @@
<version>${project.version}</version>
</dependency>
<dependency>
+ <groupId>${project.groupId}</groupId>
+ <artifactId>openejb-common-cli</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+ <dependency>
<groupId>jline</groupId>
<artifactId>jline</artifactId>
<version>0.9.94</version>
Modified: openejb/trunk/openejb/server/openejb-ssh/src/main/java/org/apache/openejb/server/ssh/OpenEJBCommands.java
URL: http://svn.apache.org/viewvc/openejb/trunk/openejb/server/openejb-ssh/src/main/java/org/apache/openejb/server/ssh/OpenEJBCommands.java?rev=1232963&r1=1232962&r2=1232963&view=diff
==============================================================================
--- openejb/trunk/openejb/server/openejb-ssh/src/main/java/org/apache/openejb/server/ssh/OpenEJBCommands.java (original)
+++ openejb/trunk/openejb/server/openejb-ssh/src/main/java/org/apache/openejb/server/ssh/OpenEJBCommands.java Wed Jan 18 17:24:22 2012
@@ -1,13 +1,6 @@
package org.apache.openejb.server.ssh;
-import jline.ConsoleReader;
-import org.apache.commons.lang3.builder.ToStringBuilder;
-import org.apache.commons.lang3.builder.ToStringStyle;
-import org.apache.openejb.assembler.classic.OpenEjbConfiguration;
-import org.apache.openejb.assembler.classic.cmd.Info2Properties;
-import org.apache.openejb.loader.SystemInstance;
-import org.apache.openejb.server.groovy.OpenEJBGroovyShell;
-import org.apache.openejb.util.helper.CommandHelper;
+import org.apache.openejb.server.cli.CliRunnable;
import org.apache.sshd.server.Command;
import org.apache.sshd.server.Environment;
import org.apache.sshd.server.ExitCallback;
@@ -15,191 +8,50 @@ import org.apache.sshd.server.ExitCallba
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
-import java.io.OutputStreamWriter;
-import java.io.PrintStream;
-import java.util.Collection;
-
-public class OpenEJBCommands implements Command, Runnable {
- public static final String EXIT_COMMAND = "exit";
- private static final String GROOVY_PREFIX = "G ";
- private static final String LIST_CMD = "list";
- private static final String PROPERTIES_CMD = "properties";
- private static final String WELCOME = "Welcome on your $bind:$port $name server";
- public static final String LINE_SEP = "\r\n"; // don't use line.separator (sshd use this one)
- public static final String OS_LINE_SEP = System.getProperty("line.separator");
- private static final String NAME;
- public static final String PROMPT = "openejb> ";
- static {
- System.setProperty("line.separator", LINE_SEP);
- try {
- // just to force the loading of this class with the set line.separator
- // because ConsoleReader.CR is a constant and we need sometimes another value
- // not a big issue but keeping this as a workaround
- new ConsoleReader();
- } catch (IOException ignored) {
- // no-op
- } finally {
- System.setProperty("line.separator", OS_LINE_SEP);
- }
-
- String name = "OpenEJB";
- try {
- OpenEJBCommands.class.getClassLoader().loadClass("org.apache.tomee.loader.TomcatHook");
- name = "TomEE";
- } catch (ClassNotFoundException cnfe) {
- // ignored, we are using a simple OpenEJB server
- }
- NAME = name;
- }
-
- private OpenEJBGroovyShell shell;
- private OutputStreamWriter serr;
- private OutputStreamWriter sout;
- private OutputStream out;
+public class OpenEJBCommands extends CliRunnable implements Command, Runnable {
private ExitCallback cbk;
- private InputStream sin;
- private String bind;
- private int port;
-
public OpenEJBCommands(String bind, int port) {
- this.bind = bind;
- this.port = port;
+ super(bind, port);
}
@Override
public void setInputStream(InputStream in) {
- sin = in;
+ super.setInputStream(in);
}
@Override
public void setOutputStream(OutputStream out) {
- this.out = out;
- sout = new OutputStreamWriter(out);
+ super.setOutputStream(out);
}
@Override
public void setErrorStream(OutputStream err) {
- serr = new OutputStreamWriter(err);
+ super.setErrorStream(err);
}
@Override
- public void setExitCallback(ExitCallback callback) {
- cbk = callback;
+ public void destroy() {
+ super.destroy();
}
@Override
- public void start(Environment env) throws IOException {
- shell = new OpenEJBGroovyShell();
- new Thread(this, "OpenEJB Groovy Shell " + System.identityHashCode(this)).start();
+ public void setExitCallback(ExitCallback callback) {
+ cbk = callback;
}
@Override
- public void destroy() {
- shell.resetLoadedClasses();
+ public void start(Environment env) throws IOException {
+ start();
}
@Override
public void run() {
try {
-
- final ConsoleReader reader = new ConsoleReader(sin, sout);
- // TODO : add completers with method names...?
-
- String line;
- write(sout, WELCOME // simple replace for now, if it is mandatory we could bring velocity to do it
- .replace("$bind", bind)
- .replace("$port", Integer.toString(port))
- .replace("$name", NAME));
- while ((line = reader.readLine(PROMPT)) != null) {
- if (EXIT_COMMAND.equals(line)) {
- break;
- }
-
- if (line.startsWith(GROOVY_PREFIX)) {
- try {
- write(sout, result(line.substring(GROOVY_PREFIX.length())));
- } catch (SshRuntimeException sshEx) {
- write((Exception) sshEx.getCause());
- }
- } else if (LIST_CMD.equals(line)) {
- list();
- } else if (PROPERTIES_CMD.equals(line)) {
- properties();
- } else {
- write(sout, "sorry i don't understand '" + line + "'");
- }
- }
- } catch (IOException e) {
- throw new SshRuntimeException(e);
+ super.run();
} finally {
cbk.onExit(0);
}
}
-
- private void properties() {
- final OpenEjbConfiguration config = SystemInstance.get().getComponent(OpenEjbConfiguration.class);
- Info2Properties.printConfig(config, new PrintStream(out), LINE_SEP);
- }
-
- private void list() {
- try {
- CommandHelper.listEJBs(LINE_SEP).print(new PrintStream(out));
- } catch (Exception e) {
- write(e);
- }
- }
-
- private static void write(final OutputStreamWriter writer, final String s) {
- for (String l : s.split(LINE_SEP)) {
- try {
- writer.write(l);
- writer.write(LINE_SEP);
- writer.flush();
- } catch (IOException e) {
- // ignored
- }
- }
- }
-
- private void write(Exception e) {
- if (e.getStackTrace() == null) {
- write(serr, e.getMessage());
- } else {
- final StringBuilder error = new StringBuilder();
- for (StackTraceElement elt : e.getStackTrace()) {
- error.append(elt.toString()).append(LINE_SEP);
- }
- write(serr, error.toString());
- }
- }
-
- private String result(final String value) {
- Object out;
- try {
- out = shell.evaluate(value);
- } catch (Exception e) {
- throw new SshRuntimeException(e);
- }
-
- if (out == null) {
- return "null";
- }
- if (out instanceof Collection) {
- final StringBuilder builder = new StringBuilder();
- for (Object o : (Collection) out) {
- builder.append(string(o)).append(LINE_SEP);
- }
- return builder.toString();
- }
- return string(out);
- }
-
- private static String string(Object out) {
- if (!out.getClass().getName().startsWith("java")) {
- return ToStringBuilder.reflectionToString(out, ToStringStyle.SHORT_PREFIX_STYLE);
- }
- return out.toString();
- }
}
Modified: openejb/trunk/openejb/server/openejb-ssh/src/test/java/org/apache/openejb/server/ssh/SSHServerTest.java
URL: http://svn.apache.org/viewvc/openejb/trunk/openejb/server/openejb-ssh/src/test/java/org/apache/openejb/server/ssh/SSHServerTest.java?rev=1232963&r1=1232962&r2=1232963&view=diff
==============================================================================
--- openejb/trunk/openejb/server/openejb-ssh/src/test/java/org/apache/openejb/server/ssh/SSHServerTest.java (original)
+++ openejb/trunk/openejb/server/openejb-ssh/src/test/java/org/apache/openejb/server/ssh/SSHServerTest.java Wed Jan 18 17:24:22 2012
@@ -17,21 +17,30 @@
package org.apache.openejb.server.ssh;
import org.apache.openejb.OpenEjbContainer;
+import org.apache.sshd.ClientChannel;
+import org.apache.sshd.ClientSession;
+import org.apache.sshd.SshClient;
import org.junit.AfterClass;
import org.junit.BeforeClass;
import org.junit.Test;
import javax.ejb.embeddable.EJBContainer;
-import java.io.File;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.io.PipedInputStream;
+import java.io.PipedOutputStream;
import java.util.HashMap;
-import java.util.concurrent.CountDownLatch;
+
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
public class SSHServerTest {
private static EJBContainer container;
@BeforeClass
public static void start() {
- System.setProperty("openejb.server.ssh.key", "target/ssh-key");
+ System.setProperty("openejb.server.ssh.key", "src/test/key/ssh-key");
System.setProperty("openejb.logger.external", "true");
container = EJBContainer.createEJBContainer(new HashMap<Object, Object>() {{
put(OpenEjbContainer.OPENEJB_EMBEDDED_REMOTABLE, "true");
@@ -45,12 +54,59 @@ public class SSHServerTest {
System.getProperties().remove("openejb.server.ssh.key");
}
- @Test
- public void call() {while (Thread.currentThread().isAlive()) try {
- Thread.sleep(100);
- } catch (InterruptedException e) {
- e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates.
+ @Test(timeout = 10000L)
+ public void call() throws Exception {
+ final SshClient client = SshClient.setUpDefaultClient();
+ client.start();
+ try {
+ final ClientSession session = client.connect("localhost", 4222).await().getSession();
+ session.authPassword("jonathan", "secret");
+
+ final ClientChannel channel = session.createChannel("shell");
+ ByteArrayOutputStream sent = new ByteArrayOutputStream();
+ PipedOutputStream pipedIn = new TeePipedOutputStream(sent);
+ channel.setIn(new PipedInputStream(pipedIn));
+ ByteArrayOutputStream out = new ByteArrayOutputStream();
+ ByteArrayOutputStream err = new ByteArrayOutputStream();
+ channel.setOut(out);
+ channel.setErr(err);
+ channel.open();
+
+ pipedIn.write("properties\r\n".getBytes());
+ pipedIn.flush();
+
+ pipedIn.write("exit\r\n".getBytes());
+ pipedIn.flush();
+
+ channel.waitFor(ClientChannel.CLOSED, 0);
+ channel.close(false);
+ client.stop();
+
+ assertTrue(new String(sent.toByteArray()).contains("properties\r\nexit\r\n"));
+ assertTrue(new String(out.toByteArray()).contains("ServerService(id=ssh)"));
+ } catch (Exception e) {
+ e.printStackTrace();
+ fail();
+ }
}
- System.out.println("ok");
+
+ public static class TeePipedOutputStream extends PipedOutputStream {
+ private OutputStream tee;
+
+ public TeePipedOutputStream(OutputStream tee) {
+ this.tee = tee;
+ }
+
+ @Override
+ public void write(int b) throws IOException {
+ super.write(b);
+ tee.write(b);
+ }
+
+ @Override
+ public void write(byte[] b, int off, int len) throws IOException {
+ super.write(b, off, len);
+ tee.write(b, off, len);
+ }
}
}
Added: openejb/trunk/openejb/server/openejb-ssh/src/test/key/ssh-key.ser
URL: http://svn.apache.org/viewvc/openejb/trunk/openejb/server/openejb-ssh/src/test/key/ssh-key.ser?rev=1232963&view=auto
==============================================================================
Binary file - no diff available.
Propchange: openejb/trunk/openejb/server/openejb-ssh/src/test/key/ssh-key.ser
------------------------------------------------------------------------------
svn:mime-type = application/octet-stream
Modified: openejb/trunk/openejb/server/pom.xml
URL: http://svn.apache.org/viewvc/openejb/trunk/openejb/server/pom.xml?rev=1232963&r1=1232962&r2=1232963&view=diff
==============================================================================
--- openejb/trunk/openejb/server/pom.xml (original)
+++ openejb/trunk/openejb/server/pom.xml Wed Jan 18 17:24:22 2012
@@ -44,6 +44,7 @@
<module>openejb-rest</module>
<module>openejb-ssh</module>
<module>openejb-groovy</module>
+ <module>openejb-common-cli</module>
</modules>
</project>