2

I need to close some streams when my Java EE app is undeployed to avoid pages of exceptions in the server.log every time I undeploy. The Exceptions say: "Input stream has been finalized or forced closed without being explicitly closed". I know how to close (with the close() method), but I dont know when.

finallize() comes too late, @PreDestroy is called not only before undeploying but also in normal operation mode. How does the app know, when it is undeployed?

Edit: I call this during creation:

    decisionLogger = KnowledgeRuntimeLoggerFactory.newThreadedFileLogger(
    ksession, 
    config.getString("rules.logfilename"), 
    config.getInt("rules.loginterval"));

decisionLogger is of type KnowledgeRuntimeLogger which has only the close() method. No getter for the thread that works under the hood. To shut it down gently, I need to call the close method, but when?

Arjan Tijms
  • 37,782
  • 12
  • 108
  • 140
Arne
  • 249
  • 4
  • 19
  • can you hook into the undeploy functionality of the app server you are using somehow? I'm not sure an app can know if it has been undeployed. You could also try swallowing the exceptions that the streams are throwing where you are using the streams in the code. – Matt Phillips Jul 23 '10 at 08:20
  • I use Glassfish 2.1. How can you hook into the undeploy functionality there? Swallowing the Exceptions is not an option, because I have no access to the thread that throws them. It is hidden in the Drools implementation. – Arne Jul 23 '10 at 08:54

2 Answers2

3

There are no hard and fast answers because Java EE encompasses a lot of technologies with variying lifecycles.

But I'm going to take a stab in the dark and suggest you look at ServletContextListener. This will tell you when your web application is being stopped, which is probably the time you want to release resources - not on application uninstall.

Jasper de Vries
  • 19,370
  • 6
  • 64
  • 102
McDowell
  • 107,573
  • 31
  • 204
  • 267
  • Unfortunately I do not have a web module in this app. It is just pure business logic. A JMS Topic as input, a rule engine and a mail server as output. Even more reason to include good logging capabilities, but this is exactly where the Exceptions are thrown. When the logger is destroyed during undeployment. – Arne Jul 23 '10 at 08:03
2

Add a finalize() method to the logger or whichever class is causing the issues. Close the streams from that. Unless you exit with System.exit() it will run. If System.exit is being called you can use Runtime.addShutdownHook

Matt Phillips
  • 11,249
  • 10
  • 46
  • 71
  • I use a logger of the Drools runtime. I cannot change that and I cannot subclass it because I get it from a factory that is part of the Drools runtime, too. And closing it in the finalize method of the object that uses it comes too late. I still get the exceptions then. – Arne Jul 23 '10 at 08:58
  • look at http://www.mckoi.com/database/maillist/msg00374.html . It gets the basics of what you could do. Create a method that registers with Runtime.addShutDownHook and that way when the runtime stops it will execute. – Matt Phillips Jul 23 '10 at 09:15
  • I tried that and found that it does not work in a JEE environment, since the JVM is not shut down when the app is undeployed. The ShutdownHook is never called when I undeploy. – Arne Jul 23 '10 at 09:53
  • I found another possible answer. It ties into what McDowell said about the servlet context listener http://stackoverflow.com/questions/1862242/trigger-function-when-undeploying-application . The drools runtime still has a web.xml which you need to edit in order to add the new context listener to it. – Matt Phillips Jul 28 '10 at 04:53