Monthly Archive: July 2010

Troubleshooting Out Of Memory Errors in Weblogic using Eclipse Memory Ananlyser

Eclipse Memory Ananlyser is a very useful tool to analyze heap dumps. It has a lot of features such as Memory Leak detection where it runs an automated test to determine the suspected leaks.

Here is the Procedure

Step 1). Start the Weblogic Server, with the application in active state which causes memory leak.

Step 2). Get the process id of the server using jps


Step 3). Acess the application that causes memory leak

Step 4).Take heap dump at regular interval using jmap.

jmap -dump:format=b,file=dump1.bin 5004

Step 5).Open the Heap Dump in Eclipse Memory Ananlyzer (U can download it from http://www.eclipse.org/mat/downloads.php) Approximate size is 42 MB..Just u need to extract this Zip then u can directly start (no Installation needed)

Observe the heap usage of Objects in the heap dumps. If the object instance keeps on increasing in the subequent heap dumps, force a garbage collection from the Weblogic Server console


Take heap dumps again and open in the Eclipse Memory Analyzer. If the number of instances still don’t go down for those objects, you can expect to see this

<Jul 16, 2010 10:49:15 AM IST> <Critical> <Health> <BEA-310003> <Free memory in
the server is 47,856 bytes. There is danger of OutOfMemoryError>
Exception in thread “Thread-12” java.lang.OutOfMemoryError: Java heap space
at demo.MemoryLeakTest.runTest(MemoryLeakTest.java:14)
at jsp_servlet.__memoryleak$1.run(__memoryleak.java:86)
at java.lang.Thread.run(Thread.java:619)

.

If the leak is happening due to a Weblogic Class, it can be a known issue or an undiscovered BUG. You need to get in touch with Oracle Support. If it’s an Application Class, you need to contact the developers. Out of Memory can also happen dude to third party codes such as database drivers.

Configuring Distributed Topic on Weblogic Server

A distributed topic is a set of physical JMS topic members. As such, a distributed topic can be used to create a TopicPublisher and TopicSubscriber. The fact that a distributed topic represents multiple physical topics is mostly transparent to the application.

Note: Durable subscribers (DurableTopicSubscriber) cannot be created for distributed topics. However, you can still create a durable subscription on distributed topic member and the other topic members will forward the messages to the topic member that has the durable subscription.

The topic members can be located anywhere but must all be served either by a single WebLogic Server or any number of servers in a cluster. When a message is sent to a distributed topic, it is sent to all of the topic members in the distributed topic set. This allows all subscribers to the distributed topic to receive messages published for the distributed topic.

Read more

Create two managed servers (MS1 and MS2) and assign it to cluster (Cluster).

Create two JMS Server (JMSServer-0 and JMSServer-1) and assign it to each managed servers (MS1 and MS2).

Create JMS module and target it to cluster.

Create a JMS connection factory (ConnectionFactory1) and target it to cluster.

Create a Distributed Topic (MyDistributedTopic) and target it to the cluster.


Check  the jndi tree for connection factory and distributed topic.

Use the TopicSend and TopicReceive Program to send and receive messages.
You can find the programs here
C:\bea\weblogic92\samples\server\examples\src\examples\jms\topic

Change the JNDI Name of the ConnectionFactory and the Topic.

Send message to distributed topic

java TopicSend t3://xxxx.xxxx.com:7003,xxxx.xxxx.com:7005

Receive message from the topic

java TopicReceive t3://xxxx.xxxx.com:7003,xxxx.xxxx.com:7005

Please refer this post for more details.

Securing Cookies on Weblogic Server

HTTPOnly

HTTPOnly flag is used to prevent Client side scripts to read the cookies (provided the Browser Supports it). By Default Cookie is set to HTTP Only in 11g, so when we try to read the cookies from a JAVA Script, we wont be able to read it.

Some applications dont work if the cookie is set to HTTPOnly, it can be disabled by adding the following in Session Descriptor.

<cookie-http-only>false</cookie-http-only>

Cooke Secure
When we enable cookie secure, we the cookie is sent over a secure connection.
So while using this feaure we should ensure that the application is acessible over SSL.
It can be enabled by adding the following in the session-descriptor. Note url-rewriting should be disabled.

<session-descriptor>
<cookie-secure >true</cookie-secure >
<url-rewriting-enabled>true</url-rewriting-enabled>
</session-descriptor >

WL AuthCookie.

When any secure resource is accessed over SSL, Weblogic Server adds another cookie named _WL_AUTHCOOKIE_JSESSIONID_ to the header for greater security. One must send both, the jsessionid and wl authcookie for all secure reources which are accessed over SSL. If wl authcookie is missing then one has to authenticate again.  The wl authcookie is sent encrypted over the network which makes it so secure.

It is enabled by default. To disable it, we need to add AuthCookieEnabled=”true” in the WebServer element in the config.xml

<WebServer Name=”myserver” AuthCookieEnabled=”true”/>

References :-

http://www.owasp.org/index.php/HttpOnly
http://download.oracle.com/docs/cd/E13222_01/wls/docs100/security/thin_client.html

JBoss JMS Queue configuration

Configuring JMS providers in JBoss:-
********************************
The below example demonstrates a JMS example using Queue Destination (Point – To – Point messaging feature) using the JBoss default Queue.

JBoss defines default JMS queue and Topic Destination defined in $JBOSS_HOME/server/<server-profile>/deploy/messaging/ destinations-service.xml.

You can add/remove destinations to this file, or deploy another *-service.xml descriptor with the destination configurations.

Below are the steps to setup JMS Queues in JBoss:-

1:- Start the JBoss server, select the server type which provides messaging features like all or default

Run.bat –c all


2:- Set the classpath to jbossall-client.jar which is located in the client folder.

set classpath=%CLASSPATH%;F:\jboss-5.1.0.GA\client\jbossall-client.jar

3:- Compile the below QueueSend.java  program.

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Hashtable;
import javax.jms.*;
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;
import java.util.Properties;

public class QueueSend
{

public final static String JNDI_FACTORY="org.jboss.naming.HttpNamingContextFactory";
public final static String JMS_FACTORY="ConnectionFactory";
public final static String QUEUE="/queue/DLQ";
private QueueConnectionFactory qconFactory;
private QueueConnection qcon;
private QueueSession qsession;
private QueueSender qsender;
private Queue queue;
private TextMessage msg;

public void init(Context ctx, String queueName)
throws NamingException, JMSException
{
qconFactory = (QueueConnectionFactory) ctx.lookup(JMS_FACTORY);
qcon = qconFactory.createQueueConnection();
qsession = qcon.createQueueSession(false, Session.AUTO_ACKNOWLEDGE);
queue = (Queue) ctx.lookup(queueName);
qsender = qsession.createSender(queue);
msg = qsession.createTextMessage();
qcon.start();
}

public void send(String message) throws JMSException {
msg.setText(message);
qsender.send(msg);
}

public void close() throws JMSException {
qsender.close();
qsession.close();
qcon.close();
}

public static void main(String[] args) throws Exception {
if (args.length != 1) {
System.out.println("Usage: java examples.jms.queue.QueueSend JBossURL");
return;
}
InitialContext ic = getInitialContext(args[0]);
QueueSend qs = new QueueSend();
qs.init(ic, QUEUE);
readAndSend(qs);
qs.close();
}

private static void readAndSend(QueueSend qs)
throws IOException, JMSException
{
BufferedReader msgStream = new BufferedReader(new InputStreamReader(System.in));
String line=null;
boolean quitNow = false;
do {
System.out.print("Enter message (\"quit\" to quit): \n");
line = msgStream.readLine();
if (line != null && line.trim().length() != 0) {
qs.send(line);
System.out.println("JMS Message Sent: "+line+"\n");
quitNow = line.equalsIgnoreCase("quit");
}
} while (! quitNow);

}

private static InitialContext getInitialContext(String url)
throws NamingException
{

Properties env = new Properties();
env.setProperty(Context.INITIAL_CONTEXT_FACTORY, JNDI_FACTORY);
env.setProperty(Context.PROVIDER_URL,url);
return new InitialContext(env);
} }

4:- Run the QueueSend.java program as below.
java QueueSend http://127.0.0.1:8080/invoker/JNDIFactory

output:-
*********
Enter message (“quit” to quit):
test
JMS Message Sent: test

5: Compile and execute the below QueueRecieve.java program similar to QueueSend.java.

 

import java.util.Hashtable;
import javax.jms.*;
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;
import java.util.Properties;

public class QueueReceive implements MessageListener

{
public final static String JNDI_FACTORY="org.jboss.naming.HttpNamingContextFactory";

public final static String JMS_FACTORY="ConnectionFactory";

public final static String QUEUE="/queue/DLQ";

private QueueConnectionFactory qconFactory;
private QueueConnection qcon;
private QueueSession qsession;
private QueueReceiver qreceiver;
private Queue queue;
private boolean quit = false;

public void onMessage(Message msg)
{
try {
String msgText;
if (msg instanceof TextMessage) {
msgText = ((TextMessage)msg).getText();
} else {
msgText = msg.toString();
}
System.out.println("Message Received: "+ msgText );
if (msgText.equalsIgnoreCase("quit")) {
synchronized(this) {
quit = true;
this.notifyAll(); // Notify main thread to quit
}
}
} catch (JMSException jmse) {
System.err.println("An exception occurred: "+jmse.getMessage());
}
}

public void init(Context ctx, String queueName)
throws NamingException, JMSException
{
qconFactory = (QueueConnectionFactory) ctx.lookup(JMS_FACTORY);
qcon = qconFactory.createQueueConnection();
qsession = qcon.createQueueSession(false, Session.AUTO_ACKNOWLEDGE);
queue = (Queue) ctx.lookup(queueName);
qreceiver = qsession.createReceiver(queue);
qreceiver.setMessageListener(this);
qcon.start();
}

public void close()throws JMSException
{
qreceiver.close();
qsession.close();
qcon.close();
}

public static void main(String[] args) throws Exception {

if (args.length != 1) {
System.out.println("Usage: java examples.jms.queue.QueueReceive JBossURL");
return;
}
InitialContext ic = getInitialContext(args[0]);
QueueReceive qr = new QueueReceive();
qr.init(ic, QUEUE);

System.out.println("JMS Ready To Receive Messages (To quit, send a \"quit\" message).");

synchronized(qr) {
while (! qr.quit) {
try {
qr.wait();
} catch (InterruptedException ie) {}
}
}
qr.close();
}

private static InitialContext getInitialContext(String url)
throws NamingException
{
Properties env = new Properties();
env.setProperty(Context.INITIAL_CONTEXT_FACTORY,JNDI_FACTORY);
env.setProperty(Context.PROVIDER_URL,url);
return new InitialContext(env);
}

}

 

6. Run the QueueRecieve.java as below.

java QueueReceive http://127.0.0.1:8080/invoker/JNDIFactory


JMS Ready To Receive Messages (To quit, send a “quit” message).
Message Received: test

References:-
http://docs.jboss.org/jbossas/docs/Server_Configuration_Guide/4/html/JMS_Examples-A_Point_To_Point_Example.html

NOTE: Most common errors while looking up to JBoss JNDI.
*************************************************

Exception in thread “main” javax.naming.NoInitialContextException:
Cannot instantiate class: org.jboss.naming.HttpNamingContextFactory
[Root exception is java.lang.ClassNotFoundException: org.jboss.naming.HttpNamingContextFactory]
at javax.naming.spi.NamingManager.getInitialContext(NamingManager.java:657)
at javax.naming.InitialContext.getDefaultInitCtx(InitialContext.java:288)
at javax.naming.InitialContext.init(InitialContext.java:223)
at javax.naming.InitialContext.(InitialContext.java:197)
at QueueSend.getInitialContext(QueueSend.java:122)
at QueueSend.main(QueueSend.java:90)

Caused by: java.lang.ClassNotFoundException: org.jboss.naming.HttpNamingContextFactory
at java.net.URLClassLoader$1.run(URLClassLoader.java:200)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(URLClassLoader.java:188)
at java.lang.ClassLoader.loadClass(ClassLoader.java:307)
at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:301)
at java.lang.ClassLoader.loadClass(ClassLoader.java:252)

Solution:-
The problem is with the classpath setting and the classloader is not able to load the class “org.jboss.naming.HttpNamingContextFactory” class.

Set the classpath to point to jbossall-client.jar which would be under $JBOSS_HOME\client\jbossall-client.jar

set classpath=%classpath%;$JBOSS_HOME\client\jbossall-client.jar;

Else, you can run your java applications like

java -cp “$JBOSS_HOME\client\jbossall-client.jar”  QueueReceive

Cheers,

Wonders Team. 🙂