Peter Donald wrote:
I manage a SourceForge project, http://wrapper.sourceforge.net , that does this. It currently has 2.2.2 released, but the changes I have made to get it working with Phoenix are still being finalized. Release 2.2.3 with those changes should be up in a few days. I will post again when it is.On Thu, 6 Dec 2001 21:57, Leif Mortenson wrote:
I am working on getting Phoenix running inside of a container which allows me to run Phoenix as an NT Service.
kool.
Threw way the Wrapper works is that it actually has a class WrapperManagerI have gotten it all working correctly except for one thing.
When my application shuts down the JVM, this causing the ShutdownHook in Phoenix to be triggered. Looking at the source in org.apache.avalon.phoenix.frontends.CLIMain, it looks like this is triggering the forceShutdown() method which is in turn shutting Phoenix down cleanly.
yep.
But...
Phoenix is printing out the following message:
JVM exiting abnormally. Shutting down Phoenix.
I was wondering what the "normal" way to shut down the JVM is in Phoenix. I could not locate any other shutdown functionality.
Well the "normal" way is to call Embeddor.shutdown(). Unfortunately at this stage there is no real mechanism to do this from outside the JVM. I actually have a local version that allows you to send a command of tcp to shutdown server but have yet to clean up the code, secure it and check it in.
that is loaded into the JVM and actually launches the application. Currently,
Phoenix is being launched and controlled as a generic application because I am
relying on Phoenix's ShutdownHook to shut things down cleanly.
The Wrapper also provides an Interface, WrapperListener, which provides 3
service control methods, used to allow the application to respond to start,
stop, and system signals. If Phoenix had a shutdown method that it could access,
then I could call that directly from the stop method. That should be more secure
than having a TCP connection waiting for connections.
The WrapperManager also includes commands which allow the application to
request that it be shutdown or even that its JVM be restarted. That goes
against the model that a Component should not control its own life cycle, but
it can be useful for servers. (Or maybe it is Ok, since the Component is not
actually stopping itself, but just making a request to its Container that it be
stopped)
Currently, I can not get access to the Embedder.shutdown() method as the
Embedder reference is currently stored as a private field in the instance of
CLIMain used to launch the server.
CLIMain creates an instance of DefaultEmbedder as its Embedder implementation.
then just calls the dispose() method to shutdown (it then in turn calls its own
shutdown() method).
I would be able to shutdown the server cleanly if I could get access to the CLIMain.shutdown() method.
I would like to propose that the shutdown() method be made public rather than
private. This will not cause any security problems because there is no way for
any evil classes to get a hold of the CLIMain instance. Currently, its only
references are in the ShutdownHook and in the Main class which created it.
If the Main class could call the shutdown() hook using reflection, then my problems would be solved. I have written my own Wrapper friendly version of the Main class in the launcher package and it all works beautifully with Wrapper 2.2.3 and the changes to CLIMain described below.
To make this work correctly, the shutdown() method would also have to
deregister the shutdown hook when it was called. Here is what the new
shutdown() method would look like. Also changed the comments of the
forceShutdown() method to show that it is only called from within the
ShutdownHook.
---
public synchronized void shutdown()
{
// Deregister the shutdown hook
if ( null != m_hook )
{
// Deregister the shutdown hook so it is not triggered again.
Runtime.getRuntime().removeShutdownHook( m_hook );
m_hook = null;
}
if( null != m_embeddor )
{
try
{
m_embeddor.dispose();
}
catch( final Throwable throwable )
{
handleException( throwable );
}
finally
{
m_embeddor = null;
}
}
}
---
The code to remove the hook in the execute method can also now be removed. --- ... finally { //if( null != m_hook ) //{ // Runtime.getRuntime().removeShutdownHook( m_hook ); //} shutdown(); } ... ---
I also found it necessary to change the following line of code in the CLIMain
main method.
---
final CLIMain main = new CLIMain();
---
to
---
final CLIMain main = this;
---
What is the reason for creating another instance. The original instance can
not be obtained by anyone other than the creating class Main. So I don't see
why the extra security is required.
(if this change is made, then the main method can be simplified)
I don't believe that any of these changes open up any security holes in Phoenix.
Could you take a look at it and let me know if you see any problems.
Thank you, Leif
I am including a diff of CLIMain at the bottom of this file.
===================================================================
Eventually you will be able to shutdown the server via JMX but this is something I am working on now - so it may take a while ;)
RCS file: /home/cvspublic/jakarta-avalon-phoenix/src/java/org/apache/avalon/phoenix/frontends/CLIMain.java,v
retrieving revision 1.14
diff -r1.14 CLIMain.java
44c44
< final CLIMain main = new CLIMain();
---
> final CLIMain main = this;
103,106c103,106
< if( null != m_hook )
< {
< Runtime.getRuntime().removeShutdownHook( m_hook );
< }
---
> //if( null != m_hook )
> //{
> // Runtime.getRuntime().removeShutdownHook( m_hook );
> //}
139a140,141
> * This method is designed to only be called from within the ShutdownHook.
> * To shutdown Pheonix, call shutdown() below.
147,149c149,151
< //Null hook so it is not tried to be removed
< //when we are shutting down. (Attempting to remove
< //hook during shutdown raises an exception).
---
> // Null hook so it is not tried to be removed
> // when we are shutting down. (Attempting to remove
> // hook during shutdown raises an exception).
158c160
< private synchronized void shutdown()
---
> public synchronized void shutdown()
159a162,169
> // Deregister the shutdown hook
> if ( null != m_hook )
> {
> // Deregister the shutdown hook so it is not triggered again.
> Runtime.getRuntime().removeShutdownHook( m_hook );
> m_hook = null;
> }
>