[jboss-user] [Microcontainer] - Re: Lifecycle stop() method and new objects

gcompienne do-not-reply at jboss.com
Fri Nov 28 06:35:31 EST 2008


At the moment I must admit I haven't defined any dependencies metadata as everything is self contained in a single small jar file. Do I still need to define them? (admittedly I kind of relied on the JAR structure deployer to define the default CL going with a JAR...)

The sample is a simple telnet echo server. If I connect to the echo server the "Handler" object gets created fine. And then if I delete the JAR, the bean is also undeployed fine.

Now, if I deploy and then immediately undeploy the JAR (without connecting to the telnet server) then I have a NoClassDefFoundError that occurs during the undeploy stage (typically when I try the close down any Handlers if any but to do that the code needs to create one dummy Handler...).

Here is the stack trace:

  | 11:17:53,876 WARN  [StartStopLifecycleAction] Error during stop for Controler
  | java.lang.NoClassDefFoundError: mcfproto/impl/Handler
  |         at mcfproto.impl.NetServer.closeAll(NetServer.java:110)
  |         at mcfproto.impl.NetServer.stop(NetServer.java:72)
  |         at mcfproto.impl.ControlerImpl.stop(ControlerImpl.java:20)
  |         at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
  |         at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
  |         at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
  |         at java.lang.reflect.Method.invoke(Method.java:597)
  |         at org.jboss.reflect.plugins.introspection.ReflectionUtils.invoke(ReflectionUtils.java:59)
  |         at org.jboss.reflect.plugins.introspection.ReflectMethodInfoImpl.invoke(ReflectMethodInfoImpl.java:150)
  |         at org.jboss.joinpoint.plugins.BasicMethodJoinPoint.dispatch(BasicMethodJoinPoint.java:66)
  |         at org.jboss.kernel.plugins.dependency.KernelControllerContextAction$JoinpointDispatchWrapper.execute(KernelCont
  | rollerContextAction.java:241)
  |         at org.jboss.kernel.plugins.dependency.ExecutionWrapper.execute(ExecutionWrapper.java:47)
  |         at org.jboss.kernel.plugins.dependency.KernelControllerContextAction.dispatchExecutionWrapper(KernelControllerCo
  | ntextAction.java:109)
  |         at org.jboss.kernel.plugins.dependency.KernelControllerContextAction.dispatchJoinPoint(KernelControllerContextAc
  | tion.java:70)
  |         at org.jboss.kernel.plugins.dependency.LifecycleAction.uninstallActionInternal(LifecycleAction.java:249)
  |         at org.jboss.kernel.plugins.dependency.InstallsAwareAction.uninstallAction(InstallsAwareAction.java:157)
  |         at org.jboss.kernel.plugins.dependency.InstallsAwareAction.uninstallAction(InstallsAwareAction.java:42)
  |         at org.jboss.dependency.plugins.action.SimpleControllerContextAction.simpleUninstallAction(SimpleControllerConte
  | xtAction.java:79)
  |         at org.jboss.dependency.plugins.action.AccessControllerContextAction.uninstall(AccessControllerContextAction.jav
  | a:131)
  |         at org.jboss.dependency.plugins.AbstractControllerContextActions.uninstall(AbstractControllerContextActions.java
  | :58)
  |         at org.jboss.dependency.plugins.AbstractControllerContext.uninstall(AbstractControllerContext.java:354)
  |         at org.jboss.dependency.plugins.AbstractController.uninstall(AbstractController.java:1631)
  |         at org.jboss.dependency.plugins.AbstractController.uninstallContext(AbstractController.java:1242)
  |         at org.jboss.dependency.plugins.AbstractController.uninstallContext(AbstractController.java:1146)
  |         at org.jboss.dependency.plugins.AbstractController.uninstall(AbstractController.java:655)
  |         at org.jboss.dependency.plugins.AbstractController.uninstall(AbstractController.java:568)
  |         at org.jboss.deployers.vfs.deployer.kernel.BeanMetaDataDeployer.undeploy(BeanMetaDataDeployer.java:156)
  |         at org.jboss.deployers.vfs.deployer.kernel.BeanMetaDataDeployer.undeploy(BeanMetaDataDeployer.java:51)
  |         at org.jboss.deployers.spi.deployer.helpers.AbstractSimpleRealDeployer.internalUndeploy(AbstractSimpleRealDeploy
  | er.java:69)
  |         at org.jboss.deployers.spi.deployer.helpers.AbstractRealDeployer.undeploy(AbstractRealDeployer.java:112)
  |         at org.jboss.deployers.plugins.deployers.DeployerWrapper.undeploy(DeployerWrapper.java:192)
  |         at org.jboss.deployers.plugins.deployers.DeployersImpl.doUndeploy(DeployersImpl.java:1315)
  |         at org.jboss.deployers.plugins.deployers.DeployersImpl.doUninstallParentLast(DeployersImpl.java:1222)
  |         at org.jboss.deployers.plugins.deployers.DeployersImpl.doUninstallParentLast(DeployersImpl.java:1215)
  |         at org.jboss.deployers.plugins.deployers.DeployersImpl.uninstall(DeployersImpl.java:1177)
  |         at org.jboss.dependency.plugins.AbstractControllerContext.uninstall(AbstractControllerContext.java:354)
  |         at org.jboss.dependency.plugins.AbstractController.uninstall(AbstractController.java:1631)
  |         at org.jboss.dependency.plugins.AbstractController.uninstallContext(AbstractController.java:1242)
  |         at org.jboss.dependency.plugins.AbstractController.change(AbstractController.java:827)
  |         at org.jboss.dependency.plugins.AbstractController.change(AbstractController.java:553)
  |         at org.jboss.deployers.plugins.deployers.DeployersImpl.process(DeployersImpl.java:543)
  |         at org.jboss.deployers.plugins.main.MainDeployerImpl.process(MainDeployerImpl.java:541)
  |         at org.jboss.system.server.profileservice.hotdeploy.HDScanner.scan(HDScanner.java:290)
  |         at org.jboss.system.server.profileservice.hotdeploy.HDScanner.run(HDScanner.java:221)
  |         at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:441)
  |         at java.util.concurrent.FutureTask$Sync.innerRunAndReset(FutureTask.java:317)
  |         at java.util.concurrent.FutureTask.runAndReset(FutureTask.java:150)
  |         at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$101(ScheduledThreadPoolExecutor.j
  | ava:98)
  |         at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.runPeriodic(ScheduledThreadPoolExecutor.
  | java:181)
  |         at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:205
  | )
  |         at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:885)
  |         at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:907)
  |         at java.lang.Thread.run(Thread.java:619)
  | 11:18:09,057 INFO  [ControlerImpl] ControlerImpl started...
  | 11:18:29,085 INFO  [ControlerImpl] ControlerImpl stopped...
  | 11:19:59,656 INFO  [ControlerImpl] ControlerImpl started...
  | 

Here is the jboss-beans.xml


  | <?xml version="1.0" encoding="UTF-8"?>
  | 
  | <deployment xmlns="urn:jboss:bean-deployer:2.0">
  | 
  | 	<bean name="Controler" class="mcfproto.impl.ControlerImpl">
  | 	</bean>
  | 		
  | </deployment>
  | 

Here is the source for ControlerImpl:

  | package mcfproto.impl;
  | 
  | import org.jboss.logging.Logger;
  | 
  | public class ControlerImpl {
  | 	private static Logger log = Logger.getLogger(ControlerImpl.class);
  | 	
  | 	private NetServer server;
  | 
  | 	public ControlerImpl() {     
  |       server = new NetServer();
  |    }
  | 	
  | 	public void start(){
  |       server.start();
  |       log.info("ControlerImpl started...");
  | 	}
  | 	
  | 	public void stop() {
  | 	   server.stop();
  | 	   log.info("ControlerImpl stopped...");
  | 	}
  | 	
  | 	public void destroy() {
  | 		server = null;
  | 	}
  | 	
  | }
  | 

Here is the source for NetServer:

  | package mcfproto.impl;
  | 
  | import java.net.ServerSocket;
  | import java.net.Socket;
  | import java.util.HashSet;
  | import java.util.Set;
  | 
  | import org.jboss.logging.Logger;
  | 
  | /**
  |  * Dummy telnet server that listen on port 23 and is used for testing 
  |  */
  | public class NetServer {
  | 
  |    private final static Logger LOG = Logger.getLogger(NetServer.class);
  | 
  |    private static final int TELNET_PORT = 23;
  | 
  |    private ServerSocket m_Server;
  | 
  |    volatile boolean m_Quit;
  | 
  |    private Set<Handler> m_Handlers;
  | 
  |    private Thread m_Thread;
  | 
  |    public NetServer() {
  |       m_Handlers = new HashSet<Handler>();
  |    }
  | 
  |    public void start() {
  |       try {
  |          m_Thread = new Thread(new Runnable() {
  |             public void run() {
  |                while (!m_Quit) {
  |                   try {
  |                      m_Server = new ServerSocket(TELNET_PORT);
  |                      loop();
  |                   } catch (Exception e) {
  |                      if (m_Quit) {
  |                         // It is expected that we get an exception here 
  |                         // as the "stop" method violently close the socket...
  |                         LOG.debug(e);
  |                      } else {
  |                         LOG.error("[NetServer] Inner server listen loop...", e);
  |                         sleep(1000);
  |                      }
  |                   }
  |                }
  |                closeAll();
  |             }
  |          }, "NetServer Thread");
  |          m_Thread.start();
  |       } catch (Exception e) {
  |          throw new RuntimeException(e);
  |       }
  |    }
  | 
  |    public void stop() {
  |       m_Quit = true;
  |       try {
  |          // force the "loop" to quit TCP "accept" by closing socket...
  |          m_Server.close();
  |       } catch (Exception e) {
  |          throw new RuntimeException(e);
  |       }
  |       try {
  |          m_Thread.join();
  |       } catch (InterruptedException e) {
  |          // demo code, so ignore (but should not in production code)
  |       }
  |       closeAll();
  |       m_Server = null;
  |       m_Handlers = null;
  |       m_Thread = null;
  |    }
  | 
  |    void remove(Handler handler) {
  |       synchronized (m_Handlers) {
  |          m_Handlers.remove(handler);
  |       }
  |    }
  | 
  |    private void loop() throws Exception {
  |       // no need to synchronize as m_Quit is volatile and
  |       // is acting as a memory synchronization block.
  |       // (and here we don't need sequencing, just mem sync).
  |       while (!m_Quit) {
  |          Socket socket = m_Server.accept();
  | 
  |          Handler handler = new Handler(socket, this);
  | 
  |          synchronized (m_Handlers) {
  |             m_Handlers.add(handler);
  |          }
  |          handler.start();
  |       }
  |    }
  | 
  |    private void sleep(int ms) {
  |       try {
  |          Thread.sleep(ms);
  |       } catch (InterruptedException interruptedexception) {
  |       }
  |    }
  | 
  |    private void closeAll() {
  |       Handler[] handlers = null;
  |       synchronized (m_Handlers) {
  |          handlers = m_Handlers.toArray(new Handler[m_Handlers.size()]);
  |       }
  |       for (Handler handler : handlers) {
  |          try {
  |             handler.close();
  |             handler.join();
  |          } catch (Throwable throwable) {
  |          }
  |       }
  |    }
  | }
  | 

And finally, here is the source for the Handler class:

  | /*
  |  * Filename     : Handler.java
  |  * Version      : $Revision: $
  |  * Date         : $Date: $
  |  * Copyright(c) Ubiquity Software Corporation
  |  *         http://www.ubiquity.net
  |  */
  | package mcfproto.impl;
  | 
  | import java.io.BufferedReader;
  | import java.io.IOException;
  | import java.io.InputStreamReader;
  | import java.io.OutputStreamWriter;
  | import java.io.PrintWriter;
  | import java.net.Socket;
  | 
  | import org.jboss.logging.Logger;
  | 
  | public class Handler extends Thread {
  | 
  |    private final static Logger LOG = Logger.getLogger(Handler.class);
  | 
  |    private volatile boolean quit;
  | 
  |    private Socket m_Socket;
  | 
  |    private PrintWriter m_Writer;
  | 
  |    private NetServer m_Parent;
  | 
  |    public Handler(Socket socket, NetServer activator) throws Exception {
  |       m_Socket = socket;
  | 
  |       m_Parent = activator;
  |       m_Writer = new PrintWriter(new OutputStreamWriter(socket
  |             .getOutputStream()));
  |    }
  | 
  |    void close() {
  |       try {
  |          quit = true;
  |          m_Writer.close();
  |          m_Socket.close();
  |       } catch (IOException ioexception) {
  |       }
  |    }
  | 
  |    public void run() {
  |       try {
  |          send("Welcome to Proto. Please enter a command:");
  |          send("Ex: *[echo msg]");
  |          send("Ex: quit");
  |          BufferedReader reader = new BufferedReader(new InputStreamReader(
  |                m_Socket.getInputStream()));
  | 
  |          String line;
  |          send("\n\r");
  |          while (!quit && (line = reader.readLine()) != null) {
  |             process(clean(line));
  |          }
  |          send("\n\rbye");
  | 
  |       } catch (Exception e) {
  |          if (quit) {
  |             LOG.debug(e);
  |          } else {
  |             LOG.error(
  |                "Error whilst handler was trying to process client response.",
  |                 e);
  |          }
  |       } finally {
  |          // TODO: check: need reader.close() ???
  |          m_Parent.remove(this);
  |          close();
  |          m_Socket = null;
  |          m_Writer = null;
  |          m_Parent = null;
  |       }
  |       return;
  |    }
  | 
  |    private void send(String msg) throws IOException {
  |       m_Writer.println(msg);
  |       m_Writer.flush();
  |    }
  | 
  |    private void process(String line) throws IOException {
  | 
  |       LOG.debug("Handler:process() method called with \"" + line + "\"");
  |       if (line.startsWith("quit")) {
  |          LOG.debug("QUIT command received : (" + line + ")");
  |          quit = true;
  |       } else if (line.startsWith("*")) {
  |          line = line.substring(1, line.length());
  |          dispatch(line);
  |       } else {
  |          send("Unknown command received.");
  |       }
  |    }
  | 
  |    private void dispatch(String line) throws IOException {
  |       send(line);
  |    }
  | 
  |    private String clean(String line) {
  |       int size = line.length();
  |       char[] buffer = new char[size];
  |       int out = 0;
  |       for (int in = 0; in < size; in++) {
  |          char c = line.charAt(in);
  |          if (c == '\b') // backspace - ignore
  |          {
  |             if (out > 0) {
  |                out--;
  |             }
  |          } else if (c >= ' ' && c < '\177') {
  |             buffer[out++] = c;
  |          }
  |       }
  |       String cleanedString = new String(buffer, 0, out);
  | 
  |       return cleanedString;
  |    }
  | 
  | }
  | 

View the original post : http://www.jboss.com/index.html?module=bb&op=viewtopic&p=4192994#4192994

Reply to the post : http://www.jboss.com/index.html?module=bb&op=posting&mode=reply&p=4192994



More information about the jboss-user mailing list