blob: 5dfb2e35fda3c6d2d9abf022deca2770d5a6040b [file] [log] [blame]
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<HTML>
<HEAD>
<!-- $PAGETITLE -->
<TITLE>OpenEJB - Executables</TITLE>
<LINK href="http://openejb.apache.org/all.css" rel="stylesheet" type="text/css">
<!--[if IE]><link rel="stylesheet" type="text/css" media="screen, projection" href="openejb.apache.org/ie.css"><![endif]-->
<LINK rel="SHORTCUT ICON" href="http://openejb.apache.org/images/favicon.ico">
<META http-equiv="Content-Type" content="text/html;charset=UTF-8">
<SCRIPT language="javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.3.1/jquery.min.js" type="text/javascript"></SCRIPT>
<SCRIPT language="javascript" src="http://openejb.apache.org/tweet/jquery.tweet.js" type="text/javascript"></SCRIPT>
<SCRIPT type="text/javascript">
$(document).ready(function(){
$(".tweet").tweet({
avatar_size: 32,
count: 4,
fetch:25,
username: "openejb",
list: "contributors",
template:"{avatar}{text}",
filter: function(t){ return /openejb/i.test(t["tweet_raw_text"]); },
loading_text: "loading list..."
});
});
</SCRIPT>
</HEAD>
<BODY>
<!-- Delay the loading of the external javascript file needed for labels (as it takes too long to load and visibly holds loading of the page body) -->
<!-- To do this without javascript errors over undefined functions, we need to declare stubs here (that are overrided later by the proper implementations) -->
<SCRIPT language="JavaScript" type="text/javascript">
function doAddLabel(hideTextfieldAfterAddParam)
{
// stub
}
function onAddLabel()
{
// stub
}
function showLabelsInput()
{
// stub
}
</SCRIPT>
<A name="top"></A>
<TABLE class="frameTable" cellpadding="0" cellspacing="0" border="0">
<TR class="Row1">
<TD class="Col1"><IMG alt="" src="http://openejb.apache.org/images/dotTrans.gif"></TD>
<TD class="Col2"><IMG alt="" src="http://openejb.apache.org/images/dotTrans.gif"></TD>
<TD class="Col3"><IMG alt="" src="http://openejb.apache.org/images/dotTrans.gif"></TD>
<TD class="Col4"><IMG alt="" src="http://openejb.apache.org/images/dotTrans.gif"></TD>
<TD class="Col5"><IMG alt="" src="http://openejb.apache.org/images/dotTrans.gif"></TD>
</TR>
<TR class="Row2">
<TD class="Col1"><IMG alt="" src="http://openejb.apache.org/images/dotTrans.gif"></TD>
<TD class="Col2">&nbsp;</TD>
<TD class="Col3" id="breadcrumbs">
<!-- $TOP_NAV_BAR -->
<A href="index.html" title="Index">Home</A> | <A href="news.html" title="News">News</A> | <A href="faq.html" title="FAQ">FAQ</A> | <A href="download.html" title="Download">Download</A> | <A href="mailing-lists.html" title="Mailing Lists">Lists</A> | <A href="http://issues.apache.org/jira/browse/OPENEJB" class="external-link" rel="nofollow">Issues</A>
</TD>
<TD class="Col4"><IMG alt="" src="http://openejb.apache.org/images/dotTrans.gif"></TD>
<TD class="Col5">&nbsp;</TD>
</TR>
<TR class="Row3">
<TD class="Col1"><IMG alt="" class="Row3Img" id="thinLine" src="http://openejb.apache.org/images/line_sm.gif"></TD>
<TD class="Col2"><IMG alt="" class="Row3Img" src="http://openejb.apache.org/images/dotTrans.gif"></TD>
<TD class="Col3"><IMG alt="" class="Row3Img" src="http://openejb.apache.org/images/dotTrans.gif"></TD>
<TD class="Col4"><IMG alt="" src="http://openejb.apache.org/images/dotTrans.gif"></TD>
<TD class="Col5"><IMG alt="" class="Row3Img" src="http://openejb.apache.org/images/dotTrans.gif"></TD>
</TR>
<TR class="Row4">
<TD class="Col1">
<SPAN id="Navigation">
<H3><A name="Navigation-Overview"></A>Overview</H3>
<UL class="alternate" type="square">
<LI><A href="index.html" title="Index">Home</A></LI>
<LI><A href="news.html" title="News">News</A></LI>
<LI><A href="faq.html" title="FAQ">FAQ</A></LI>
<LI><A href="download.html" title="Download">Download</A></LI>
<LI><A href="../OPENEJBx30/index.html" title="Index">Documentation</A></LI>
<LI><A href="examples.html" title="Examples">Examples</A></LI>
<LI><A href="http://cwiki.apache.org/confluence/display/OPENEJB/Lightening%20Demos" class="external-link" rel="nofollow">Lightning Demos</A></LI>
<LI><A href="mailing-lists.html" title="Mailing Lists">Mailing Lists</A></LI>
<LI><A href="source-code.html" title="Source Code">Source Code</A></LI>
<LI><A href="http://blogs.apache.org/openejb" class="external-link" rel="nofollow">Project Blog</A></LI>
</UL>
<H3><A name="Navigation-Servers"></A>Servers</H3>
<UL class="alternate" type="square">
<LI><A href="local-server.html" title="Local Server">Local</A></LI>
<LI><A href="remote-server.html" title="Remote Server">Remote</A></LI>
</UL>
<H3><A name="Navigation-Integrations"></A>Integrations</H3>
<UL class="alternate" type="square">
<LI><A href="../OPENEJBx30/tomcat.html" title="Tomcat">Tomcat</A></LI>
<LI><A href="geronimo.html" title="Geronimo">Geronimo</A></LI>
<LI><A href="webobjects.html" title="WebObjects">WebObjects</A></LI>
</UL>
<H3><A name="Navigation-Community"></A>Community</H3>
<UL class="alternate" type="square">
<LI><A href="team.html" title="Team">Team</A></LI>
<LI><A href="articles.html" title="Articles">Articles</A></LI>
<LI><A href="http://webchat.freenode.net/?channels=openejb" class="external-link" rel="nofollow">IRC</A></LI>
</UL>
<H3><A name="Navigation-RelatedProjects"></A>Related Projects</H3>
<UL class="alternate" type="square">
<LI><A href="http://activemq.apache.org/" class="external-link" rel="nofollow">ActiveMQ</A></LI>
<LI><A href="http://openjpa.apache.org/" class="external-link" rel="nofollow">OpenJPA</A></LI>
<LI><A href="http://cxf.apache.org/" class="external-link" rel="nofollow">CXF</A></LI>
</UL>
<H3><A name="Navigation-Index"></A>Index</H3>
<UL class="alternate" type="square">
<LI><A href="space-index.html" title="Space Index">Site Index</A></LI>
<LI><A href="../OPENEJBx30/space-index.html" title="Space Index">Doc Index</A></LI>
</UL>
<H3>
<A name="Navigation-Feeds"></A>
Feeds
</H3>
<UL class="feeds">
<LI>
<A href="http://cwiki.apache.org/confluence/spaces/rss.action?key=OPENEJB&newPages=false">
<IMG src="http://openejb.apache.org/images/rss.gif"></A>
<A class="feedsText" href="http://cwiki.apache.org/confluence/spaces/rss.action?key=OPENEJB&newPages=false">Site</A>
</LI>
<LI><A href="http://cwiki.apache.org/confluence/spaces/blogrss.action?key=OPENEJB">
<IMG src="http://openejb.apache.org/images/rss.gif"></A>
<A class="feedsText" href="http://cwiki.apache.org/confluence/spaces/blogrss.action?key=OPENEJB">News</A>
</LI>
</UL>
</SPAN>
</TD>
<TD class="Col2">&nbsp;</TD>
<TD class="Col3">
<TABLE id="PageHeader" border="0" width="100%">
<TR>
<TD>
<A href="http://openejb.org/">
<IMG hspace="0" src="http://openejb.apache.org/images/logo_openejb.gif" vspace="0">
</A>
</TD>
<TD align="right">
<A href="http://www.apache.org/">
<IMG src="http://www.apache.org/images/asf-logo.gif" width="258" height="66">
</A>
</TD>
</TR>
<TR>
<TD id="page_title">
<!-- $TITLE -->
Executables
</TD>
<TD align="right">
<BR><BR>
<!-- Google CSE Search Box Begins -->
<FORM id="searchbox_010475492895890475512:_t4iqjrgx90" action="http://www.google.com/cse">
<INPUT type="hidden" name="cx" value="010475492895890475512:_t4iqjrgx90">
<INPUT type="hidden" name="cof" value="FORID:0">
<INPUT name="q" type="text" size="25">
<INPUT type="submit" name="sa" value="Search">
</FORM>
<SCRIPT type="text/javascript" src="http://www.google.com/coop/cse/brand?form=searchbox_010475492895890475512:_t4iqjrgx90"></SCRIPT>
<!-- Google CSE Search Box Ends -->
</TD>
</TR>
</TABLE>
<P>
<!-- $BODY -->
<DIV id="PageContent">
<P>This doc describes the design-in-progress for revamping the command-line execution of openejb.</P>
<P>Basic ideas:</P>
<UL>
<LI>Commands can be added/removed (start, stop, test, validate, deploy)</LI>
<LI>Adding/removing only requires adding/removing jars from the classpath</LI>
</UL>
<P>We can stuff properties files into jars at:</P>
<DIV class="code panel" style="border-width: 1px;"><DIV class="codeContent panelContent">
<PRE class="code-java">META-INF/org.openejb.cli/{name}</PRE>
</DIV></DIV>
<P>The propeties file will contain a main.class property, maybe an optional main.method property, and a set of description properties.</P>
<P>Here is an example of the start command:</P>
<P>It would be located at</P>
<DIV class="code panel" style="border-width: 1px;"><DIV class="codeContent panelContent">
<PRE class="code-java">META-INF/org.openejb.cli/start</PRE>
</DIV></DIV>
<DIV class="code panel" style="border-width: 1px;"><DIV class="codeHeader panelHeader" style="border-bottom-width: 1px;"><B>start</B></DIV><DIV class="codeContent panelContent">
<PRE class="code-java">main.class=org.openejb.server.Main
description.en=Starts the Remote Server
description.es=Ejecuta el Servidor Remoto
</PRE>
</DIV></DIV>
<P>We would pull in all these files in the launcher's main method and parse them. If someone typed &quot;openejb --help&quot; then we would list the commands and descriptions.</P>
<H1><A name="Executables-Gettingthepropertiesfiles"></A>Getting the properties files</H1>
<P>Hiram wrote some code like this for activeio</P>
<DIV class="code panel" style="border-width: 1px;"><DIV class="codeHeader panelHeader" style="border-bottom-width: 1px;"><B>FactoryFinder.java</B></DIV><DIV class="codeContent panelContent">
<PRE class="code-java">/**
*
*/
<SPAN class="code-keyword">package</SPAN> org.activeio;
<SPAN class="code-keyword">import</SPAN> java.io.BufferedInputStream;
<SPAN class="code-keyword">import</SPAN> java.io.IOException;
<SPAN class="code-keyword">import</SPAN> java.io.InputStream;
<SPAN class="code-keyword">import</SPAN> java.util.Properties;
<SPAN class="code-keyword">import</SPAN> EDU.oswego.cs.dl.util.concurrent.ConcurrentHashMap;
<SPAN class="code-keyword">public</SPAN> class FactoryFinder {
<SPAN class="code-keyword">private</SPAN> <SPAN class="code-keyword">final</SPAN> <SPAN class="code-object">String</SPAN> path;
<SPAN class="code-keyword">private</SPAN> <SPAN class="code-keyword">final</SPAN> ConcurrentHashMap classMap = <SPAN class="code-keyword">new</SPAN> ConcurrentHashMap();
<SPAN class="code-keyword">public</SPAN> FactoryFinder(<SPAN class="code-object">String</SPAN> path) {
<SPAN class="code-keyword">this</SPAN>.path = path;
}
/**
* Creates a <SPAN class="code-keyword">new</SPAN> instance of the given key
*
* @param key
* is the key to add to the path to find a text file
* containing the factory name
* @<SPAN class="code-keyword">return</SPAN> a newly created instance
*/
<SPAN class="code-keyword">public</SPAN> <SPAN class="code-object">Object</SPAN> newInstance(<SPAN class="code-object">String</SPAN> key) <SPAN class="code-keyword">throws</SPAN> IllegalAccessException, InstantiationException, IOException,
ClassNotFoundException {
<SPAN class="code-keyword">return</SPAN> newInstance(key, <SPAN class="code-keyword">null</SPAN>);
}
<SPAN class="code-keyword">public</SPAN> <SPAN class="code-object">Object</SPAN> newInstance(<SPAN class="code-object">String</SPAN> key, <SPAN class="code-object">String</SPAN> propertyPrefix) <SPAN class="code-keyword">throws</SPAN> IllegalAccessException,
InstantiationException, IOException, ClassNotFoundException {
<SPAN class="code-keyword">if</SPAN> (propertyPrefix == <SPAN class="code-keyword">null</SPAN>)
propertyPrefix = &quot;&quot;;
<SPAN class="code-object">Class</SPAN> clazz = (<SPAN class="code-object">Class</SPAN>) classMap.get(propertyPrefix+key);
<SPAN class="code-keyword">if</SPAN>( clazz == <SPAN class="code-keyword">null</SPAN> ) {
clazz = newInstance(doFindFactoryProperies(key), propertyPrefix);
}
<SPAN class="code-keyword">return</SPAN> clazz.newInstance();
}
<SPAN class="code-keyword">private</SPAN> <SPAN class="code-object">Class</SPAN> newInstance(Properties properties, <SPAN class="code-object">String</SPAN> propertyPrefix) <SPAN class="code-keyword">throws</SPAN> ClassNotFoundException,
InstantiationException, IllegalAccessException, IOException {
<SPAN class="code-object">String</SPAN> className = properties.getProperty(propertyPrefix + <SPAN class="code-quote">&quot;class&quot;</SPAN>);
<SPAN class="code-keyword">if</SPAN> (className == <SPAN class="code-keyword">null</SPAN>) {
<SPAN class="code-keyword">throw</SPAN> <SPAN class="code-keyword">new</SPAN> IOException(<SPAN class="code-quote">&quot;Expected property is missing: &quot;</SPAN> + propertyPrefix + <SPAN class="code-quote">&quot;class&quot;</SPAN>);
}
<SPAN class="code-object">Class</SPAN> clazz;
<SPAN class="code-keyword">try</SPAN> {
clazz = <SPAN class="code-object">Thread</SPAN>.currentThread().getContextClassLoader().loadClass(className);
} <SPAN class="code-keyword">catch</SPAN> (ClassNotFoundException e) {
clazz = FactoryFinder.class.getClassLoader().loadClass(className);
}
<SPAN class="code-keyword">return</SPAN> clazz;
}
<SPAN class="code-keyword">private</SPAN> Properties doFindFactoryProperies(<SPAN class="code-object">String</SPAN> key) <SPAN class="code-keyword">throws</SPAN> IOException, ClassNotFoundException {
<SPAN class="code-object">String</SPAN> uri = path + key;
<SPAN class="code-comment">// lets <SPAN class="code-keyword">try</SPAN> the thread context class loader first
</SPAN> InputStream in = <SPAN class="code-object">Thread</SPAN>.currentThread().getContextClassLoader().getResourceAsStream(uri);
<SPAN class="code-keyword">if</SPAN> (in == <SPAN class="code-keyword">null</SPAN>) {
in = FactoryFinder.class.getClassLoader().getResourceAsStream(uri);
<SPAN class="code-keyword">if</SPAN> (in == <SPAN class="code-keyword">null</SPAN>) {
<SPAN class="code-keyword">throw</SPAN> <SPAN class="code-keyword">new</SPAN> IOException(<SPAN class="code-quote">&quot;Could not find factory class <SPAN class="code-keyword">for</SPAN> resource: &quot;</SPAN> + uri);
}
}
<SPAN class="code-comment">// lets load the file
</SPAN> BufferedInputStream reader = <SPAN class="code-keyword">null</SPAN>;
<SPAN class="code-keyword">try</SPAN> {
reader = <SPAN class="code-keyword">new</SPAN> BufferedInputStream(in);
Properties properties = <SPAN class="code-keyword">new</SPAN> Properties();
properties.load(reader);
<SPAN class="code-keyword">return</SPAN> properties;
} <SPAN class="code-keyword">finally</SPAN> {
<SPAN class="code-keyword">try</SPAN> {
reader.close();
} <SPAN class="code-keyword">catch</SPAN> (Exception e) {
}
}
}
}
</PRE>
</DIV></DIV>
<P>If we used a class similar to that, we could get the commands like such:</P>
<DIV class="code panel" style="border-width: 1px;"><DIV class="codeHeader panelHeader" style="border-bottom-width: 1px;"><B>Main.java</B></DIV><DIV class="codeContent panelContent">
<PRE class="code-java">FactoryFinder finder = <SPAN class="code-keyword">new</SPAN> FactoryFinder(<SPAN class="code-quote">&quot;META-INF/org.openejb.cli/&quot;</SPAN>);
Properties props = finder.doFindFactoryProperies(<SPAN class="code-quote">&quot;start&quot;</SPAN>)
commands.put(<SPAN class="code-quote">&quot;start&quot;</SPAN>,props);
<SPAN class="code-comment">// we should <SPAN class="code-keyword">try</SPAN> and load them all into properties instances and map them in advance
</SPAN>
<SPAN class="code-comment">//.. later to list help
</SPAN><SPAN class="code-object">String</SPAN> local = <SPAN class="code-comment">//get the i18n 2 character local (en, es, fr...)
</SPAN>
<SPAN class="code-keyword">for</SPAN> each commands.entrySet() ... {
Map.Entry entry = commandEntries.next();
<SPAN class="code-object">String</SPAN> command = entry.getKey();
Properties props = (Properties) entry.getValue();
<SPAN class="code-object">String</SPAN> description = props.getProperty(<SPAN class="code-quote">&quot;description.&quot;</SPAN>+local, props.getProperty(<SPAN class="code-quote">&quot;description&quot;</SPAN>));
<SPAN class="code-object">System</SPAN>.out.print(<SPAN class="code-quote">&quot; &quot;</SPAN>+command+<SPAN class="code-quote">&quot;\t&quot;</SPAN>+description);
}
<SPAN class="code-comment">//.. later to execute a command
</SPAN>Properties props = (Properties)commands.get(<SPAN class="code-quote">&quot;start&quot;</SPAN>);
<SPAN class="code-object">String</SPAN> mainClass = props.getProperty(<SPAN class="code-quote">&quot;main.class&quot;</SPAN>);
<SPAN class="code-object">Class</SPAN> clazz = getClassLoader().loadClass(mainClass);
Method mainMethod = clazz.getMethod(<SPAN class="code-quote">&quot;main&quot;</SPAN>, <SPAN class="code-keyword">new</SPAN> <SPAN class="code-object">Class</SPAN>[]{<SPAN class="code-object">String</SPAN>[].class});
mainMethod.invoke(args); <SPAN class="code-comment">// obviously the <SPAN class="code-quote">&quot;start&quot;</SPAN> arg has been shaved off first</SPAN>
</PRE>
</DIV></DIV>
<H1><A name="Executables-Actualimplementation"></A>Actual implementation</H1>
<P>I took a different approach. Since we won't use this class to actually return a class loaded from the properties file, I made minor changes. I also made the CommandFinder.java capable of finding all possible command homes so that others wouldn't have to implement it themselves. Also, the CommandFinder will automatically set the openejb.home. The idea is that we may be able to get rid of all of the scripts checking for OPENEJB_HOME for us. This is the initial concept so please make changes or suggestions.</P>
<DIV class="code panel" style="border-width: 1px;"><DIV class="codeHeader panelHeader" style="border-bottom-width: 1px;"><B>CommandFinder.java</B></DIV><DIV class="codeContent panelContent">
<PRE class="code-java"><SPAN class="code-keyword">package</SPAN> org.openejb.cli;
<SPAN class="code-keyword">import</SPAN> java.io.BufferedInputStream;
<SPAN class="code-keyword">import</SPAN> java.io.File;
<SPAN class="code-keyword">import</SPAN> java.io.IOException;
<SPAN class="code-keyword">import</SPAN> java.io.InputStream;
<SPAN class="code-keyword">import</SPAN> java.net.URL;
<SPAN class="code-keyword">import</SPAN> java.util.Collections;
<SPAN class="code-keyword">import</SPAN> java.util.Enumeration;
<SPAN class="code-keyword">import</SPAN> java.util.HashMap;
<SPAN class="code-keyword">import</SPAN> java.util.Map;
<SPAN class="code-keyword">import</SPAN> java.util.Properties;
<SPAN class="code-keyword">public</SPAN> class CommandFinder {
<SPAN class="code-keyword">private</SPAN> <SPAN class="code-object">String</SPAN> path;
<SPAN class="code-keyword">private</SPAN> Map classMap = Collections.synchronizedMap(<SPAN class="code-keyword">new</SPAN> HashMap());
<SPAN class="code-keyword">public</SPAN> CommandFinder(<SPAN class="code-object">String</SPAN> path) {
<SPAN class="code-keyword">this</SPAN>.path = path;
}
<SPAN class="code-keyword">public</SPAN> Properties doFindCommandProperies(<SPAN class="code-object">String</SPAN> key) <SPAN class="code-keyword">throws</SPAN> IOException {
<SPAN class="code-object">String</SPAN> uri = path + key;
<SPAN class="code-comment">// lets <SPAN class="code-keyword">try</SPAN> the thread context class loader first
</SPAN> InputStream in = <SPAN class="code-object">Thread</SPAN>.currentThread().getContextClassLoader().getResourceAsStream(uri);
<SPAN class="code-keyword">if</SPAN> (in == <SPAN class="code-keyword">null</SPAN>) {
in = CommandFinder.class.getClassLoader().getResourceAsStream(uri);
<SPAN class="code-keyword">if</SPAN> (in == <SPAN class="code-keyword">null</SPAN>) {
<SPAN class="code-keyword">throw</SPAN> <SPAN class="code-keyword">new</SPAN> IOException(<SPAN class="code-quote">&quot;Could not find factory class <SPAN class="code-keyword">for</SPAN> resource: &quot;</SPAN> + uri);
}
}
<SPAN class="code-comment">// lets load the file
</SPAN> BufferedInputStream reader = <SPAN class="code-keyword">null</SPAN>;
<SPAN class="code-keyword">try</SPAN> {
reader = <SPAN class="code-keyword">new</SPAN> BufferedInputStream(in);
Properties properties = <SPAN class="code-keyword">new</SPAN> Properties();
properties.load(reader);
<SPAN class="code-comment">//All is well, set openejb.home
</SPAN> URL propsURL = <SPAN class="code-object">Thread</SPAN>.currentThread().getContextClassLoader().getResource(uri);
<SPAN class="code-object">String</SPAN> propsString = propsURL.getFile();
URL jarURL;
File jarFile;
propsString = propsString.substring(0, propsString.indexOf(<SPAN class="code-quote">&quot;!&quot;</SPAN>));
jarURL = <SPAN class="code-keyword">new</SPAN> URL(propsString);
jarFile = <SPAN class="code-keyword">new</SPAN> File(jarURL.getFile());
<SPAN class="code-keyword">if</SPAN> (jarFile.getName().indexOf(<SPAN class="code-quote">&quot;openejb-core&quot;</SPAN>) &gt; -1) {
File lib = jarFile.getParentFile();
File home = lib.getParentFile();
<SPAN class="code-object">System</SPAN>.setProperty(<SPAN class="code-quote">&quot;openejb.home&quot;</SPAN>, home.getAbsolutePath());
}
<SPAN class="code-keyword">return</SPAN> properties;
} <SPAN class="code-keyword">finally</SPAN> {
<SPAN class="code-keyword">try</SPAN> {
reader.close();
} <SPAN class="code-keyword">catch</SPAN> (Exception e) {
}
}
}
<SPAN class="code-keyword">public</SPAN> Enumeration doFindCommands() <SPAN class="code-keyword">throws</SPAN> IOException {
<SPAN class="code-keyword">return</SPAN> <SPAN class="code-object">Thread</SPAN>.currentThread().getContextClassLoader().getResources(path);
}
}
</PRE>
</DIV></DIV>
<H1><A name="Executables-CurrentImplementationUsage"></A>Current Implementation Usage</H1>
<P>The usage for this is the same as before but you would use the following approach to run instead of the OPENEJB_HOME/bin/openejb command:</P>
<DIV class="code panel" style="border-width: 1px;"><DIV class="codeHeader panelHeader" style="border-bottom-width: 1px;"><B>Usage</B></DIV><DIV class="codeContent panelContent">
<PRE class="code-java">java -jar OPENEJB_HOME/lib/openejb-core-&lt;VERSION&gt;.jar
</PRE>
</DIV></DIV>
<P>Eventually, once David and I talk, we will wrap this in a script, like we do now. Right now, only the core commands are implemented:</P>
<UL>
<LI>deploy</LI>
<LI>help</LI>
<LI>start</LI>
<LI>stop</LI>
<LI>validate</LI>
</UL>
<H1><A name="Executables-CurrentQuestionsBeforeIntegratingIntoMainstream"></A>Current Questions Before Integrating Into Mainstream</H1>
<UL>
<LI>Classpath - Will the command implementors be responsible for managing their classpath?</LI>
<LI>Logging - Will we log errors in the CommandFinder.java or continue as-is outputting StackTrace and OpenEJB messages</LI>
<LI>Handling non-core command - We should have an OPENEJB_HOME/lib/etc where all 3rd party commands, like tests, can house their jars. We need a standard location so the code can just work without the user having to add things to the classpath manually</LI>
<LI>Wrapping in script - We will eventually wrap our executable jar in a script.</LI>
</UL>
<H1><A name="Executables-Help%21"></A>Help!</H1>
<P>openejb --help<BR>
(list the commands and descriptions)</P>
<P>This would be the job of the main class of the launcher. It would find all the commands in the system, and list their names and print their &quot;description&quot; property.</P>
<P>openejb start --help <BR>
(list the start help text)</P>
<P>The main class of the launcher would do nothing with this. The start command would need to grab it's help text and print it to the system.out. Yes, this is extra work, but the various commands already support this. Also, at some point we won't have the help text as is and will use commons.cli to create the text.</P>
</DIV>
</P>
</TD>
<TD class="Col4"><IMG src="http://openejb.apache.org/images/dotTrans.gif"></TD>
<TD class="Col5">
</TD>
</TR>
<TR class="Row5">
<TD class="Col1">&nbsp;</TD>
<TD class="Col2">&nbsp;</TD>
<TD class="Col3">
<BR>
<BR>
<IMG width="100%" height="1" src="http://openejb.apache.org/images/line_light.gif">
<TABLE width="100%">
<TR>
<TD>
<SPAN class="bodyGrey">
<SMALL>
<NOTICE><!-- $FOOTER -->
Apache OpenEJB is an project of The Apache Software Foundation (ASF)
</NOTICE>
<BR>
Site Powered by
<A href="http://atlassian.com/">Atlassian</A>
<A href="http://atlassian.com/confluence/">Confluence</A>
.
</SMALL>
</SPAN>
</TD>
<TD align="right">
<A style="color:#999;font-size:small;font-weight:normal;" href="https://cwiki.apache.org/confluence/pages/editpage.action?spaceKey=OPENEJB&title=Executables">[ edit ]</A>
</TD>
</TR>
</TABLE>
<BR>
</TD>
<TD class="Col4"><IMG src="http://openejb.apache.org/images/dotTrans.gif"></TD>
<TD class="Col5">&nbsp;</TD>
</TR>
</TABLE>
<!-- Needed for composition plugin -->
<!-- delay the loading of large javascript files to the end so that they don't interfere with the loading of page content -->
<SPAN style="display: none">
<SCRIPT type="text/javascript" language="JavaScript" src="http://cwiki.apache.org/confluence/labels-javascript"></SCRIPT>
<SCRIPT src="http://www.google-analytics.com/urchin.js" type="text/javascript">
</SCRIPT>
<SCRIPT type="text/javascript">
_uacct = "UA-2717626-1";
urchinTracker();
</SCRIPT>
</SPAN>
</BODY>
</HTML>