Peter,
It doesn't look like there is any plaform specific code in the current
build.xml, but it is fairly easy to add checks for the platform so that
the correct scripts are copied into the dist/bin directory for each
platform.

Let me know what you think, and I can make the changes for you.

patches gladly accepted ;)
I am sending you a modified build.xml which sets up all of the scripts used to launch Phoenix on the different platforms. The user always runs "build main", which depends on the "dist-lite-wrapper" task. ÂThis task then sets up the Wrapper using the files for the current platform, whatever that may be.

This build now does everything based on the wrapper.home property, so the others can be removed from ant.properties.sample

...
# ----- Java Service Wrapper, version 2.2.4 or later -----
wrapper.home=${base.path}/wrapper_linux_2.2.4
...

This build file will work with the Windows version of the 2.2.3 wrapper, but it needs the 2.2.4 version for Unix versions because of a bug when the APP_NAME is different from the name of the script used to launch the Wrapper. ÂIn this case, Phoenix and phoenix.so

We just released version 2.2.4 for all three platforms. ÂThis release contains several other fixes and the logging feature request that you had.

I am also resending the new wrapper.conf as well as the DaemonLoader class.

Before you commit these things though, I did have a problem.

On Windows, everything is working correctly, but on the Linux version, I get the following stack dump if I launch the wrapper with only wrapper.jar and phoenix-loader.jar in the classpath:
Exception in thread "main" java.lang.NoClassDefFoundError: org/apache/avalon/framework/activity/Executable
jvm 1    |      at java.lang.Class.getMethod0(Native Method)
jvm 1    |      at java.lang.Class.getMethod(Class.java:920)
jvm 1    |      at org.apache.avalon.phoenix.launcher.DaemonLauncher.main(DaemonLauncher.java:108)
This is happening on  the following line, taken straight out of Main.java:
final Class[] paramTypes = new Class[] { args.getClass(), Hashtable.class };
mainMethod = clazz.getMethod( "main", paramTypes );

Adding ../lib/avalon-framework-20011110.jar to the classpath, makes the problem go away.

This was being caused by the following line in CLIMain.java
private Embeddor m_embeddor;
For some reason, the getMethod method is hidding this field and failing because it could not load one of the Embeddor's superclasses. I am attaching a version of CLIMain which abstracts this reference to make things work correctly with reflection.
private Object m_embeddor;

The thing that I do not understand is why this works when called from the Main class and not from DaemonLauncher. The code is identical. It seems like it should not ever have been working...

You may know the reason, if so please le t me know.


Also I wondering. What about the idea of having anÂ'init' or 'libsu' directory or something where the phoenix-engine.jar, phoenix-loader.jar, wrapper.jar, wrapper.conf and Wrapper.dll could be located. Also place wrapper.log into the logs directory. That would help clear up the clutter in the bin directory.

The final file contains all of the diffs

Cheers,
Leif

#********************************************************************
# Wrapper parameters
#********************************************************************
# Java Application
wrapper.java.command=java

# Java Main class
wrapper.java.mainclass=org.apache.avalon.phoenix.launcher.DaemonLauncher

# Java Classpath (include wrapper.jar)  Add class path elements as 
wrapper.java.classpath.1=phoenix-loader.jar
wrapper.java.classpath.2=wrapper.jar
#wrapper.java.classpath.3=../lib/avalon-framework-20011110.jar

# Java Library Path (location of wrapper.lib)
wrapper.java.library.path=./

# Java Additional Parameters
wrapper.java.additional.1=-Djava.ext.dirs=..\lib
wrapper.java.additional.2=-Dphoenix.home=..
#wrapper.java.additional.3=-Djava.security.policy=jar:file:../bin/wrapper-loader.jar!/META-INF/java.policy
#wrapper.java.additional.4=-Djava.security.manager

# Initial Java Heap Size (in MB)
wrapper.java.initmemory=16

# Maximum Java Heap Size (in MB)
wrapper.java.maxmemory=64

# Application parameters.  Add parameters as needed starting from 1
#wrapper.app.parameter.1=

# Port which the native wrapper code will attempt to connect to
wrapper.port=15012

# Number of seconds to allow for the JVM to be launched and contact the wrapper 
before the
#  wrapper should assume that the JVM is hung and terminate the JVM process.  0 
means never
#  time out.  Defaults to 30 seconds.
wrapper.startup.timeout=30

# Number of seconds to allow between the wrapper pinging the JVM and the 
#  response.  0 means never time out.  Defaults to 30 seconds.
wrapper.ping.timeout=30

# The Wrapper detects when an application calls System.exit() and treats this 
as a request
#  to stop the server by default.
#wrapper.disable_shutdown_hook=TRUE

#********************************************************************
# Wrapper Logging parameters
#********************************************************************
# Log file to use for wrapper output logging.
wrapper.logfile=wrapper.log

# Format of output for the log file.  (See docs for formats)
wrapper.logfile.format=PTM

# Format of output for the log file.  (See docs for formats)
wrapper.console.format=PM

# Show debug messages
#wrapper.debug=TRUE

#********************************************************************
# Wrapper Unix daemon parameters
#********************************************************************
# File to write process ID to
wrapper.pidfile=var/run/phoenix.pid

#********************************************************************
# Wrapper NT Service parameters
#********************************************************************
# WARNING - Do not modify any of these parameters when an application
#  using this configuration file has been installed as a service.
#  Please uninstall the service before modifing this section.  The
#  service can then be reinstalled.

# Name of the service
wrapper.ntservice.name=Phoenix

# Display name of the service
wrapper.ntservice.displayname=Phoenix Application Server

# Service dependencies.  Add dependencies as needed starting from 1
wrapper.ntservice.dependency.1=

# Mode in which the service is installed.  AUTO_START or DEMAND_START
wrapper.ntservice.starttype=AUTO_START
<?xml version="1.0"?>

<!--
==============================================================================

 Phoenix build file

Authors:
 Federico Barbieri <[EMAIL PROTECTED]>
 Berin Loritsch <[EMAIL PROTECTED]>
 Peter Donald <[EMAIL PROTECTED]>
 Leo Simons <[EMAIL PROTECTED]>

Legal:
  Copyright (c) 1999-2001 The Apache Software Foundation. All Rights Reserved.

==============================================================================
-->

<project default="main" basedir=".">

  <!--
    Give user a chance to override without editing this file
    (and without typing -D each time he compiles it)
  -->
  <property file=".ant.properties"/>
  <property file="${user.home}/.ant.properties"/>

  <!-- platform -->
  <property name="is.${os.name}" value="true"/>

  <property name="name" value="phoenix"/>
  <property name="Name" value="Phoenix"/>
  <property name="version" value="4.0a4"/>
  <property name="year" value="1999-2001"/>
  <property name="status" value="alpha"/>
  <property name="release" value="4th"/>
  <property name="short.version" value="4.0a"/>

  <property name="build.debug" value="on"/>
  <property name="build.optimize" value="off"/>
  <property name="build.deprecation" value="off"/>

  <!-- Set the properties for intermediate directory -->
  <property name="build.dir" value="build"/>
  <property name="build.lib" value="${build.dir}/lib"/>
  <property name="build.src" value="${build.dir}/src"/>
  <property name="build.classes" value="${build.dir}/classes"/>
  <property name="build.javadocs" value="${build.dir}/javadocs"/>
  <property name="build.docs" value="${build.dir}/docs"/>
  <property name="build.context" value="${build.dir}/documentation"/>
  <property name="build.xdocs" value="${build.context}/xdocs"/>

  <!-- Set the properties for source directories -->
  <property name="src.dir" value="src"/>
  <property name="java.dir" value="${src.dir}/java"/>
  <property name="conf.dir" value="${src.dir}/conf"/>
  <property name="script.dir" value="${src.dir}/script"/>
  <property name="manifest.dir" value="${src.dir}/manifest"/>
  <property name="lib.dir" value="lib"/>
  <property name="tools.dir" value="../jakarta-avalon/tools"/>
  <property name="docs.dir" value="docs"/>
  <property name="www.dir" value="../jakarta-avalon-site/docs/${name}"/>
  <property name="avalon.skin" value="${tools.dir}/lib/jakarta-style.jar"/>
  <property name="xdocs.dir" value="${src.dir}/xdocs"/>
  <property name="javadocs.dir" value="${docs.dir}/api"/>
  <property name="context.dir" value="../jakarta-avalon/src/documentation"/>

  <property name="dist.name" value="${name}-${version}"/>
  <property name="dist.base" value="distributions"/>
  <property name="bin.dist.dir" value="dist"/>
  <property name="src.dist.dir" value="${dist.name}"/>

  <property name="constants.file" value="org/apache/avalon/phoenix/Constants.java"/>
  <property name="xerces.dir" value="${lib.dir}"/>
  <property name="xerces.file" value="xerces.jar"/>
  <property name="xerces.jar" value="${xerces.dir}/${xerces.file}"/>
  <property name="xalan.jar" value="${tools.dir}/lib/xalan-2.2.0-D8.jar"/>
  <property name="framework.jar" value="${lib.dir}/avalon-framework-20011110.jar"/>
  <property name="excalibur.jar" value="${lib.dir}/avalon-excalibur-20011120.jar"/>
  <property name="scratchpad.jar" value="${lib.dir}/avalon-scratchpad-20011122.jar"/>
  <property name="logkit.jar" value="${lib.dir}/logkit-1.0.jar"/>
  <property name="jmxri.jar" value="${lib.dir}/jmxri.jar"/>
  <property name="jmxtools.jar" value="${lib.dir}/jmxtools.jar"/>
  <property name="tools.jar" value="${java.home}/../lib/tools.jar"/>

  <property name="announce2txt" value="${tools.dir}/announcement2txt.xsl"/>
  <property name="announce2header" value="${tools.dir}/announcement2header.xsl"/>
  <property name="announce2readme" value="${tools.dir}/announcement2readme.xsl"/>
  <property name="announce2site" value="${tools.dir}/announcement2site.xsl"/>

  <path id="project.class.path">
    <pathelement location="${xerces.jar}"/>
    <pathelement location="${framework.jar}"/>
    <pathelement location="${excalibur.jar}"/>
    <pathelement location="${scratchpad.jar}"/>
    <pathelement location="${logkit.jar}"/>
    <pathelement location="${jmxri.jar}"/>
    <pathelement location="${jmxtools.jar}"/>
    <pathelement location="${wrapper.home}/lib/wrapper.jar"/>
    <pathelement path="${java.class.path}" />
    <fileset dir="${lib.dir}">
      <include name="*.jar" />
    </fileset>
    <pathelement path="${build.classes}" />
  </path>

  <path id="tools.class.path">
    <pathelement location="${xerces.jar}"/>
    <pathelement location="${xalan.jar}"/>
    <pathelement location="${tools.jar}"/>
    <fileset dir="${tools.dir}/lib">
      <exclude name="ant.jar" />
    </fileset>
  </path>

  <!-- Main target -->
  <target name="main" depends="dist-lite-wrapper" 
          description="generates the Phoenix distribution using the wrapper, without the javadocs"/>
  <target name="all" depends="dist-lite,docs" description="generates the Phoenix distribution" />

  <!-- Help on usage -->
  <target name="usage">
    <echo message="Use the -projecthelp option instead"/>
  </target>

  <target name="help" depends="usage"/>
  
  <!-- Resolve Platform properties -->
  <target name="init-windows-nt" if="is.Windows NT">
    <property name="is.Windows" value="true"/>
    <available property="is.Windows.wrapper.present" classname="com.silveregg.wrapper.WrapperManager">
      <classpath refid="project.class.path"/>
    </available>
  </target>
  <target name="init-windows-2000" if="is.Windows 2000">
    <property name="is.Windows" value="true"/>
    <available property="is.Windows.wrapper.present" classname="com.silveregg.wrapper.WrapperManager">
      <classpath refid="project.class.path"/>
    </available>
  </target>
  <target name="init-linux" if="is.Linux">
    <property name="is.Unix" value="true"/>
    <available property="is.Linux.wrapper.present" classname="com.silveregg.wrapper.WrapperManager">
      <classpath refid="project.class.path"/>
    </available>
  </target>
  <target name="init-solaris" if="is.SunOS">
    <property name="is.Unix" value="true"/>
    <available property="is.SunOS.wrapper.present" classname="com.silveregg.wrapper.WrapperManager">
      <classpath refid="project.class.path"/>
    </available>
  </target>
  <target name="init" depends="init-windows-nt, init-windows-2000, init-linux, init-solaris">
  </target>

  <!-- Check requirements of environment -->
  <target name="check-environment" depends="init">
    <available property="xerces.present" type="file" file="${xerces.jar}"/>
    <available property="servlet.present" classname="javax.servlet.Servlet">
      <classpath refid="project.class.path"/>
    </available>
    <available property="jmx.present" classname="javax.management.MBeanException">
      <classpath refid="project.class.path"/>
    </available>
    <available property="wrapper.present" classname="com.silveregg.wrapper.WrapperManager">
      <classpath refid="project.class.path"/>
    </available>
  </target>

  <!-- Setup the filters -->
  <target name="setup-filters">
    <filter token="Name" value="Avalon Phoenix"/>
    <filter token="name" value="phoenix"/>
    <filter token="version" value="${version}"/>
    <filter token="year" value="${year}"/>
    <filter token="status" value="${status}"/>
    <filter token="release" value="${release}"/>
    <filter token="short-version" value="${short.version}"/>

    <property name="avalon.base" value="http://jakarta.apache.org/avalon"/>
    <property name="framework.base" value="http://jakarta.apache.org/avalon/framework"/>
    <property name="phoenix.base" value="http://jakarta.apache.org/avalon/phoenix"/>
    <property name="cornerstone.base" value="http://jakarta.apache.org/avalon/cornerstone"/>
    <property name="logkit.base" value="http://jakarta.apache.org/avalon/logkit"/>
    <property name="testlet.base" value="http://jakarta.apache.org/avalon/testlet"/>

    <filter token="year" value="${year}"/>
    <filter token="AVALON_BASE" value="${avalon.base}"/>
    <filter token="FRAMEWORK_BASE" value="${framework.base}"/>
    <filter token="PHOENIX_BASE" value="${phoenix.base}"/>
    <filter token="CORNERSTONE_BASE" value="${cornerstone.base}"/>
    <filter token="LOGKIT_BASE" value="${logkit.base}"/>
    <filter token="TESTLET_BASE" value="${testlet.base}"/>
    
    <!-- Wrapper filters -->
    <filter token="app.name" value="phoenix"/>
    <filter token="app.long.name" value="Phoenix Application Server"/>
  </target>

  <!-- Prepares the build directory -->
  <target name="prepare" depends="check-environment">

    <mkdir dir="${build.src}"/>
    <copy todir="${build.src}">
      <fileset dir="${java.dir}">
        <include name="${constants.file}" />
      </fileset>
    </copy>

    <tstamp/>
    <replace file="${build.src}/${constants.file}" token="@@VERSION@@" value="${version}"/>
    <replace file="${build.src}/${constants.file}" token="@@NAME@@" value="${Name}"/>
    <replace file="${build.src}/${constants.file}" token="@@DATE@@" value="${TODAY}"/>

  </target>

  <!-- Create the announcements and HEADER.html -->
  <target name="changelog" depends="setup-filters">

    <taskdef name="clog" classname="org.apache.tools.ant.taskdefs.ChangeLog">
      <classpath refid="tools.class.path"/>
    </taskdef>

    <!-- Build change log -->
    <clog basedir="." output="ChangeLog" userlist="${tools.dir}/Users.properties" />

    <style in="ChangeLog" style="${tools.dir}/changelog.xsl" out="ChangeLog.html">
      <param name="module" expression="'jakarta-avalon-phoenix'"/>
      <param name="cvsweb" expression="'http://cvs.apache.org/viewcvs.cgi'"/>
    </style>

  </target>

  <!-- Create the announcements and HEADER.html -->
  <target name="announcement" depends="setup-filters">

    <mkdir dir="${build.dir}" />
    <mkdir dir="${dist.base}" />

    <copy todir="${build.context}" filtering="on">
      <fileset dir="${context.dir}">
        <exclude name="diagrams/**"/>
        <exclude name="resources/**"/>
        <exclude name="xdocs/**"/>
      </fileset>
    </copy>

    <copy todir="${build.xdocs}" filtering="on">
      <fileset dir="${xdocs.dir}"/>
    </copy>

    <style style="${announce2txt}" in="${build.context}/xdocs/announcement.xml" 
           out="Announcement.txt"/>
    <style style="${announce2header}" in="${build.context}/xdocs/announcement.xml" 
           out="${dist.base}/HEADER.html"/>
    <style style="${announce2readme}" in="${build.context}/xdocs/announcement.xml"
           out="${dist.base}/README.html"/>
    <style style="${announce2site}" in="${build.context}/xdocs/announcement.xml"
           out="jakarta-news.xml"/>

  </target>

  <!-- Compiles the source code -->
  <target name="compile" depends="prepare" description="compiles the source code">

    <mkdir dir="${build.classes}"/>

    <javac srcdir="${java.dir}"
           destdir="${build.classes}"
           debug="${build.debug}"
           optimize="${build.optimize}"
           deprecation="${build.deprecation}">
      <classpath refid="project.class.path" />
      <src path="${build.src}" />
      <exclude name="${constants.file}" />
      <exclude name="org/apache/avalon/phoenix/frontends/PhoenixServlet.java" unless="servlet.present"/>
      <exclude name="org/apache/avalon/phoenix/frontends/ComposableServlet.java" unless="servlet.present"/>
      <exclude name="org/apache/jmx/**" unless="jmx.present"/>
      <exclude name="**/*MBean.java" unless="jmx.present"/>
      <exclude name="org/apache/avalon/phoenix/components/manager/DefaultManager.java" 
               unless="jmx.present"/>
      <exclude name="org/apache/avalon/phoenix/launcher/DaemonLauncher.java" 
               unless="wrapper.present"/>
    </javac>

    <copy todir="${build.classes}">
      <fileset dir="${java.dir}">
        <include name="**/*.properties" />
      </fileset>
    </copy>

  </target>

  <target name="rmic" depends="compile" if="jmx.present"
          description="runs rmic on JMX Adaptor">

    <rmic base="${build.classes}" 
          classname="org.apache.jmx.adaptor.RMIAdaptorImpl" 
          stubVersion="1.2">
      <classpath refid="project.class.path" />
    </rmic>

  </target>

  <!-- Create the API documentation -->
  <target name="javadocs" description="generates the API documentation">

    <delete dir="${build.javadocs}"/>
    <mkdir dir="${build.javadocs}"/>

    <javadoc packagenames="org.apache.*"
             sourcepath="${java.dir}"
             destdir="${build.javadocs}">
      <classpath refid="project.class.path" />
      <doclet name="com.sun.tools.doclets.standard.Standard">
       <param name="-author"/>
       <param name="-version"/>
       <param name="-doctitle" value="${Name}"/>
       <param name="-windowtitle" value="${Name} API"/>
       <param name="-bottom" 
              value="&quot;Copyright &#169; 2001 Apache Jakarta Project. All Rights Reserved.&quot;"/>
      </doclet>
    </javadoc>

  </target>

  <!-- Create the Local API documentation -->
  <target name="local-javadocs" depends="javadocs">

    <delete dir="${javadocs.dir}"/>
    <mkdir dir="${javadocs.dir}"/>

    <copy todir="${javadocs.dir}">
      <fileset dir="${build.javadocs}" />
    </copy>

  </target>

  <target name="printer-friendly" depends="javadocs">
    <echo message="Printer friendly documentation is not available right now."/>
  </target>

  <!-- Prepares the documentation directory -->
  <target name="docs" depends="setup-filters,javadocs" description="generates the Phoenix documentation">

    <mkdir dir="${build.context}"/>
    <mkdir dir="${build.xdocs}"/>
    <mkdir dir="${build.docs}"/>
    <mkdir dir="${build.dir}/work"/>

    <!-- Base pointers for non-xdocs documentation. Override these in .ant.properties to link to local docs -->
    <copy todir="${build.context}" filtering="on">
      <fileset dir="${context.dir}">
        <exclude name="diagrams/**"/>
        <exclude name="resources/**"/>
        <exclude name="xdocs"/>
      </fileset>
    </copy>

    <copy todir="${build.context}/xdocs" filtering="on" overwrite="yes">
      <fileset dir="${xdocs.dir}"/>
    </copy>

    <copy todir="${build.context}/resources" filtering="off" overwrite="yes">
      <fileset dir="${context.dir}/resources"/>
      <fileset dir="${xdocs.dir}">
        <include name="**/images/**"/>
      </fileset>
    </copy>

    <java classname="org.apache.cocoon.Main" fork="true">
      <arg value="-c${build.context}/"/>
      <arg value="-d${build.docs}"/>
      <arg value="-w${build.dir}/work"/>
      <arg value="-l${build.dir}/work/cocoon.log"/>
      <arg value="-uINFO"/>
      <arg value="-f${xdocs.dir}/phoenix.uris"/>
      <classpath>
        <path refid="tools.class.path"/>
        <fileset dir="${tools.dir}/ext"/>
      </classpath>
    </java>
  </target>

  <!-- Create the Local site documentation -->
  <target name="local-xdocs" depends="docs">

    <delete>
      <fileset dir="${docs.dir}">
        <exclude name="api/**"/>
      </fileset>
    </delete>
    <mkdir dir="${docs.dir}"/>

    <copy todir="${docs.dir}">
      <fileset dir="${build.docs}" />
    </copy>

  </target>

  <target name="local-docs" depends="local-javadocs,local-xdocs"/>

  <!-- Update the www directory -->
  <target name="site-docs" depends="local-docs">

    <mkdir dir="${www.dir}"/>

    <!-- delete all old documents but keep CVS directories -->
    <!-- note that by doing an include the defaultexcludes (CVS dirs) will be kept -->
    <delete>
      <fileset dir="${www.dir}">
        <include name="**"/>
      </fileset>
    </delete>

    <mkdir dir="${www.dir}"/>
    <copy todir="${www.dir}">
      <fileset dir="${docs.dir}" />
    </copy>

  </target>

  <!-- Creates all the .jar files -->
  <target name="jars" depends="rmic">

    <mkdir dir="${build.lib}"/>

    <jar jarfile="${build.lib}/phoenix-client.jar" basedir="${build.classes}">
      <include name="org/apache/avalon/phoenix/*"/>
      <include name="org/apache/avalon/phoenix/metainfo/**"/>
      <include name="org/apache/avalon/phoenix/metadata/**"/>
      <include name="org/apache/avalon/phoenix/tools/**"/>
    </jar>

    <jar jarfile="${build.lib}/phoenix-loader.jar"
         basedir="${build.classes}"
         manifest="${manifest.dir}/loader-Manifest.mf" >
      <include name="org/apache/avalon/phoenix/launcher/**"/>

      <zipfileset dir="${conf.dir}" prefix="META-INF/">
        <include name="java.policy"/>
      </zipfileset>
    </jar>

    <jar jarfile="${build.lib}/avalon-jmx.jar" basedir="${build.classes}">
      <include name="org/apache/jmx/**" />
    </jar>

    <jar jarfile="${build.lib}/phoenix-engine.jar"
         basedir="${build.classes}"
         manifest="${manifest.dir}/engine-Manifest.mf" >

      <include name="org/apache/avalon/phoenix/engine/**"/>
      <include name="org/apache/avalon/phoenix/frontends/**"/>
      <include name="org/apache/avalon/phoenix/components/**"/>
      <include name="org/apache/avalon/phoenix/interfaces/**"/>
      <exclude name="org/apache/avalon/phoenix/launcher/**"/>
    </jar>

  </target>

  <!-- Create the lite build -->
  <target name="dist-lite" depends="jars" 
          description="generates the Phoenix distribution without the javadocs">

    <property name="bin.dist.bin" value="${bin.dist.dir}/bin"/>
    <property name="bin.dist.apps" value="${bin.dist.dir}/apps"/>
    <property name="bin.dist.ext" value="${bin.dist.dir}/ext"/>
    <property name="bin.dist.lib" value="${bin.dist.dir}/lib"/>

    <mkdir dir="${bin.dist.bin}"/>
    <mkdir dir="${bin.dist.apps}"/>
    <mkdir dir="${bin.dist.ext}"/>
    <mkdir dir="${bin.dist.lib}"/>

    <copy file="${build.lib}/phoenix-loader.jar" todir="${bin.dist.bin}/"/>
    <copy file="${build.lib}/phoenix-engine.jar" todir="${bin.dist.bin}"/>

    <copy file="${build.lib}/phoenix-client.jar" todir="${bin.dist.lib}"/>
    <copy file="${build.lib}/avalon-jmx.jar" todir="${bin.dist.lib}"/>
    <copy file="${logkit.jar}" todir="${bin.dist.lib}"/>
    <copy file="${jmxri.jar}" todir="${bin.dist.lib}"/>
    <copy file="${jmxtools.jar}" todir="${bin.dist.lib}"/>
    <copy file="${framework.jar}" todir="${bin.dist.lib}"/>
    <copy file="${excalibur.jar}" todir="${bin.dist.lib}"/>
    <copy file="${scratchpad.jar}" todir="${bin.dist.lib}"/>
    <copy file="${xerces.jar}" todir="${bin.dist.lib}"/>
    <!--
    This was not copying for relatively local ..\jakarta-avalon\tools\lib\xerces.jar - PH
    <copy todir="${bin.dist.lib}">
      <fileset dir="${xerces.dir}">
        <include name="${xerces.file}" if="xerces.present"/>
      </fileset>
    </copy>
    -->

    <copy file="${script.dir}/run.bat" todir="${bin.dist.bin}"/>
    <copy file="${script.dir}/run.sh" todir="${bin.dist.bin}"/>

    <chmod dir="${bin.dist.dir}" perm="go-rwx" />
    <chmod file="${bin.dist.bin}/run.sh" perm="u+x"/>
    <chmod file="${bin.dist.bin}/run.bat" perm="u-x"/>
    <fixcrlf srcdir="${bin.dist.dir}" includes="**/*.bat" eol="crlf" />
    <fixcrlf srcdir="${bin.dist.dir}" includes="**/*.sh" eol="lf" />

  </target>

  <!-- Add the Wrapper to the dist build -->
  <target name="dist-lite-wrapper-windows" depends="dist-lite" if="is.Windows.wrapper.present">
    <!-- src bin files -->
    <copy file="${wrapper.home}/src/bin/App.bat.in"
          tofile="${bin.dist.bin}/Phoenix.bat"/>
    <copy file="${wrapper.home}/src/bin/InstallApp-NT.bat.in"
          tofile="${bin.dist.bin}/InstallPhoenix-NT.bat"/>
    <copy file="${wrapper.home}/src/bin/UninstallApp-NT.bat.in"
          tofile="${bin.dist.bin}/UninstallPhoenix-NT.bat"/>
    <!-- bin files -->
    <copy file="${wrapper.home}/bin/Wrapper.exe"
          toFile="${bin.dist.bin}/Wrapper.exe"/>
    <!-- lib files -->
    <copy file="${wrapper.home}/lib/Wrapper.dll"
          toFile="${bin.dist.bin}/Wrapper.dll"/>
    <!-- patch batch files so that they work with the Phoenix directory structure -->
    <replace dir="${bin.dist.bin}"
          token='set _WRAPPER_CONF="%_APP_HOME%\conf\wrapper.conf"'
          value='set _WRAPPER_CONF="%_APP_HOME%\bin\wrapper.conf"'>
        <include name="Phoenix.bat"/>
        <include name="InstallPhoenix-NT.bat"/>
        <include name="UninstallPhoenix-NT.bat"/>
    </replace>
  </target>
  <target name="dist-lite-wrapper-linux" depends="dist-lite, setup-filters" if="is.Linux.wrapper.present">
    <!-- src bin files -->
    <copy file="${wrapper.home}/src/bin/bash.script.in"
          tofile="${bin.dist.bin}/phoenix.sh"
          filtering="on"/>
    <!-- bin files -->
    <copy file="${wrapper.home}/bin/wrapper"
          toFile="${bin.dist.bin}/wrapper"/>
    <chmod file="${bin.dist.bin}/wrapper" perm="+x"/>
    <copy file="${wrapper.home}/bin/realpath"
          toFile="${bin.dist.bin}/realpath"/>
    <chmod file="${bin.dist.bin}/realpath" perm="+x"/>
    <!-- lib files -->
    <copy file="${wrapper.home}/lib/libwrapper.so"
          toFile="${bin.dist.bin}/libwrapper.so"/>
    <!-- patch script file so that it works with the Phoenix directory structure -->
    <replace file="${bin.dist.bin}/phoenix.sh"
          token='WRAPPER_CONF="../conf/wrapper.conf"'
          value='WRAPPER_CONF="./wrapper.conf"'/>
    <chmod file="${bin.dist.bin}/phoenix.sh" perm="+x"/>
  </target>
  <target name="dist-lite-wrapper-solaris" depends="dist-lite, setup-filters" if="is.SunOS.wrapper.present">
    <!-- src bin files -->
    <copy file="${wrapper.home}/src/bin/sh.script.in"
          tofile="${bin.dist.bin}/phoenix.sh"
          filtering="on"/>
    <!-- bin files -->
    <copy file="${wrapper.home}/bin/wrapper"
          toFile="${bin.dist.bin}/wrapper"/>
    <chmod file="${bin.dist.bin}/wrapper" perm="+x"/>
    <copy file="${wrapper.home}/bin/realpath"
          toFile="${bin.dist.bin}/realpath"/>
    <chmod file="${bin.dist.bin}/realpath" perm="+x"/>
    <!-- lib files -->
    <copy file="${wrapper.home}/lib/libwrapper.so"
          toFile="${bin.dist.bin}/libwrapper.so"/>
    <!-- patch script file so that it works with the Phoenix directory structure -->
    <replace file="${bin.dist.bin}/phoenix.sh"
          token='WRAPPER_CONF="../conf/wrapper.conf"'
          value='WRAPPER_CONF="./wrapper.conf"'/>
    <chmod file="${bin.dist.bin}/phoenix.sh" perm="+x"/>
  </target>
  <target name="dist-lite-wrapper"
          depends="dist-lite-wrapper-windows, dist-lite-wrapper-linux, dist-lite-wrapper-solaris"
          if="wrapper.present"
          description="dist-lite target + Wrapper files for the current platform">
    
    <!-- Delete unused run scripts -->
    <echo message="*** Deleting run.bat/run.sh in favor of Wrapper based scripts ***"/>
    <delete file="${bin.dist.bin}/run.bat"/>
    <delete file="${bin.dist.bin}/run.sh"/>
    
    <!-- Copy Common wrapper files -->
    <copy file="${wrapper.home}/lib/wrapper.jar" todir="${bin.dist.bin}"/>
    <copy file="${conf.dir}/wrapper.conf" todir="${bin.dist.bin}"/>
  </target>

  <target name="install" depends="dist-lite-wrapper,install-check-cjan,install-check-phoenix">

    <mkdir dir="${cjan.lib}" />
    <copy file="${build.lib}/phoenix-client.jar" todir="${cjan.lib}"/>

    <mkdir dir="${phoenix.home}" />

    <copy todir="${phoenix.home}">
      <fileset dir="${bin.dist.dir}"/>
    </copy>

    <chmod file="${phoenix.home}/bin/*.sh" perm="u+x"/>
    <chmod file="${phoenix.home}/bin/*.bat" perm="u-x"/>

  </target>

  <target name="install-check-cjan" unless="cjan.lib">
    <fail message="cjan.lib not specified." />
  </target>

  <target name="install-check-phoenix" unless="phoenix.home">
    <fail message="phoenix.home not specified." />
  </target>

  <!-- Create the distribution -->
  <target name="bin-dist" depends="all,setup-filters">

    <property name="bin.dist.docs" value="${bin.dist.dir}/docs"/>
    <property name="bin.dist.javadocs" value="${bin.dist.dir}/docs/api"/>

    <mkdir dir="${bin.dist.docs}"/>
    <mkdir dir="${bin.dist.javadocs}"/>

    <copy todir="${bin.dist.docs}">
      <fileset dir="${build.docs}"/>
    </copy>

    <copy todir="${bin.dist.javadocs}">
      <fileset dir="${build.javadocs}"/>
    </copy>

    <copy todir="${bin.dist.dir}" filtering="on">
      <fileset dir=".">
        <include name="README.txt"/>
        <include name="WARNING.txt"/>
        <include name="LICENSE"/>
      </fileset>
    </copy>

    <chmod dir="${bin.dist.dir}" perm="go-rwx" />

  </target>

  <!-- Create the source distribution -->
  <target name="src-dist" depends="setup-filters">

    <property name="src.dist.src" value="${src.dist.dir}/src"/>
    <property name="src.dist.docs" value="${src.dist.dir}/docs"/>
    <property name="src.dist.javadocs" value="${src.dist.dir}/docs/api"/>
    <property name="src.dist.lib" value="${src.dist.dir}/lib"/>
    <property name="src.dist.tools" value="${src.dist.dir}/tools"/>

    <mkdir dir="${src.dist.dir}" />
    <mkdir dir="${src.dist.docs}"/>
    <mkdir dir="${src.dist.javadocs}"/>

    <copy file="${xerces.jar}" todir="${src.dist.lib}/"/>
    <copy file="${framework.jar}" todir="${src.dist.lib}"/>
    <copy file="${excalibur.jar}" todir="${src.dist.lib}"/>
    <copy file="${scratchpad.jar}" todir="${src.dist.lib}"/>
    <copy file="${logkit.jar}" todir="${src.dist.lib}"/>

    <copy todir="${src.dist.src}">
      <fileset dir="${src.dir}"/>
    </copy>

    <copy todir="${src.dist.docs}">
      <fileset dir="${build.docs}"/>
    </copy>

    <copy todir="${src.dist.javadocs}">
      <fileset dir="${build.javadocs}"/>
    </copy>

    <copy todir="${src.dist.dir}" filtering="on">
      <fileset dir=".">
        <include name="README.txt"/>
        <include name="WARNING.txt"/>
        <include name="LICENSE"/>
        <include name="BUILDING.txt"/>
        <include name="build.xml"/>
      </fileset>
    </copy>

    <fixcrlf srcdir="${src.dist.src}/java" includes="**/*.java" eol="lf"/>
    <chmod dir="${src.dist.dir}" perm="go-rwx" />

  </target>

  <!-- Completely build all dists -->
  <target name="dist" depends="announcement,site-docs" description="generates the Phoenix distribution">
    <mkdir dir="${dist.base}"/>

    <antcall target="bin-dist">
      <param name="bin.dist.dir" value="${dist.name}" />
    </antcall>

    <zip file="${dist.base}/${dist.name}-bin.zip" 
         basedir="${dist.name}/.." 
         includes="${dist.name}/**"/>

    <tar longfile="gnu" tarfile="${dist.base}/${dist.name}-bin.tar">
      <tarfileset dir="${dist.name}/.." mode="755" username="avalon" group="avalon">
        <include name="${dist.name}/bin/*.sh"/>
      </tarfileset> 
      <tarfileset dir="${dist.name}/.." username="avalon" group="avalon"> 
        <include name="${dist.name}/**"/>
        <exclude name="${dist.name}/bin/*.sh"/>
      </tarfileset> 
    </tar>

    <gzip zipfile="${dist.base}/${dist.name}-bin.tar.gz" 
          src="${dist.base}/${dist.name}-bin.tar"/>

    <delete file="${dist.base}/${dist.name}-bin.tar"/>
    <delete dir="${dist.name}" />

    <antcall target="src-dist">
      <param name="src.dist.dir" value="${dist.name}" />
    </antcall>

    <zip file="${dist.base}/${dist.name}-src.zip" 
         basedir="${dist.name}/.." 
         includes="${dist.name}/**"/>

    <tar longfile="gnu" tarfile="${dist.base}/${dist.name}-src.tar" >
      <tarfileset dir="${dist.name}/.." username="avalon" group="avalon"> 
        <include name="${dist.name}/**"/>
      </tarfileset>
    </tar> 

    <gzip zipfile="${dist.base}/${dist.name}-src.tar.gz" 
          src="${dist.base}/${dist.name}-src.tar"/>

    <delete file="${dist.base}/${dist.name}-src.tar"/>
    <delete dir="${dist.name}" />

  </target>

  <!-- Makes the Phoneix Development Kit -->
  <target name="make-pdk" depends="jars" description="Generates thd PDK distribution">

    <mkdir dir="${dist.base}"/>
    <zip file="${dist.base}/phoenix-developers-kit.zip">
      <fileset dir="src/pdk">
        <include name="**"/>
      </fileset>
      <fileset dir=".">
        <include name="lib/**"/>
      </fileset>
      <fileset dir="build">
        <include name="lib/phoenix-client.jar"/>
      </fileset>      
    </zip>
    
  </target>

  <!-- Cleans up build and distribution directories -->
  <target name="clean" description="cleans up the created directories">
    <delete dir="${build.dir}" />
    <delete dir="${bin.dist.dir}" />
    <delete>
      <fileset dir="." includes="**/*~" defaultexcludes="no"/>
    </delete>
  </target>

  <!-- Cleans absolutely everything up -->
  <target name="distclean" depends="clean" description="cleans up all generated files and directories">
    <delete dir="${docs.dir}" />
    <delete dir="${dist.base}" />
  </target>

</project>
cvs -z3 diff build.xml (in directory E:\Jakarta\jakarta-avalon-phoenix\)
Index: build.xml
===================================================================
RCS file: /home/cvspublic/jakarta-avalon-phoenix/build.xml,v
retrieving revision 1.88
diff -r1.88 build.xml
28a29,31
>   <!-- platform -->
>   <property name="is.${os.name}" value="true"/>
> 
97c100
<     <pathelement location="${wrapper.jar}"/>
---
>     <pathelement location="${wrapper.home}/lib/wrapper.jar"/>
115,116c118,119
<   <target name="main" depends="wrapper-dist" 
<           description="generates the Phoenix distribution without the 
javadocs"/>
---
>   <target name="main" depends="dist-lite-wrapper" 
>           description="generates the Phoenix distribution using the wrapper, 
> without the javadocs"/>
124a128,155
>   
>   <!-- Resolve Platform properties -->
>   <target name="init-windows-nt" if="is.Windows NT">
>     <property name="is.Windows" value="true"/>
>     <available property="is.Windows.wrapper.present" 
> classname="com.silveregg.wrapper.WrapperManager">
>       <classpath refid="project.class.path"/>
>     </available>
>   </target>
>   <target name="init-windows-2000" if="is.Windows 2000">
>     <property name="is.Windows" value="true"/>
>     <available property="is.Windows.wrapper.present" 
> classname="com.silveregg.wrapper.WrapperManager">
>       <classpath refid="project.class.path"/>
>     </available>
>   </target>
>   <target name="init-linux" if="is.Linux">
>     <property name="is.Unix" value="true"/>
>     <available property="is.Linux.wrapper.present" 
> classname="com.silveregg.wrapper.WrapperManager">
>       <classpath refid="project.class.path"/>
>     </available>
>   </target>
>   <target name="init-solaris" if="is.SunOS">
>     <property name="is.Unix" value="true"/>
>     <available property="is.SunOS.wrapper.present" 
> classname="com.silveregg.wrapper.WrapperManager">
>       <classpath refid="project.class.path"/>
>     </available>
>   </target>
>   <target name="init" depends="init-windows-nt, init-windows-2000, 
> init-linux, init-solaris">
>   </target>
127c158
<   <target name="check-environment">
---
>   <target name="check-environment" depends="init">
163a195,198
>     
>     <!-- Wrapper filters -->
>     <filter token="app.name" value="phoenix"/>
>     <filter token="app.long.name" value="Phoenix Application Server"/>
474,480c509,586
<   <!-- Create the lite build -->
<   <target name="wrapper-dist" depends="dist-lite" if="wrapper.present"
<           description="generates the Phoenix binary distribution without the 
javadocs and with wrapper">
<           
<     <copy file="${wrapper.jar}" todir="${bin.dist.bin}"/>
<     <copy file="${wrapper.exe}" todir="${bin.dist.bin}"/>
<     <copy file="${wrapper.dll}" todir="${bin.dist.bin}"/>
---
>   <!-- Add the Wrapper to the dist build -->
>   <target name="dist-lite-wrapper-windows" depends="dist-lite" 
> if="is.Windows.wrapper.present">
>     <!-- src bin files -->
>     <copy file="${wrapper.home}/src/bin/App.bat.in"
>           tofile="${bin.dist.bin}/Phoenix.bat"/>
>     <copy file="${wrapper.home}/src/bin/InstallApp-NT.bat.in"
>           tofile="${bin.dist.bin}/InstallPhoenix-NT.bat"/>
>     <copy file="${wrapper.home}/src/bin/UninstallApp-NT.bat.in"
>           tofile="${bin.dist.bin}/UninstallPhoenix-NT.bat"/>
>     <!-- bin files -->
>     <copy file="${wrapper.home}/bin/Wrapper.exe"
>           toFile="${bin.dist.bin}/Wrapper.exe"/>
>     <!-- lib files -->
>     <copy file="${wrapper.home}/lib/Wrapper.dll"
>           toFile="${bin.dist.bin}/Wrapper.dll"/>
>     <!-- patch batch files so that they work with the Phoenix directory 
> structure -->
>     <replace dir="${bin.dist.bin}"
>           token='set _WRAPPER_CONF="%_APP_HOME%\conf\wrapper.conf"'
>           value='set _WRAPPER_CONF="%_APP_HOME%\bin\wrapper.conf"'>
>         <include name="Phoenix.bat"/>
>         <include name="InstallPhoenix-NT.bat"/>
>         <include name="UninstallPhoenix-NT.bat"/>
>     </replace>
>   </target>
>   <target name="dist-lite-wrapper-linux" depends="dist-lite, setup-filters" 
> if="is.Linux.wrapper.present">
>     <!-- src bin files -->
>     <copy file="${wrapper.home}/src/bin/bash.script.in"
>           tofile="${bin.dist.bin}/phoenix.sh"
>           filtering="on"/>
>     <!-- bin files -->
>     <copy file="${wrapper.home}/bin/wrapper"
>           toFile="${bin.dist.bin}/wrapper"/>
>     <chmod file="${bin.dist.bin}/wrapper" perm="+x"/>
>     <copy file="${wrapper.home}/bin/realpath"
>           toFile="${bin.dist.bin}/realpath"/>
>     <chmod file="${bin.dist.bin}/realpath" perm="+x"/>
>     <!-- lib files -->
>     <copy file="${wrapper.home}/lib/libwrapper.so"
>           toFile="${bin.dist.bin}/libwrapper.so"/>
>     <!-- patch script file so that it works with the Phoenix directory 
> structure -->
>     <replace file="${bin.dist.bin}/phoenix.sh"
>           token='WRAPPER_CONF="../conf/wrapper.conf"'
>           value='WRAPPER_CONF="./wrapper.conf"'/>
>     <chmod file="${bin.dist.bin}/phoenix.sh" perm="+x"/>
>   </target>
>   <target name="dist-lite-wrapper-solaris" depends="dist-lite, setup-filters" 
> if="is.SunOS.wrapper.present">
>     <!-- src bin files -->
>     <copy file="${wrapper.home}/src/bin/sh.script.in"
>           tofile="${bin.dist.bin}/phoenix.sh"
>           filtering="on"/>
>     <!-- bin files -->
>     <copy file="${wrapper.home}/bin/wrapper"
>           toFile="${bin.dist.bin}/wrapper"/>
>     <chmod file="${bin.dist.bin}/wrapper" perm="+x"/>
>     <copy file="${wrapper.home}/bin/realpath"
>           toFile="${bin.dist.bin}/realpath"/>
>     <chmod file="${bin.dist.bin}/realpath" perm="+x"/>
>     <!-- lib files -->
>     <copy file="${wrapper.home}/lib/libwrapper.so"
>           toFile="${bin.dist.bin}/libwrapper.so"/>
>     <!-- patch script file so that it works with the Phoenix directory 
> structure -->
>     <replace file="${bin.dist.bin}/phoenix.sh"
>           token='WRAPPER_CONF="../conf/wrapper.conf"'
>           value='WRAPPER_CONF="./wrapper.conf"'/>
>     <chmod file="${bin.dist.bin}/phoenix.sh" perm="+x"/>
>   </target>
>   <target name="dist-lite-wrapper"
>           depends="dist-lite-wrapper-windows, dist-lite-wrapper-linux, 
> dist-lite-wrapper-solaris"
>           if="wrapper.present"
>           description="dist-lite target + Wrapper files for the current 
> platform">
>     
>     <!-- Delete unused run scripts -->
>     <echo message="*** Deleting run.bat/run.sh in favor of Wrapper based 
> scripts ***"/>
>     <delete file="${bin.dist.bin}/run.bat"/>
>     <delete file="${bin.dist.bin}/run.sh"/>
>     
>     <!-- Copy Common wrapper files -->
>     <copy file="${wrapper.home}/lib/wrapper.jar" todir="${bin.dist.bin}"/>
484c590
<   <target name="install" 
depends="wrapper-dist,install-check-cjan,install-check-phoenix">
---
>   <target name="install" 
> depends="dist-lite-wrapper,install-check-cjan,install-check-phoenix">
495,496c601,602
<     <chmod file="${phoenix.home}/bin/run.sh" perm="u+x"/>
<     <chmod file="${phoenix.home}/bin/run.bat" perm="u-x"/>
---
>     <chmod file="${phoenix.home}/bin/*.sh" perm="u+x"/>
>     <chmod file="${phoenix.home}/bin/*.bat" perm="u-x"/>
597c703
<         <include name="${dist.name}/bin/run.sh"/>
---
>         <include name="${dist.name}/bin/*.sh"/>
601c707
<         <exclude name="${dist.name}/bin/run.sh"/>
---
>         <exclude name="${dist.name}/bin/*.sh"/>

*****CVS exited normally with code 1*****

cvs -z3 diff wrapper.conf (in directory 
E:\Jakarta\jakarta-avalon-phoenix\src\conf\)
Index: wrapper.conf
===================================================================
RCS file: /home/cvspublic/jakarta-avalon-phoenix/src/conf/wrapper.conf,v
retrieving revision 1.1
diff -r1.1 wrapper.conf
13,21c13
< wrapper.java.classpath.3=../lib/avalon-excalibur-20011120.jar
< wrapper.java.classpath.4=../lib/avalon-framework-20011110.jar
< wrapper.java.classpath.5=../lib/avalon-jmx.jar
< wrapper.java.classpath.6=../lib/avalon-scratchpad-20011122.jar
< wrapper.java.classpath.7=../lib/phoenix-client.jar
< wrapper.java.classpath.8=../lib/logkit-1.0.jar
< wrapper.java.classpath.9=../lib/xerces.jar
< wrapper.java.classpath.10=../lib/jmxri.jar
< wrapper.java.classpath.11=../lib/jmxtools.jar
---
> #wrapper.java.classpath.3=../lib/avalon-framework-20011110.jar
27,28c19,22
< #wrapper.java.additional.1=-Dwrapper.debug=true
< wrapper.java.additional.1=
---
> wrapper.java.additional.1=-Djava.ext.dirs=..\lib
> wrapper.java.additional.2=-Dphoenix.home=..
> #wrapper.java.additional.3=-Djava.security.policy=jar:file:../bin/wrapper-loader.jar!/META-INF/java.policy
> #wrapper.java.additional.4=-Djava.security.manager
37,39c31
< #wrapper.app.parameter.1=--remote-manager
< #wrapper.app.parameter.1="C:/FullPath/MyApp/conf/myappservlet.conf"
< #wrapper.app.parameter.1.stripquotes=TRUE
---
> #wrapper.app.parameter.1=
44,50c36,38
< # Log file to use for wrapper output logging.
< #wrapper.logfile=C:/FullPath/MyApp/logs/myappwrapper.log
< 
< # Number of seconds to allow for the JVM to be launched and contact the 
< #  wrapper before the wrapper should assume that the JVM is hung and 
< #  terminate the JVM process.  0 means never time out.  Defaults to 
< #  30 seconds.
---
> # Number of seconds to allow for the JVM to be launched and contact the 
> wrapper before the
> #  wrapper should assume that the JVM is hung and terminate the JVM process.  
> 0 means never
> #  time out.  Defaults to 30 seconds.
55a44,59
> 
> # The Wrapper detects when an application calls System.exit() and treats this 
> as a request
> #  to stop the server by default.
> #wrapper.disable_shutdown_hook=TRUE
> 
> #********************************************************************
> # Wrapper Logging parameters
> #********************************************************************
> # Log file to use for wrapper output logging.
> wrapper.logfile=wrapper.log
> 
> # Format of output for the log file.  (See docs for formats)
> wrapper.logfile.format=PTM
> 
> # Format of output for the log file.  (See docs for formats)
> wrapper.console.format=PM

*****CVS exited normally with code 1*****

cvs -z3 diff DaemonLauncher.java (in directory 
E:\Jakarta\jakarta-avalon-phoenix\src\java\org\apache\avalon\phoenix\launcher\)
Index: DaemonLauncher.java
===================================================================
RCS file: 
/home/cvspublic/jakarta-avalon-phoenix/src/java/org/apache/avalon/phoenix/launcher/DaemonLauncher.java,v
retrieving revision 1.3
diff -r1.3 DaemonLauncher.java
12,13c12,22
< import java.awt.event.ActionEvent;
< import java.awt.event.ActionListener;
---
> import com.silveregg.wrapper.WrapperSimpleApp;
> 
> import java.io.File;
> import java.lang.reflect.InvocationTargetException;
> import java.lang.reflect.Method;
> import java.net.URL;
> import java.net.URLClassLoader;
> import java.security.CodeSource;
> import java.security.PermissionCollection;
> import java.security.Permissions;
> import java.security.Policy;
14a24
> import java.util.StringTokenizer;
20a31
>  * @author <a href="mailto:[EMAIL PROTECTED]">Leif Mortenson</a>
22,23c33,34
< public class DaemonLauncher
<     implements WrapperListener, Runnable, ActionListener
---
> public final class DaemonLauncher
>     implements WrapperListener, Runnable
25,27c36,88
<     private String[] m_args;
< 
<     public Integer start( final String[] args )
---
>     /*
>      * Based on com.silveregg.wrapper.WrapperSimpleApp
>      */
>     
>     private final static String MAIN_CLASS = 
> "org.apache.avalon.phoenix.frontends.CLIMain";
>     private final static String MAIN_JAR = "phoenix-engine.jar";
>     private final static String LOADER_JAR = "phoenix-loader.jar";
>     
>     /**
>      * Class loader used to launch Phoenix.
>      */
>     private URLClassLoader m_classLoader;
>     
>     /**
>      * Application's instance
>      */
>     private Object m_instance;
>     
>     /**
>      * Application's main method
>      */
>     private Method m_mainMethod;
>     
>     /**
>      * Application's shutdown method
>      */
>     private Method m_shutdownMethod;
>     
>     /**
>      * Command line arguments to be passed on to the application
>      */
>     private String[] m_appArgs;
>     
>     /**
>      * Gets set to true when the thread used to launch the application 
> completes.
>      */
>     private boolean m_mainComplete;
>     
>     /**
>      * Exit code to be returned if the application fails to start.
>      */
>     private Integer m_mainExitCode;
>     
>     /**
>      * Flag used to signify that the start method is done waiting for the 
> application to start.
>      */
>     private boolean m_waitTimedOut;
>     
>     
>     /*---------------------------------------------------------------
>      * Main Method
>      *-------------------------------------------------------------*/
>     public final static void main( final String args[] )
29,40c90,132
<         // This startup could take a while, so tell the wrapper to be patient.
<         WrapperManager.signalStarting( 45000 );
< 
<         m_args = args;
< 
<         final Thread thread = new Thread( this );
<         thread.start();
< 
<         // We are almost up now, so reset the wait time
<         WrapperManager.signalStarting( 2000 );
< 
<         return null;
---
>         final URLClassLoader classLoader;
>         final Method mainMethod;
>         final Method shutdownMethod;
>         final Object instance;
>         
>         try
>         {
>             //setup new Policy manager
>             Policy.setPolicy( new FreeNEasyPolicy() );
>             
>             //Create engine ClassLoader
>             final File mainJar = findEngineJar();
>             final URL archive = mainJar.toURL();
>             classLoader = new URLClassLoader( new URL[]{ archive } );
>             
>             //Create main launcher
>             final Class clazz = classLoader.loadClass( MAIN_CLASS );
>             final Class[] paramTypes = new Class[] { args.getClass(), 
> Hashtable.class };
>             mainMethod = clazz.getMethod( "main", paramTypes );
>             shutdownMethod = clazz.getMethod( "shutdown", null );
>             instance = clazz.newInstance();
>             
>             //kick the tires and light the fires....
>             //method.invoke( instance, new Object[]{ args } );
>         }
>         catch( final Exception e )
>         {
>             e.printStackTrace();
>             WrapperManager.stop(1);
>             return;  // Will not get here
>         }
>         
>         // Create the Main WrapperListener
>         DaemonLauncher app = new DaemonLauncher( classLoader, instance, 
> mainMethod, shutdownMethod );
>         
>         // Start the application.  If the JVM was launched from the native
>         //  Wrapper then the application will wait for the native Wrapper to
>         //  call the application's start method.  Otherwise the start method
>         //  will be called immediately.
>         WrapperManager.start( app, args );
>         
>         // This thread ends, the WrapperManager will start the application 
> after the Wrapper has
>         //  been propperly initialized by calling the start method.
42c134,151
< 
---
>     
>     /*---------------------------------------------------------------
>      * Constructors
>      *-------------------------------------------------------------*/
>     private DaemonLauncher( URLClassLoader classLoader, Object instance, 
> Method mainMethod, Method shutdownMethod )
>     {
>         m_classLoader = classLoader;
>         m_instance = instance;
>         m_mainMethod = mainMethod;
>         m_shutdownMethod = shutdownMethod;
>     }
>     
>     /*---------------------------------------------------------------
>      * Runnable Methods
>      *-------------------------------------------------------------*/
>     /**
>      * Used to launch the application in a separate thread.
>      */
45,49c154,158
<         final Hashtable data = new Hashtable();
<         data.put( ActionListener.class.getName(), this );
< 
<         try { Main.startup( m_args, data ); }
<         catch( final Exception e )
---
>         //Setup context classLoader
>         Thread.currentThread().setContextClassLoader( m_classLoader );
>         
>         Throwable t = null;
>         try
51c160,247
<             e.printStackTrace();
---
>             if ( WrapperManager.isDebugEnabled() )
>             {
>                 System.out.println( "DaemonLauncher: invoking main method" );
>             }
>             m_mainMethod.invoke( m_instance, new Object[] {m_appArgs, new 
> Hashtable() } );
>             if ( WrapperManager.isDebugEnabled() )
>             {
>                 System.out.println( "DaemonLauncher: main method completed" );
>             }
>             
>             // If we get here, then the application completed normally and we 
> should shut down
>             //  if there are no daemon threads running.
>             Thread[] threads = new Thread[Thread.activeCount() * 2];
>             Thread.enumerate( threads );
>             
>             // Only shutdown if there are any non daemon threads which are 
>             //  still alive other than this thread.
>             int liveCount = 0;
>             for ( int i = 0; i < threads.length; i++ )
>             {
>                 if ( ( threads[i] != null ) && ( threads[i].isAlive() && ( 
> !threads[i].isDaemon() ) ) )
>                 {
>                     // Do not count this thread or the wrapper connection 
> thread
>                     if ( (Thread.currentThread() != threads[i] ) && 
>                         ( 
> !WrapperManager.WRAPPER_CONNECTION_THREAD_NAME.equals( threads[i].getName() ) 
> ) )
>                     {
>                         // Non-Daemon livine thread
>                         liveCount++;
>                     }
>                 }
>             }
>             
>             synchronized(this)
>             {
>                 // Let the start() method know that the main method returned, 
> in case it is 
>                 //  still waiting.
>                 m_mainComplete = true;
>                 this.notifyAll();
>             }
>             
>             // There will always be one non-daemon thread alive.  This thread 
> is either the main
>             //  thread which has not yet completed, or a thread launched by 
> java when the main
>             //  thread completes whose job is to wait around for all other 
> non-daemon threads to
>             //  complete.  We are overriding that thread here.
>             if ( liveCount <= 1 )
>             {
>                 // Exit normally
>                 WrapperManager.stop( 0 );
>                 // Will not get here.
>             }
>             else
>             {
>                 // There are daemons running, let the JVM continue to run.
>             }
>             return;
>         }
>         catch ( final IllegalAccessException e )
>         {
>             t = e;
>         }
>         catch ( final IllegalArgumentException e )
>         {
>             t = e;
>         }
>         catch ( final InvocationTargetException e )
>         {
>             t = e;
>         }
>         
>         // If we get here, then an error was thrown.  If this happened 
> quickly enough, the
>         //  start method should be allowed to shut things down.
>         System.out.println( "Encountered an error running main: " + t );
>         synchronized( this )
>         {
>             if ( m_waitTimedOut )
>             {
>                 // Shut down here.
>                 WrapperManager.stop( 1 );
>                 return; // Will not get here.
>             }
>             else
>             {
>                 // Let start method handle shutdown.
>                 m_mainComplete = true;
>                 m_mainExitCode = new Integer( 1 );
>                 this.notifyAll();
>                 return;
>             }
54,55c250,266
< 
<     public int stop( final int exitCode )
---
>     
>     /*---------------------------------------------------------------
>      * WrapperListener Methods
>      *-------------------------------------------------------------*/
>     /**
>      * The start method is called when the WrapperManager is signaled by the 
>      *        native wrapper code that it can start its application.  This
>      *        method call is expected to return, so a new thread should be 
> launched
>      *        it necessary.
>      * If there are any problems, then an Integer should be returned, set to
>      *        the desired exit code.  If the application should continue,
>      *        return null.
>      *
>      * This method will launch the Phoenix server in a second thread, but wait
>      *  a few seconds before returning in case Phoenix fails to start.
>      */
>     public Integer start( final String[] args )
57c268,337
<         Main.shutdown();
---
>         if ( WrapperManager.isDebugEnabled() )
>         {
>             System.out.println( "DaemonLauncher: start(args)" );
>         }
>         
>         Thread mainThread = new Thread( this, "DaemonLauncher" );
>         synchronized( this )
>         {
>             m_appArgs = args;
>             mainThread.start();
>             
>             // Wait for two seconds to give the application a chance to have 
> failed.
>             try {
>                 this.wait( 2000 );
>             } catch (InterruptedException e) {
>             }
>             m_waitTimedOut = true;
>             
>             if (WrapperManager.isDebugEnabled()) {
>                 System.out.println("DaemonLauncher: start(args) end.  
> Running=" + m_waitTimedOut + ", exitCode=" + m_mainExitCode);
>             }
>             return m_mainExitCode;
>         }
>     }
>     
>     /**
>      * Called when the application is shutting down.
>      */
>     public int stop( int exitCode )
>     {
>         if ( WrapperManager.isDebugEnabled() ) {
>             System.out.println("DaemonLauncher: stop(" + exitCode + ")");
>         }
>         
>         Throwable t = null;
>         try
>         {
>             if ( WrapperManager.isDebugEnabled() )
>             {
>                 System.out.println( "DaemonLauncher: invoking shutdown 
> method" );
>             }
>             m_shutdownMethod.invoke( m_instance, null );
>             if ( WrapperManager.isDebugEnabled() )
>             {
>                 System.out.println( "DaemonLauncher: shutdown method 
> completed" );
>             }
>             
>             return exitCode;
>         }
>         catch ( final IllegalAccessException e )
>         {
>             t = e;
>         }
>         catch ( final IllegalArgumentException e )
>         {
>             t = e;
>         }
>         catch ( final InvocationTargetException e )
>         {
>             t = e;
>         }
>         
>         // If we get here, then an error was thrown.
>         System.out.println( "Encountered an error running shutdown: " + t );
>             
>         // Set the exit code to the error state.
>         if ( exitCode == 0 )
>         {
>             exitCode = 1;
>         }
60,61c340,348
< 
<     public void controlEvent( final int event )
---
>     
>     /**
>      * Called whenever the native wrapper code traps a system control signal
>      *  against the Java process.  It is up to the callback to take any 
> actions
>      *  necessary.  Possible values are: WrapperManager.WRAPPER_CTRL_C_EVENT, 
>      *    WRAPPER_CTRL_CLOSE_EVENT, WRAPPER_CTRL_LOGOFF_EVENT, or 
>      *    WRAPPER_CTRL_SHUTDOWN_EVENT
>      */
>     public void controlEvent(int event)
63c350
<         if( WrapperManager.isControlledByNativeWrapper() )
---
>         if ( WrapperManager.isControlledByNativeWrapper() )
65,66c352,356
<             // This application ignores all incoming control events.
<             //  It relies on the wrapper code to handle them.
---
>             if ( WrapperManager.isDebugEnabled() )
>             {
>                 System.out.println( "DaemonLauncher: controlEvent(" + event + 
> ") Ignored" );
>             }
>             // Ignore the event as the native wrapper will handle it.
69a360,366
>             if ( WrapperManager.isDebugEnabled() )
>             {
>                 System.out.println( "DaemonLauncher: controlEvent(" + event + 
> ") Stopping" );
>             }
>             
>             // Not being run under a wrapper, so this isn't an NT service and 
> should always exit.
>             //  Handle the event here.
70a368
>             // Will not get here.
73c371,374
< 
---
>     
>     /*---------------------------------------------------------------
>      * Private Methods
>      *-------------------------------------------------------------*/
75,90c376,389
<      * We use an ActionListener rather than operating on some more meaningful
<      * event system as ActionListener and friends can be loaded from system
<      * ClassLoader and thus the Embeddor does not have to share a common
<      * classloader ancestor with invoker
<      */
<     public void actionPerformed( final ActionEvent action )
<     {
<         final String command = action.getActionCommand();
<         if( command.equals( "restart" ) )
<         {
<             System.out.println( "Pre-restart()" );
<             System.out.flush();
<             WrapperManager.restart();
<             System.out.println( "Post-restart()" );
<             System.out.flush();
< 
---
>      * Find the "engine" jar from which to run main phoenix kernel.
>      *
>      * @return the engine file
>      * @exception Exception if an error occurs
>      */
>     private final static File findEngineJar()
>         throws Exception
>     {
>         String phoenixHome = System.getProperty( "phoenix.home", null );
>         
>         if( null == phoenixHome )
>         {
>             final File loaderDir = findLoaderDir();
>             phoenixHome = loaderDir.getAbsoluteFile().getParentFile() + 
> File.separator;
92c391,410
<         else
---
>         
>         phoenixHome = (new File( phoenixHome )).getCanonicalFile().toString();
>         System.setProperty( "phoenix.home", phoenixHome );
>         
>         final String filename =
>             phoenixHome + File.separator + "bin" + File.separator + MAIN_JAR;
>         return (new File( filename )).getCanonicalFile();
>     }
>     
>     /**
>      *  Finds the LOADER_JAR file in the classpath.
>      */
>     private final static File findLoaderDir()
>         throws Exception
>     {
>         final String classpath = System.getProperty( "java.class.path" );
>         final String pathSeparator = System.getProperty( "path.separator" );
>         final StringTokenizer tokenizer = new StringTokenizer( classpath, 
> pathSeparator );
>         
>         while( tokenizer.hasMoreTokens() )
94c412,419
<             throw new IllegalArgumentException( "Unknown action " + command );
---
>             final String element = tokenizer.nextToken();
>             
>             if( element.endsWith( LOADER_JAR ) )
>             {
>                 File file = ( new File( element ) ).getCanonicalFile();
>                 file = file.getParentFile();
>                 return file;
>             }
95a421,422
>         
>         throw new Exception( "Unable to locate " + LOADER_JAR + " in 
> classpath" );
97,98c424,430
< 
<     public static void main( final String[] args )
---
>     
>     /**
>      * Default polic class to give every code base all permssions.
>      * Will be replaced once the kernel loads.
>      */
>     private static class FreeNEasyPolicy
>         extends Policy
100c432,441
<         WrapperManager.start( new DaemonLauncher(), args );
---
>         public PermissionCollection getPermissions( final CodeSource 
> codeSource )
>         {
>             final Permissions permissions = new Permissions();
>             permissions.add( new java.security.AllPermission() );
>             return permissions;
>         }
>         
>         public void refresh()
>         {
>         }
102a444
> 

*****CVS exited normally with code 1*****

cvs -z3 diff CLIMain.java (in directory 
E:\Jakarta\jakarta-avalon-phoenix\src\java\org\apache\avalon\phoenix\frontends\)
Index: CLIMain.java
===================================================================
RCS file: 
/home/cvspublic/jakarta-avalon-phoenix/src/java/org/apache/avalon/phoenix/frontends/CLIMain.java,v
retrieving revision 1.18
diff -r1.18 CLIMain.java
33c33,34
<     private Embeddor m_embeddor;
---
>     ///(This can not be of type Embeddor or reflection from Main and 
> DaemonLauncher will fail)
>     private Object m_embeddor;
96c97
<             m_embeddor.execute();
---
>             ((Embeddor)m_embeddor).execute();
132c133
<             m_embeddor.initialize();
---
>             ((Embeddor)m_embeddor).initialize();
184c185
<                 m_embeddor.dispose();
---
>                 ((Embeddor)m_embeddor).dispose();

*****CVS exited normally with code 1*****

--
To unsubscribe, e-mail:   <mailto:[EMAIL PROTECTED]>
For additional commands, e-mail: <mailto:[EMAIL PROTECTED]>

Reply via email to