This bug occurs when my program enters the shutdown hook and tries to write the settings file to a text document. The strange thing is, it doesnt throw an exception everytime.
Exception in thread "Thread-4" java.lang.IllegalStateException: zip file closed
at java.util.zip.ZipFile.ensureOpen(Unknown Source)
at java.util.zip.ZipFile.getEntry(Unknown Source)
at java.util.jar.JarFile.getEntry(Unknown Source)
at java.util.jar.JarFile.getJarEntry(Unknown Source)
at com.crimson.server.JarClassLoader.findJarEntry(JarClassLoader.java:514)
at com.crimson.server.JarClassLoader.findJarClass(JarClassLoader.java:584)
at com.crimson.server.JarClassLoader.loadClass(JarClassLoader.java:956)
at java.lang.ClassLoader.loadClass(Unknown Source)
at com.crimson.universalUtils.Datastore.store(Datastore.java:66)
at com.crimson.server.ServerShutdownHook.run(ServerShutdownHook.java:38)
Here is Datastore.store(Settings):
public static File set = new File("settings.properties");
public static void store(Settings settings){
set.delete();
try {
set.createNewFile();
PrintWriter pw = new PrintWriter(set);//line 66
pw.println(ObjectTransfer.toString(settings));
pw.close();
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
I dont know why creating the PrintWriter calls ClassLoader.loadClass, but that could be the problem because im using JarClassLoader: http://www.jdotsoft.com/JarClassLoader.php
I checked the source code of JarClassLoader and the problem is that JarClassLoader also has a shutdown hook to close the jar file. And as the documentation of shutdown hooks says, they may be invoked in any order, or even in parallel. So when your hook "gets in" before JarClassLoaders, your code works. When it's a bit too late, you get this exception.
A way to get around this would be to ensure the PrintWriter class is loaded before invoking the shutdown hook.
Related
I have the following simple piece of code to register a DataProvider.
The line "Environment.isDestinationDataProviderRegistered()" fails. The try-catch doesn't catch it. The failure just kills the appication.
Is there a way to find out what is actually happening? There is not exception. The application just fails.
I even wrote some loggers to test the static class. All of the methods that started with Environment.in* print out the appropriate true/false response. But, when I logger out all the Environment.is* methods (also booleans), then each one kills the application.
It surprises me that a simple boolean is*() method would fail.
My code:
try {
destinationName = dbProps.getProperty(JCO_DESTINATION_NAME);
createDestination(destinationName);
if (! Environment.isDestinationDataProviderRegistered()) {
Environment.registerDestinationDataProvider(new SAPJCOUtils());
}
} catch (RuntimeException re) {
re.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
I have written a Java code that must run only after successful shutting down of weblogic server.
The code shuts down the weblogic server and performs the required operations and then restarts the servers.
My question now is .. Is there a way by which 1 can keep a tab on the weblogic console to see if the shutdown proceess is over or not or if there were some exceptions thrown by the server during startup or shut down(not manually but programmatically)??
In my local machine I had made the thread to sleep until the server was shutdown completely by keeping the average time to shut (manually).
The code goes as under:
static final String DOMAIN_NAMES = "domainNames";
static final String DOMAIN_HOME="domainHome";
public static void main(String[] argss)
{
AbstractApplicationContext context=new FileSystemXmlApplicationContext(new String[]{"src/main/resources/redeployconfig.xml"});
StepOneRedeploy stepOne=(StepOneRedeploy) context.getBean("stepOneRedeploy");
stepOne.setProperties();
Properties prop=stepOne.getProperties();
String domainNames = prop.getProperty(DOMAIN_NAMES);
System.out.println(domainNames);
String domainHome = prop.getProperty(DOMAIN_HOME);
StringTokenizer domainNamesTokens= new StringTokenizer(domainNames,",");
StringTokenizer domainNamesTokens2=domainNamesTokens;
ArrayList<String> serverIPListArray = new ArrayList<String>();
while (domainNamesTokens.hasMoreElements())
{
String domainName=domainNamesTokens.nextToken();
System.out.println(domainName);
serverIPListArray.add(domainName);
}
while(domainNamesTokens2.hasMoreElements())
{
String domainName=domainNamesTokens2.nextToken();
/** Stopping weblogicserver **/
String domainPathToShutServer = domainHome + domainName+"/stopWebLogic.cmd";
String commandToShutServer="cmd /C start "+domainPathToShutServer;
try
{
Process p = Runtime.getRuntime().exec(commandToShutServer,null);
}
catch (Exception e)
{
e.printStackTrace();
}
/**Putting thread to sleep for 1 minute**/
try {
Thread.sleep(20000);
} catch (InterruptedException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
/** Deleting temp folder **/
try
{
File delTmpFile=new File("");
boolean isTmpDelete=delTmpFile.delete();
System.out.println(isTmpDelete);
if(!isTmpDelete)
{
throw new TempDeleteFailedException("Could not delete Tmp folder for "+domainName);
}
}
catch(TempDeleteFailedException tdfe)
{
tdfe.printStackTrace();
}
catch(Exception e)
{
e.printStackTrace();
}
/** Deleting stage folder **/
try
{
File delStgFile=new File("");
boolean isStgDelete=delStgFile.delete();
System.out.println(isStgDelete);
if(isStgDelete)
{
throw new StageDeleteFailedException();
}
}
catch (StageDeleteFailedException stgDelEileException)
{
stgDelEileException.printStackTrace();
}
catch(Exception e)
{
e.printStackTrace();
}
/** Starting weblogicserver **/
String domainPath = domainHome + domainName+"/startWebLogic.cmd";
String command="cmd /C start "+domainPath;
try
{
Process p = Runtime.getRuntime().exec(command,null);
}
catch (Exception e)
{
e.printStackTrace();
}
}
}
I have tried ProcessBuilder to start weblogic server.
But it says that
java.io.IOException: Cannot run program "startWebLogic.cmd" (in directory "D:\Oracle\Middleware\user_projects\domains\ass1"): CreateProcess error=2, The system cannot find the file specified
at java.lang.ProcessBuilder.start(ProcessBuilder.java:470)
at TestMain.main(TestMain.java:35)
Caused by: java.io.IOException: CreateProcess error=2, The system cannot find the file specified
at java.lang.ProcessImpl.create(Native Method)
at java.lang.ProcessImpl.(ProcessImpl.java:177)
at java.lang.ProcessImpl.start(ProcessImpl.java:28)
at java.lang.ProcessBuilder.start(ProcessBuilder.java:452)
... 1 more
So if I were to refactor the Question...
How can 1 catch the exceptions thrown by the executable run using Java code?
Is there a way by which 1 can keep a tab on the weblogic console to see if the shutdown proceess is over or not or if there were some exceptions thrown by the server during startup or shut down(not manually but programmatically)??
Weblogic logs are written to disk. By default they ae in DOMAIN_NAME\servers\SERVER_NAME\logs\SERVER_NAME.log(see: Understanding WebLogic logging files).
Just monitor the server log for exceptions. Take a look at Commons IO - Tailer.
By the way, you can use WLST and JMX to stop, start, restart and monitor the health of Weblogic (see ServerRuntimeMBean and ServerLifeCycleRuntimeMBean), no need to fire standalone processes.
You can either:
Use MBeanServerConnection (see: This Example)
Use an Embbeded WLST interpreter to Manage the server Life Cycle.
"Waiting enough" is a bad idea as it will easily break when the situation changes, and using a process builder is very limiting (not to mention that, these startup scripts typically spawn the main process as a separate process so you don't get to watch them to start with).
I'd look into hooks that the WebLogic server provides. WebLogic has lots of hooks so I don't know which one would be appropriate for you, but for example if it's a servlet you could do your shutdown process from a ServletContextListener.
I am running in to some trouble when shutting down the server component and was hoping to get some help.
My server code looks as follows, it has a method to shut down the server
Server
private final String address = "127.0.0.1";
private Registry registry;
private int port = 6789;
public RmiServer() throws RemoteException {
try {
registry = LocateRegistry.createRegistry(port);
registry.rebind("rmiServer", this);
} catch (RemoteException e) {
logger.error("Unable to start the server. Exiting the application.", e);
System.exit(-1);
}
}
public void shutDownServer() throws RemoteException {
int succesful = 0;
try {
registry.unbind("rmiServer");
UnicastRemoteObject.unexportObject(this, true);
Thread.sleep(1000);
} catch (NotBoundException e) {
logger.error("Error shutting down the server - could not unbind the registry", e);
succesful = -1;
} catch (InterruptedException e) {
logger.info("Unable to sleep when shutting down the server", e);
succesful = -1;
}
catch (AccessException e) {
logger.info("Access Exception", e);
succesful = -1;
}
catch (UnmarshalException e) {
System.out.println(e.detail.getMessage());
logger.info("UnMarshall Exception", e);
succesful = -1;
}
catch (RemoteException e) {
System.out.println(e.detail.getMessage());
logger.info("Remote Exception", e);
succesful = -1;
}
logger.info("server shut down gracefully");
System.exit(succesful);
}
My client connects fine, no issues, so to shutdown i created a new application, copied the client code to connect and then call the close method on the server
Shutdown
public class Shutdown {
private String serverAddress = "127.0.0.1";
private String serverPort = "6789";
private ReceiveMessageInterface rmiServer;
private Registry registry;
public Shutdown(){
try {
registry = LocateRegistry.getRegistry(serverAddress, (new Integer(serverPort)).intValue());
rmiServer = (ReceiveMessageInterface) (registry.lookup("rmiServer"));
logger.info("Client started correctly");
rmiServer.shutDownServer();
System.exit(0);
}
catch (UnmarshalException e ){
logger.error("Unmarshall exception. Exiting application", e);
System.exit(-1);
}
catch (RemoteException e) {
logger.error("Remote object exception occured when connecting to server. Exiting application", e);
System.exit(-1);
} catch (NotBoundException e) {
logger.error("Not Bound Exception occured when connecting to server. Exiting application", e);
System.exit(-1);
}
}
No matter what i try i keep getting the following exception;
ERROR com.rmi.client.RMIClient - Unmarshall exception. Exiting application
java.rmi.UnmarshalException: Error unmarshaling return header; nested exception is:
java.net.SocketException: Connection reset
at sun.rmi.transport.StreamRemoteCall.executeCall(Unknown Source)
at sun.rmi.server.UnicastRef.invoke(Unknown Source)
at java.rmi.server.RemoteObjectInvocationHandler.invokeRemoteMethod(Unknown Source)
at java.rmi.server.RemoteObjectInvocationHandler.invoke(Unknown Source)
at $Proxy0.shutDownServer(Unknown Source)
at com.rmi.shutdown.Shutdown.<init>(Shutdown.java:31)
at com.rmi.shutdown.Shutdown.main(Shutdown.java:52)
Caused by: java.net.SocketException: Connection reset
at java.net.SocketInputStream.read(Unknown Source)
at java.io.BufferedInputStream.fill(Unknown Source)
at java.io.BufferedInputStream.read(Unknown Source)
at java.io.DataInputStream.readByte(Unknown Source)
... 7 more
I belive this might be due to the fact that the client is not properly disconnected and just gets "cut off" but i am unsure how else to disconnect the server side?
please can some one advise.
thanks
Unexport with force = true doesn't abort calls in progress. In general it will let in-progress calls run to completion. Your shutDownServer method is almost correct in that it unregisters the remote reference and unexports it. What it does next doesn't work, though. First, it sleeps for one second. This keeps the call in progress and keeps the client waiting for a reply. Then the shutdown code exits the server JVM without returning from the remote call. This closes client's connection while it's still awaiting a reply. That's why the client gets the connection reset exception.
To shut down cleanly, unregister the remote object, unexport it with force = true (as you've done) and then simply return. This will send a reply to the client, letting its remote call complete, and it will then exit. Back on the server, after the last in-progress call has completed, if there are no other objects exported, and if there's nothing else keeping the JVM around (such as non-daemon threads) the JVM will exit. You need to let RMI finish up its server-side processing instead of calling System.exit().
The system is doing exactly what you told it to do. You told it to unexport itself, and you set the 'force' parameter to true, which aborts calls in progress, so it unexported itself and aborted the call in progress. Just ignore it, or if you insist on a clean response to the shutdown client, have the server start a new thread for the unexport operation, with a short delay so the shutdown call can return to the client.
My code looks like this :
try
{
String htmlPageText=readFromHtml("http://www.yahoo.com");
}
catch (Exception e)
{
System.out.println("===Here===");
}
Method readFromHtml() will take a URL and return an HTML page. Normally it works fine. But I'm trying to simulate a "site down" situation, so I unplugged the Internet connection. I thought, the error should be caught and the result will be "===Here===", but instead, it returned:
java.net.UnknownHostException: http://www.yahoo.com"
and never printed out "===Here===". UnknownHostException is an extension of java.lang.Exception, so why was it not caught in the catch clause? Do I need a catch (UnknownHostException ex) to get it?
What is the readFromHTML method source code ? My guess is that this method throws some kind of exception but not UnknownHostException... Somewhere else in your code the exception is left unhandled.
I'm having a problem with a WCF Service and Java Client, I will try to give as much information as i can, thanks for your time.
The Endpoint of the server is BasicHttpBinding, I tried hosting the server as a Windows Service and in IIS but nothing changed.
The weird thing is that the Client works great if I use a simple class, in the moment I switch the class to an JApplet I get the problem mentioned.
I'm using Eclipse as an IDE, I tried Axis and Metro to generate the stub with the same bad results.
Here is an example of the Java class where everything is working
public class TestSoaMetro {
public String TestMethod(){
String result = null;
IDigitalSignatureService aa = new DigitalSignatureService().getBasicHttpBindingEndpoint();
try {
result = aa.getData("1", "id002962");
} catch (IDigitalSignatureServiceGetDataArgumentExceptionFaultFaultMessage e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IDigitalSignatureServiceGetDataInvalidOperationExceptionFaultFaultMessage e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return result;
}
}
Here is the example of the JApplet where I get the error:
public class TestSoaMetroApplet extends JApplet {
public void init() {
Container content = getContentPane();
content.setBackground(Color.white);
content.setLayout(new FlowLayout());
String result= this.TestMethod();
JLabel label = new JLabel(result);
content.add(label);
}
public String TestMethod(){
String result = null;
IDigitalSignatureService aa = null;
try {
aa = new DigitalSignatureService().getBasicHttpBindingEndpoint();
result= aa.getData("1", "id002962");
} catch (IDigitalSignatureServiceGetDataArgumentExceptionFaultFaultMessage e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IDigitalSignatureServiceGetDataInvalidOperationExceptionFaultFaultMessage e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return result;
}
}
In the moment the Applet loads I get the error, is the exact same call so I don't understand why I get the exception using the Applet. I Also tried to call this from a Silverlight client and I was getting a security exception, this is where I found out about clientaccesspolicy.xml and crossdomain.xml, I added clientaccesspolicy.xml to the service and the Silverlight Client works great, so I decided to try crossdomain.xml and nothing, the Applet still does not work.
I will put the stack trace at the end, thanks all for your time.
Juan Zamudio
javax.xml.ws.WebServiceException: org.apache.axis2.AxisFault: Transport error: 405 Error: Method not allowed
at org.apache.axis2.jaxws.ExceptionFactory.createWebServiceException(ExceptionFactory.java:175)
at org.apache.axis2.jaxws.ExceptionFactory.makeWebServiceException(ExceptionFactory.java:70)
at org.apache.axis2.jaxws.ExceptionFactory.makeWebServiceException(ExceptionFactory.java:128)
at org.apache.axis2.jaxws.core.controller.impl.AxisInvocationController.execute(AxisInvocationController.java:559)
at org.apache.axis2.jaxws.core.controller.impl.AxisInvocationController.doInvoke(AxisInvocationController.java:118)
at org.apache.axis2.jaxws.core.controller.impl.InvocationControllerImpl.invoke(InvocationControllerImpl.java:82)
at org.apache.axis2.jaxws.client.proxy.JAXWSProxyHandler.invokeSEIMethod(JAXWSProxyHandler.java:317)
at org.apache.axis2.jaxws.client.proxy.JAXWSProxyHandler.invoke(JAXWSProxyHandler.java:159)
at $Proxy12.getData(Unknown Source)
at TestSoaMetroApplet.TestMethod(TestSoaMetroApplet.java:28)
at TestSoaMetroApplet.init(TestSoaMetroApplet.java:19)
at sun.applet.AppletPanel.run(Unknown Source)
at java.lang.Thread.run(Unknown Source)
Caused by: org.apache.axis2.AxisFault: Transport error: 405 Error: Method not allowed
at org.apache.axis2.transport.http.HTTPSender.handleResponse(HTTPSender.java:295)
at org.apache.axis2.transport.http.HTTPSender.sendViaPost(HTTPSender.java:190)
at org.apache.axis2.transport.http.HTTPSender.send(HTTPSender.java:75)
at org.apache.axis2.transport.http.CommonsHTTPTransportSender.writeMessageWithCommons(CommonsHTTPTransportSender.java:389)
at org.apache.axis2.transport.http.CommonsHTTPTransportSender.invoke(CommonsHTTPTransportSender.java:222)
at org.apache.axis2.engine.AxisEngine.send(AxisEngine.java:435)
at org.apache.axis2.description.OutInAxisOperationClient.send(OutInAxisOperation.java:402)
at org.apache.axis2.description.OutInAxisOperationClient.executeImpl(OutInAxisOperation.java:229)
at org.apache.axis2.client.OperationClient.execute(OperationClient.java:165)
at org.apache.axis2.jaxws.core.controller.impl.AxisInvocationController.execute(AxisInvocationController.java:554)
... 9 more
The exception is obviously caused by an HTTP 405 error, so it is the server, which decides that the client is not allowed to invoke the method. If it is an applet or a standalone Java application should not really matter. Is the applet and the standalone application perhaps accessing the server from different IPs and the server is configured to allow access from the IP used by the standalone app, but denying access from the IP used by the applet?