... This is simply telling, that the items "jms/MyQCF", and "jms/MyQ" exist, and are instances of QueueConnectionFactory, and Queue, respectively. The actual configuration is in context.xml: ... Thus, if you have JNI code that follows the convention of including a static initilaizer like this:
No Format |
class FooWrapper {
static {
System.loadLibrary("foo");
}
native void doFoo();
}
|
then both this class and the shared library should be placed in the $CATALINA_HOME/shared/lib directory. ... The symptom of this problem that I encountered looked something like this -
No Format |
java.lang.UnsatisfiedLinkError: Native Library WEB-INF/lib/libfoo.so already loaded in another classloader
at java.lang.ClassLoader.loadLibrary0(ClassLoader.java:1525)
|
...
- If you have not already done so begin by creating a new Tomcat context for your application. Navigate to TOMCAT_HOME\conf\Catalina\localhost and create a new file, say, myapp.xml. This will become part of your url, so to access your app you'll have to type *http://localhost:8080/myapp*.
- Enter the following in myapp.xml:
No Format |
<Context docBase="c:/workspace/myapp/WebRoot" />
|
- This assumes you have a web application containing WEB-INF in c:/workspace/myapp/WebRoot
- Create two environment variables:
No Format |
C:\>set JPDA_ADDRESS=1044
C:\>set JPDA_TRANSPORT=dt_socket
|
- Now, you can launch Tomcat with these debug options:
No Format |
TOMCAT_HOME\bin\>catalina jpda start
|
- Use your IDE to connect to Tomcat through port 1044
See also: FAQ/Developing How do I debug a Tomcat application when Tomcat is run as a Windows service ? ...
- Launch a command prompt
- Set the proper CATALINA_HOME environment variable: pointing to tomcat home
- Run the following command:
No Format |
%CATALINA_HOME%\bin\tomcat6w.exe //ES//tomcat6
|
- Select the Java tab in the properties dialog box,
- Add the following two lines to the Java Options text box:
No Format |
-Xdebug
-Xrunjdwp:transport=dt_socket,address=127.0.0.1:1044,server=y,suspend=n
|
... For IntelliJ IDEA you choose a remote debug target and set transport to "socket" and mode to "attach" , then you specify the host (127.0.0.1) and port (1044) See also: FAQ/Developing How do I check whether Tomcat is UP or DOWN? There is no status command ... Here is my code to do this. Consider it public domain and use it as you see fit. Tomcat makes a note of this connection with something like this on the console.
No Format |
May 1, 2007 5:10:35 PM org.apache.catalina.core.StandardServer await
WARNING: StandardServer.await: Invalid command '' received
|
Ideally this should be incorporated into org.apache.catalina.util.ServerInfo by some committer. In addition to the shutdown command they should add commands like status (UP or DOWN) and uptime in the await method of org.apache.catalina.core.StandardServer
No Format |
import java.io.File;
import java.io.IOException;
import java.io.OutputStream;
import java.net.Socket;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.xml.sax.SAXException;
/**
* Check to see if Tomcat is UP/DOWN.
*
* This parses the server.xml file for the Tomcat admin port and see if
* we can connect to it. If we can, then the Tomcat is UP otherwise it
* is DOWN
*
* It is invoked as follows:
* java -Dcatalina.base=c:/tomcat-6.0.10 CatalinaStatus
*
* It can also (optionally) shutdown the Tomcat by adding the shutdown
* command line parameter as follows:
*
* java -Dcatalina.base=c:/tomcat-6.0.10 CatalinaStatus shutdown
*
* @author Shiraz Kanga <skanga at yahoo.com>
*/
public class CatalinaStatus
{
/**
* Pathname to the server configuration file.
*/
protected static String configFile = "conf/server.xml";
protected static String serverShutdown;
protected static int serverPort;
/**
* The application main program.
*
* @param args Command line arguments
*/
public static void main (String args[])
{
Document configDom = getXmlDom (configFile ());
parseDocument (configDom);
// System.out.println ("Catalina.serverPort: " + serverPort);
// System.out.println ("Catalina.serverShutdown: " + serverShutdown);
// Stop the existing server
try
{
Socket localSocket = new Socket ("127.0.0.1", serverPort);
System.err.println ("Server status: UP");
if ((args.length > 0) && (args[0].equalsIgnoreCase ("shutdown")))
{
System.out.println ("Tomcat shutdown initiated" );
doShutdown (localSocket);
}
localSocket.close ();
}
catch (IOException e)
{
System.err.println ("Server status: DOWN");
System.exit(1);
}
}
/**
* Return a File object representing our configuration file.
*/
protected static File configFile ()
{
File confFile = new File (configFile);
if (!confFile.isAbsolute())
confFile = new File (System.getProperty ("catalina.base"), configFile);
return (confFile);
}
/**
* Parses an XML file and returns a DOM document.
*/
public static Document getXmlDom (File fileName)
{
try
{
// Create a builder factory
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance ();
// Create the builder and parse the file
Document doc = factory.newDocumentBuilder ().parse (fileName);
return doc;
}
catch (SAXException e)
{
// A parsing error occurred; the xml input is not valid
e.printStackTrace ();
}
catch (ParserConfigurationException e)
{
e.printStackTrace ();
}
catch (IOException e)
{
e.printStackTrace ();
}
return null;
}
/**
* Extract the server port & shutdown command from the DOM
*/
private static void parseDocument (Document configDom)
{
//get the root element which is Server Eg: <Server port="8005" shutdown="SHUTDOWN">
Element docEle = configDom.getDocumentElement ();
serverPort = Integer.parseInt (docEle.getAttribute ("port"));
serverShutdown = docEle.getAttribute ("shutdown");
}
/**
* Send the shutdown command to the server
*/
private static void doShutdown (Socket localSocket)
{
try
{
OutputStream outStream = localSocket.getOutputStream ();
for (int i = 0; i < serverShutdown.length (); i++)
outStream.write (serverShutdown.charAt (i));
outStream.flush ();
outStream.close ();
}
catch (IOException e)
{
System.out.println ("ERROR: I/O Exception during server shutdown.");
e.printStackTrace ();
}
}
}
|
... Oracle JDK (not the JRE) (formerly Sun JDK) since version 1.6 (and since 1.4 on *nix systems) ships with a program called jstack (or jstack.exe on Microsoft Windows) which will give you a thread dump on standard output. Redirect the output into a file and you have your thread dump. You will need the process id ("pid") of the process to dump. Use of the program jps (jps.exe on Microsoft Windows) can help you determine the pid of a specific Java process. See Tools page in JDK documentation for usage reference. ... If you are running on Microsoft Windows You can try to use SendSignal, developed specifically for this purpose. Make sure you read the comments for certain sitautions (e.g. running as a service, RDP connections, etc.). http://www.latenighthacking.com/projects/2003/sendSignal/ ... If the monitoring application is not running, you can start it manually. The command is Tomcat8wTomcat9w.exe //MS// or Tomcat8wTomcat9w.exe //MS//servicename If you installed Tomcat with an "exe" installer, "Apache Tomcat version servicename" group in the Windows menu has shortcut "Monitor Tomcat" that starts the monitoring application. For details, see Windows service page in Tomcat documentation. If you have Tomcat running in a console ... Tomcat Manager web application starting with Tomcat 7.0.58 / 8.0.0 supports a command that outputs a thread dump. (Tomcat 8 9 documentation, BZ 57261) StuckThreadDetectionValve valve logs stacktraces of request processing threads that are busy for longer than configured time limit. It is available starting with Tomcat 6.0.36 / 7.0.14. (Tomcat 8 9 documentation) ... How do I read a Java thread dump ? ... One such tool is the Thread Dump Viewer (TDV), which you can find here: httphttps://tdv.sourceforge.net/projects/tdv/. It is a bit old (last release: 2007) but it can be somewhat helpful. How do I obtain a heap dump? See Getting a Heap Dump on the help pages of Eclipse Memory Analysis Tool. How do I add my own custom MBean to monitor my application within Tomcat 6? First of all, you can read this great tutorial from Christopher Blunck ( ch...@wxnet.org ). I will just add my comments and improvements. ... 1. Start your Tomcat and check that you have access to http://localhost:8080/manager/jmxproxy/. It means that JMX is enabled on your Tomcat configuration (if not, check if the following line is in your /conf/server.xml file: <Listener className="org.apache.catalina.mbeans.ServerLifecycleListener" /> ... Otherwise, check the Tomcat documentation to activate it). Let this page opened to check further if your custom ... MBean is detected by Tomcat. 2. Build your custom MBean by following the Christopher Blunck's example: ... In this implementation, firstly notice the ObjectName representing the MBean (in the constructor): name = new ObjectName("Application:Name=Server,Type=Server"); Do not hesitate to change the domain name (the first parameter) by your own to easily find your MBean reference in the http://localhost:8080/manager/jmxproxy page. Secondly, take a look at your MBean constructor:
- First step is to get a reference to the Tomcat's MBeanServer with MBeanServer server = getServer();.
...
- The getServer() method returns the first MBean server in the list of MBean servers registered in JVM, which is the one used by Tomcat.
In my application architecture, I placed the 2 MBeans files (the interface and its implementation) in a particular package (I don't think its compulsary but definitely more aesthetic). Compile those one in a jar archive and place it in the Tomcat's library folder (/lib ). 3. Build your ContextListener: According to the Tomcat's documentation, a Listener is a a component that performs actions when specific events occur, usually Tomcat starting or Tomcat stopping.. We need to instantiate and load our MBean at Tomcat's start. So we build a ContextListener.java file which is placed wherever you want in your project architecture:
No Format |
package '''org.bonitasoft.context''';
/**
* @author Christophe Havard
*
*/
import javax.servlet.ServletContext;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
import org.bonitasoft.mbeans.Server;
public final class ContextListener implements ServletContextListener {
public void contextInitialized(ServletContextEvent event) {
Server mbean = new Server();
}
public void contextDestroyed(ServletContextEvent event) { }
}
|
... Then, you have to modify your WEB-INF/web.xml file to make Tomcat execute your ContextListener.
No Format |
<?xml version="1.0" encoding="ISO-8859-1"?>
<!DOCTYPE web-app
PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
"http://java.sun.com/dtd/web-app_2_3.dtd">
<web-app>
<display-name>My Web Application</display-name>
'''''bla bla bla...'''''
<listener>
<listener-class>org.bonitasoft.context.ContextListener</listener-class>
</listener>
</web-app>
|
... 5. The configuration should be over. You should have done those the following operations:
- Build your MBean,
...
- Compile it and place the .jar archive in the Tomcat's /lib folder,
...
- Build your ContextListener.java,
...
- Add a reference to your ContextListener inside your WEB-INF/web.xml file
You can try to run your project. Open the http://localhost:8080/manager/jmxproxy page and find your custom MBean (with a simple ctrl+f). You can see its domain, name, type and its attributes and methods. You can now use this MBean in your application by getting a reference to the Tomcat's MBean server:
No Format |
MBeanServer mbs = ManagementFactory.getPlatformMBeanServer();
//call operations with invoke(...) and attributes with getAttributes(...)
|
Do not hesitate to check the ManagementFactory class javadoc. CategoryFAQ |