Overview
Running Oracle Weblogic server on Windows can be done in two ways:
- You can start Oracle Weblogic Server from the command line. This is good for test purposes but not very likely to be used in a production environment.
- You can install Oracle Weblogic Server to run as a windows service using the java wrapper beasvc.exe (or beasvcX64.exe on windows 64-bit)
The problem with the last option is that, if you stop the service, the Java Virtual Machine (and thus the Oracle Weblogic Server) simply gets killed. This can result in corrupt files, database connections that aren’t closed or even transactions that are started but won’t be stopped. A possible workaround is to stop each Weblogic server in the domain from the admin console. This not only time consuming but also not the preferred way of working.
In order to provide a proper shutdown, the beasvc.exe has an option called “stopclass”. It specifies a java class with a stop method that will be invoked at the moment the windows service gets stopped. Although you can write any kind of java code in the shutdown class, we will focus on writing code for a decent shutdown for both admin servers and managed servers.
The shutdown class works as follows:
- It sends a request over HTTP to the Admin server
- The Admin server sends the shutdown request to the corresponding server.
This means that the admin server sends a request to itself in case of a shutdown. The shutdown request for a managed server passes first via the admin server back to the managed server.
Configuration
First of all the beasvc.exe service wrapper needs to be aware of the shutdown class. This can be done by adding the -stopclass option (for example: -stopclass: be.i8c.systemtools.weblogic.ServerStopper)
Secondly, two options need to be set on each server in the domain:
- You have to enable tunneling. You do this by ticking “Enable Tunneling” under Domain > Environment > Servers > “Server” > Protocols > General
- You have to ignore http sessions during shutdown, otherwise the server keeps on waiting for ever until no more http sessions are active. Enable the option “Ignore Sessions During Shutdown” under Domain > Environment > Servers > “Server” > Control > Start/Stop
Code
package be.i8c.systemtools.weblogic;
import java.io.File;
import java.net.URL;
import java.net.URLClassLoader;
import java.util.Date;
import java.util.Iterator;
import java.util.Properties;
import java.util.Set;
import javax.naming.Context;
import weblogic.jndi.Environment;
import weblogic.management.MBeanHome;
import weblogic.management.runtime.ServerRuntimeMBean;
import weblogic.management.runtime.ServerStates;
public class ServerStopper
{
public static void stop()
{
Properties prop = System.getProperties();
try
{
MBeanHome home = null;
//url of the Admin server
String url = "";
if (prop.getProperty("weblogic.management.server") != null)
{
// this property will be set automatically on a managed server to indicate the location of the admin server
url = prop.getProperty("weblogic.management.server");
}
else
{
// the admin.url is a property to indicate the location of the admin server on the admin server. It refers to itself, but is necessary to perform a proper shutdown. You can add it manually as a –D property when you install the server as a windows service. The name of the property can be any random name.
url = prop.getProperty("admin.url");
}
// username and password to perform the shutdown operation
username = "username";
password = "password";
ServerRuntimeMBean serverRuntime = null;
Set mbeanSet = null;
Iterator mbeanIterator = null;
// Set ContextClassloader to prevent assertions
URL[] urls = { new File("/").toURL() };
Thread.currentThread().setContextClassLoader(new URLClassLoader(urls));
Environment env = new Environment();
env.setProviderUrl(url);
env.setSecurityPrincipal(username);
env.setSecurityCredentials(password);
Context ctx = env.getInitialContext();
home = (MBeanHome)ctx.lookup("weblogic.management.adminhome");
mbeanSet = home.getMBeansByType("ServerRuntime");
mbeanIterator = mbeanSet.iterator();
while(mbeanIterator.hasNext())
{
serverRuntime = (ServerRuntimeMBean)mbeanIterator.next();
try
{
// we have to add this check, since the iterator will list all the servers, both admin and managed. If we don’t add this check a shutdown of all the servers will be performed in case we only stop one server
if (serverRuntime.getName().equalsIgnoreCase(prop.getProperty("weblogic.Name")))
{
if(serverRuntime.getState().equals(ServerStates.RUNNING))
{
// we perform a normal shut down in case the server is in the RUNNING state
serverRuntime.shutdown();
}
else
{
//This is the same as a forced shutdown, but not the same as killing the JVM. We don’t do a normal shutdown in case the server is not in the RUNNING state.
System.exit(10);
}
}
}
catch (Exception e)
{
// You can do nothing over here. In case the shutdown call will fail, windows will wait for the service to end, but that won’t happen. It will kill the service anyway after a while.
}
}
}
catch (Exception e)
{
// We get here in case the admin server couldn’t be reached
System.exit(10);
}
}
}
Author: Dimitri Van Kerckhoven