Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

BytesMessage problem revisited

6 views
Skip to first unread message

Anamitra

unread,
Feb 19, 2002, 12:10:14 PM2/19/02
to

Hi All
I am posting a stripped down version of my BytesMessageProducer.java - all it
does is reads some text/xml files as bytes and creates a message - adds 1-2 properties
and sends the message (PERSISTANT) to the Queue - having file/jdbc store. I have
no consumers sitting on the other side.
The obeservations are:
1> BytesMessage perform really bad - 5 times worse than text messages in WLS 6.1
sp2
2>If the file size is very big (like 4-5mb) after sending a few bytes messages
I get a PeerGoneException:

weblogic.jms.common.JMSException: Error sending message
at weblogic.jms.client.JMSProducer.sendMessage(JMSProducer.java:279)
at weblogic.jms.client.JMSProducer.send(JMSProducer.java:175)
at testmdb.BytesMsgProducer.example(BytesMsgProducer.java:126)
at testmdb.BytesMsgProducer.main(BytesMsgProducer.java:73)
----------- Linked Exception -----------
weblogic.rjvm.PeerGoneException: ; nested exception is:
java.io.EOFException
java.io.EOFException
at weblogic.rjvm.t3.T3JVMConnection.endOfStream(T3JVMConnection.java:599
)
at weblogic.socket.JavaSocketMuxer.processSockets2(JavaSocketMuxer.java:
311)
at weblogic.socket.JavaSocketMuxer.processSockets(JavaSocketMuxer.java:2
33)
at weblogic.socket.SocketReaderRequest.execute(SocketReaderRequest.java:
24)
at weblogic.kernel.ExecuteThread.execute(ExecuteThread.java:139)
at weblogic.kernel.ExecuteThread.run(ExecuteThread.java:120)
--------------- nested within: ------------------
weblogic.rmi.extensions.RemoteRuntimeException - with nested exception:
[weblogic.rjvm.PeerGoneException: ; nested exception is:
java.io.EOFException]
at weblogic.rmi.internal.ProxyStub.invoke(ProxyStub.java:60)
at $Proxy2.dispatchSyncNoTranFuture(Unknown Source)
at weblogic.jms.dispatcher.DispatcherWrapperState.dispatchSyncNoTran(Dis
patcherWrapperState.java:341)
at weblogic.jms.client.JMSProducer.sendMessage(JMSProducer.java:269)
at weblogic.jms.client.JMSProducer.send(JMSProducer.java:175)
at testmdb.BytesMsgProducer.example(BytesMsgProducer.java:126)
at testmdb.BytesMsgProducer.main(BytesMsgProducer.java:73)


I do not have a clue why I am facing this - if anyone in Weblogic can throw a
light on this - it will be of great help.

Note: I get this exception only for big messages - but same big message works
fine with TextMessage!!
TIA
Anamitra

Zach

unread,
Feb 19, 2002, 12:22:05 PM2/19/02
to
You did not post your code.

The EOF is strange. It is coming from the underlying stream. There is no
much JMS can do about it. Don't know.
_sjz.

"Anamitra" <ana_...@yahoo.com> wrote in message
news:3c7286f6$2...@newsgroups.bea.com...

Anamitra

unread,
Feb 19, 2002, 1:57:13 PM2/19/02
to

I hope I attached it corrcetly this time.
So what u are saying is this EOF is nothing related to JMS - what I will try is
use any other file to test this 5mb problem. But pls throw some light on this
performance stuff - I really am baffled to see bytes performing slower than text!
TIA
Anamitra

Anamitra

unread,
Feb 19, 2002, 1:59:09 PM2/19/02
to

Something is wrong with this mailing system - I have pasted the code here


package testmdb;

import java.rmi.RemoteException;
import java.util.Properties;

import javax.jms.JMSException;
import javax.jms.Message;
import javax.jms.Session;
import javax.jms.TextMessage;
import javax.jms.Topic;
import javax.jms.TopicConnection;
import javax.jms.TopicConnectionFactory;
import javax.jms.TopicPublisher;
import javax.jms.TopicSession;

import javax.jms.*;
import java.io.*;

import javax.ejb.CreateException;
import javax.ejb.RemoveException;
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;
import javax.rmi.PortableRemoteObject;
import javax.transaction.*;

public class BytesMsgProducer
{
static private String QUEUE_NAME = "testInQueue";

private String m_url;

private Context m_context;
private QueueConnection m_queueConnection;

public BytesMsgProducer(String url) throws NamingException
{
m_url = url;

try {
m_context = getInitialContext();

QueueConnectionFactory cf =
(QueueConnectionFactory) m_context.lookup("weblogic.jms.ConnectionFactory");
m_queueConnection = cf.createQueueConnection();
m_queueConnection.start();

}
catch(Exception ex) {
ex.printStackTrace();
}
}


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

log("\nBeginning message.Client...\n");

String url = "t3://localhost:7001";

BytesMsgProducer client = null;
try {
client = new BytesMsgProducer(url);
} catch (NamingException ne) {
System.exit(1);
}

try {
client.example();
}
catch (Exception e) {
e.printStackTrace();
}

log("\nEnd message.Client...\n");
}

/**
* Runs this example.
*/
public void example()
throws RemoteException, JMSException, NamingException
{
Queue newQueue = null;
QueueSession session = null;
try
{
session =
m_queueConnection.createQueueSession(true,
Session.AUTO_ACKNOWLEDGE);

newQueue = (Queue) m_context.lookup(QUEUE_NAME);
}
catch(NamingException ex)
{
ex.printStackTrace();
}

QueueSender sender = session.createSender(newQueue);
BytesMessage tm = session.createBytesMessage();

long t = System.currentTimeMillis();
for (int i = 0; i < 40; i++)
{
System.out.println(" preparing ----"+i);
tm.setStringProperty("order","msg "+i);
if((i%2)==0 )
{
tm.setStringProperty("orgid","EAGLENA");
}
else
{
tm.setStringProperty("orgid","EAGLESA");
}

long t1 = System.currentTimeMillis();
byte[] bytes = getXmlFile("po.xml");
long t2 = System.currentTimeMillis();
System.out.println("time to read------"+(t2-t1));

tm.writeBytes(bytes);
sender.send(tm, DeliveryMode.PERSISTENT, 4, 0);


session.commit();

long t3 = System.currentTimeMillis();

System.out.println("time to send------"+(t3-t2));

System.out.println(" send ----"+i);


}

long t4 = System.currentTimeMillis();
System.out.println("time total------"+(t4-t));
}


public byte[] getXmlFile(String fileName)
{
FileInputStream fi = null;
BufferedInputStream bf = null;
try
{

File f = new File(fileName);
byte[] bytes = new byte[(int)f.length()];
fi = new FileInputStream(f);
bf = new BufferedInputStream(fi);


bf.read(bytes,0,(int)f.length());

return bytes;
}
catch(Exception e)
{
e.printStackTrace();

return null;
}
finally
{
try{bf.close();}catch(Exception e2){}
}
}


private Context getInitialContext() throws NamingException {

try {
// Get an InitialContext
Properties h = new Properties();
h.put(Context.INITIAL_CONTEXT_FACTORY,
"weblogic.jndi.WLInitialContextFactory");
h.put(Context.PROVIDER_URL, m_url);
return new InitialContext(h);
}
catch (NamingException ex) {
throw ex;
}
}


private static void log(String s) {
System.out.println(s);
}

}

Anamitra

unread,
Feb 19, 2002, 2:47:48 PM2/19/02
to

Zach I tested the code with a different file - this file was the small file (145kb)
- that works - I just icreased the size of that file by doing "copy/paste" and
made that file 9mb - and this time the error showed up! - same error of PeerGone!!
- So the "bug" definitely has to do something with the file size - for 145kb files
- I never have this problem - only they are slower to TextMessages.
But if the files are big - I start getting this problem.
TIA
Anamitra

Ps: u can just ask BEA QA team to create any text file of 5mb or > and test this
code - in Win 2000 with file store. Should be easily reproduceable.

Tom Barnes

unread,
Feb 19, 2002, 2:50:08 PM2/19/02
to Anamitra
The interposed BufferedInputStream is expensive. Read from the file directly into the
buffer.
All the BIS does is introduce extra memory copies and synchronization.

If your XML file is directly I18N encoded (e.g. 2 bytes for each
character) the bytes message is likely going to take up twice as much
serialized space as the text message.

You have System.out as part of the timed code (System.out can be quite expensive
and has variable performance characteristics).

For that matter currentTimeMillis costs too, but probably not noticable for
persistent messages.

To best compare the two:

0) ensure client and server are on different boxes
1) create message
2) save currTime
3) send X times
4) rate = x/(currTime - savedTime)

This will measure pure JMS time, with no variance introduced
by client disk I/O or the time it takes client to set up the message.

Tom Barnes

unread,
Feb 19, 2002, 2:58:18 PM2/19/02
to dev....@not.my.address.com
Please post your code that converts the XML file into a String.

Anamitra

unread,
Feb 19, 2002, 3:11:24 PM2/19/02
to

As per ur prev post - I had actually done
----------------------------------------------------------

public byte[] getXmlFile(String fileName)
{
FileInputStream fi = null;
try
{

File f = new File(fileName);
byte[] bytes = new byte[(int)f.length()];

fi = new FileInputStream(f);
fi.read(bytes);

return bytes;
}
catch(Exception e)
{
e.printStackTrace();

return null;
}
finally
{
try{fi.close();}catch(Exception e2){}
}
}

with the same result.
------------------------------------------------------

TextMessage code below.

package testmdb;

import java.rmi.RemoteException;
import java.util.Properties;

import javax.jms.JMSException;
import javax.jms.Message;
import javax.jms.Session;
import javax.jms.TextMessage;
import javax.jms.Topic;
import javax.jms.TopicConnection;
import javax.jms.TopicConnectionFactory;
import javax.jms.TopicPublisher;
import javax.jms.TopicSession;

import javax.jms.*;
import java.io.*;

import javax.ejb.CreateException;
import javax.ejb.RemoveException;
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;
import javax.rmi.PortableRemoteObject;
import javax.transaction.*;

public class Client {


static private String QUEUE_NAME = "testInQueue";

private String m_url;

private Context m_context;
private QueueConnection m_queueConnection;

UserTransaction utx = null;

public Client(String url)


throws NamingException
{
m_url = url;

try {
//
// Create a context
//
m_context = getInitialContext();

//
// Create the connection and start it
//


QueueConnectionFactory cf =
(QueueConnectionFactory) m_context.lookup("weblogic.jms.ConnectionFactory");
m_queueConnection = cf.createQueueConnection();
m_queueConnection.start();

utx = (UserTransaction) m_context.lookup("javax.transaction.UserTransaction");

}
catch(Exception ex) {
ex.printStackTrace();
}
}


/**
* Runs this example from the command line. Example:
* <p>
* <tt>java examples.ejb20.message.Client "t3://localhost:7001"</tt>
* <p>
* The parameters are optional, but if any are supplied,
* they are interpreted in this order:
* <p>
* @param url URL such as "t3://localhost:7001" of Server
*/


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

log("\nBeginning message.Client...\n");

String url = "t3://localhost:7001";


Client client = null;
try {
client = new Client(url);
} catch (NamingException ne) {
System.exit(1);
}

try {
client.example();
}
catch (Exception e) {
e.printStackTrace();
}

log("\nEnd message.Client...\n");
}

/**
* Runs this example.
*/
public void example()
throws RemoteException, JMSException, NamingException
{
Queue newQueue = null;
QueueSession session = null;
try {
session =

m_queueConnection.createQueueSession(true, // non transacted
Session.AUTO_ACKNOWLEDGE);

newQueue = (Queue) m_context.lookup(QUEUE_NAME);
}
catch(NamingException ex) {

ex.printStackTrace();
}

QueueSender sender = session.createSender(newQueue);
TextMessage tm = session.createTextMessage();

long t = System.currentTimeMillis();
for (int i = 0; i < 40; i++) {

//tm.setJMSMessageID(String.valueOf(i));

System.out.println(" preparing ----"+i);
tm.setStringProperty("order","msg "+i);
if((i%2)==0 )
{
tm.setStringProperty("orgid","EAGLENA");
}
else
{
tm.setStringProperty("orgid","EAGLESA");
}

String as = null;

long t1 = System.currentTimeMillis();
as = getXmlFileString("po.xml");
long t2 = System.currentTimeMillis();

System.out.println("time to read------"+(t2-t1));

tm.setText(as);
sender.send(tm, DeliveryMode.PERSISTENT, 4, 3600000);


session.commit();

long t3 = System.currentTimeMillis();

System.out.println("time to send------"+(t3-t2));

System.out.println(" send ----"+i);

}

long t4 = System.currentTimeMillis();
System.out.println("time total------"+(t4-t));

//session.commit();
//session.commit();
}

public String getXmlFileString(String fileName)
{
FileInputStream fi = null;
try
{

File f = new File(fileName);
byte[] bytes = new byte[(int)f.length()];

fi = new FileInputStream(f);
fi.read(bytes);

return new String(bytes);


}
catch(Exception e)
{
e.printStackTrace();
return null;
}
finally
{

try{fi.close();}catch(Exception e2){}
}
}

/**
* Using a Properties object will work on JDK 1.1.x and Java2
* clients
*/


private Context getInitialContext() throws NamingException {

try {
// Get an InitialContext
Properties h = new Properties();
h.put(Context.INITIAL_CONTEXT_FACTORY,
"weblogic.jndi.WLInitialContextFactory");
h.put(Context.PROVIDER_URL, m_url);
return new InitialContext(h);
}
catch (NamingException ex) {

log("We were unable to get a connection to the WebLogic server at "+m_url);
log("Please make sure that the server is running.");
throw ex;
}
}

/**
* This is the Java2 version to get an InitialContext.
* This version relies on the existence of a jndi.properties file in
* the application's classpath.
*
*/
// private static Context getInitialContext()
// throws NamingException
// {
// return new InitialContext();
// }

Zach

unread,
Feb 19, 2002, 4:03:57 PM2/19/02
to
Note there is other stuff going on here (most notably transactions).

Is there anything in the server log file when you get the EOF? If
you send a 9MB text message it can be serialized to something
much larger. What is the maximum T3 message size defined as
on your server? The default is 10 MB.
_sjz.


Anamitra

unread,
Feb 19, 2002, 4:28:47 PM2/19/02
to

yes u are right I use the default size - 10mb - so now that u have said this -
it may happen that for bytes message some thing wrong is happening to make the
byte size bigger than what I am sending - so that explains why I get slower performance
for 145kb files - but no exception - and why I get exception for 5mb files.
But what confuses me is - if u have seen my code - I just loop through for 40
times and send the same file - for 5mb messages I get the error for the 3rd message.
For 9mb messages i get the error in the 2nd message - which is very interesting.
Also I tried by using a NON-TX session (passing the "false") - still the problem
happens at the same place.
So TX maynot be the problem.

I kind of think for some reason the byte message size is getting larger than expected
somewhere in the message sender framework of WLS.

Zach

unread,
Feb 19, 2002, 5:02:13 PM2/19/02
to
Except you create the message outside of the loop. Then you keep
appending 5 MB. The first is 5 MB, then 10, 15 and you fail on
the third. Your last message is something like 200 MB in length.
In the 9 MB case it fails on the second message. This too makes
sense. The first message you send is 9 MB, the second is 18
MB.

_sjz.

"Anamitra" <ana_...@yahoo.com> wrote in message

news:3c72c38f$1...@newsgroups.bea.com...

Zach

unread,
Feb 19, 2002, 5:08:31 PM2/19/02
to
Note that the TextMessage is faster for you because you have to do a
setText() which always replaces the text (as opposed to appending the text).
In the TextMessage case you send a total of 40 files worth of data. In the
BytesMessage case you are sending a total of 820 ((n * (n + 1)) / 2 ) files
worth of data. So you are sending roughly 20 times as much data and it
slows to 1/5th the speed (instead of 1/20th). Seems like ByteMessage
performance is quite a bit better than the TextMessage performance.

If you really want to test the messaging system performance, the read the
file once before you enter the loop. Then simply send the same message in
the loop.
_sjz.


Anamitra

unread,
Feb 19, 2002, 6:21:26 PM2/19/02
to

OOPS!! - I am sorry - yeah u are right I am creating it outside the loop - that
was the mistake - well thanks - I goofed up.
Anamitra

Cameron Purdy

unread,
Feb 21, 2002, 6:34:16 PM2/21/02
to
That won't work reliably. You need something like:

/**
* Read the contents out of the passed stream into the passed byte array
* and return the length read. This method will read up to the number of
* bytes that can fit into the passed array.
*
* @param stream a java.io.InputStream object to read from
* @param ab a byte array to read into
*
* @return the number of bytes read from the InputStream and stored into
* the passed byte array
*
* @throws java.io.IOException
*/
public static int read(InputStream stream, byte[] ab)
throws IOException
{
int MAX = ab.length;
int cb = 0;
boolean fEOF = false;
while (!fEOF && cb < MAX)
{
int cbBlock = stream.read(ab, cb, MAX - cb);
if (cbBlock < 0)
{
fEOF = true;
}
else
{
cb += cbBlock;
}
}
stream.close();
return cb;
}

Peace,

--
Cameron Purdy
Tangosol, Inc.
Clustering Weblogic? You're either using Coherence, or you should be!
Download a Tangosol Coherence eval today at http://www.tangosol.com/

"Anamitra" <ana_...@yahoo.com> wrote in message

news:3c72b16c$1...@newsgroups.bea.com...

0 new messages