You are viewing a plain text version of this content. The canonical link for it is here.
Posted to users@tomcat.apache.org by eurotrans-Verlag <ve...@t-online.de> on 2011/07/10 22:05:19 UTC

AJP-APR failures on Tomcat 7.0.16 with ISAPI Redirector 1.2.32

Hi all,

I have a system with Windows Server 2008 (32 bit), Sun/Oracle JDK 1.6.0_26
and I’m using Tomcat 7.0.16 with Tomcat Native 1.1.20, and IIS 7.0 with
ISAPI Redirector 1.2.32. For AJP, I use the AJP-APR connector.

Sometimes, when many requests are sent to a webapp in short time, some
requests fail, and the ISAPI log (log_level=error) says:

[Sun Jul 10 21:35:55.061 2011] [580:5032] [error]
ajp_get_reply::jk_ajp_common.c (2187): (worker1) Tomcat already send headers
[Sun Jul 10 21:35:55.071 2011] [580:5032] [error]
ajp_service::jk_ajp_common.c (2600): (worker1) sending request to tomcat
failed (unrecoverable),  (attempt=1)
[Sun Jul 10 21:35:55.080 2011] [580:5032] [error]
HttpExtensionProc::jk_isapi_plugin.c (2261): service() failed with http
error 502
[Sun Jul 10 21:35:55.087 2011] [580:4776] [error]
ajp_get_reply::jk_ajp_common.c (2187): (worker1) Tomcat already send headers
[Sun Jul 10 21:35:55.097 2011] [580:4776] [error]
ajp_service::jk_ajp_common.c (2600): (worker1) sending request to tomcat
failed (unrecoverable),  (attempt=1)
[Sun Jul 10 21:35:55.104 2011] [580:4776] [error]
HttpExtensionProc::jk_isapi_plugin.c (2261): service() failed with http
error 502
[Sun Jul 10 21:37:20.662 2011] [5696:3220] [error]
ajp_connection_tcp_get_message::jk_ajp_common.c (1296): wrong message format
0x3000 from 127.0.0.1:8019
[Sun Jul 10 21:37:20.679 2011] [5696:3220] [error]
ajp_get_reply::jk_ajp_common.c (2118): (worker1) Tomcat is down or refused
connection. No response has been sent to the client (yet)
[Sun Jul 10 21:42:56.105 2011] [580:5032] [error]
ajp_connection_tcp_get_message::jk_ajp_common.c (1296): wrong message format
0x3000 from 127.0.0.1:8019
[Sun Jul 10 21:42:56.135 2011] [580:5032] [error]
ajp_get_reply::jk_ajp_common.c (2118): (worker1) Tomcat is down or refused
connection. No response has been sent to the client (yet)
[Sun Jul 10 21:42:56.149 2011] [580:3100] [error]
ajp_get_reply::jk_ajp_common.c (2187): (worker1) Tomcat already send headers
[Sun Jul 10 21:42:56.160 2011] [580:3100] [error]
ajp_service::jk_ajp_common.c (2600): (worker1) sending request to tomcat
failed (unrecoverable),  (attempt=1)
[Sun Jul 10 21:42:56.168 2011] [580:3100] [error]
HttpExtensionProc::jk_isapi_plugin.c (2261): service() failed with http
error 502
[Sun Jul 10 21:45:49.849 2011] [580:4532] [error]
ajp_connection_tcp_get_message::jk_ajp_common.c (1296): wrong message format
0x3000 from 127.0.0.1:8019
[Sun Jul 10 21:45:49.867 2011] [580:4532] [error]
ajp_get_reply::jk_ajp_common.c (2118): (worker1) Tomcat is down or refused
connection. No response has been sent to the client (yet)

However I didn't see any errors in the Tomcat logs.

I could reproduce the errors by pressing F5 in Firefox several seconds, so
that FF makes a lot of requests in a short time.

However, when I switch to AJP BIO, it seems that the errors go away.


Please note that I'm also using the Java ImageIO to produce and serve images
with some servlets. I think somewhere I read that using the ImageIO with APR
connectors could cause problems. Is this correct? If yes, does that mean
that I have to stick with the AJP BIO (or NIO?) connector, instead of AJP
APR; or does anybody know why there are these errors?


Thanks.


Regards,
Konstantin Preißer


---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@tomcat.apache.org
For additional commands, e-mail: users-help@tomcat.apache.org


Re: AJP-APR failures on Tomcat 7.0.16 with ISAPI Redirector 1.2.32

Posted by Christopher Schultz <ch...@christopherschultz.net>.
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Konstantin,

On 8/23/2011 4:02 PM, Konstantin Preißer wrote:
> I see that you changed the flush() method in the decorator class to
>  pass flush() calls to the underlying stream as long as the stream
> is set to be "active".
> 
> The reason that I didn't make this call-through was because it
> seems that flush() is the only method called by the ImageIO (when
> the Image Writer is garbage collected), and by preventing any 
> pass-through of flush(), no errors can occur.
> 
> When flush() of the decorator class passes its call to the original
>  stream as long as it's active, there may be a race condition
> between the request processing thread of the Servlet and the GC
> thread which collects the Image Writer, which possibly (but highly
> unlikely) could cause a flush() call (from GC thread) on the
> already closed stream, even if the "isActive" flag is volatile
> (please correct me if I'm wrong - I'm not a expert in how GC is
> working).

I added the flush() pass-through in case you actually wanted to flush
the stream. It seems reasonable that you might want to flush the
buffer at some point, and turning flush() into a no-op didn't seem
like a good idea.

I would expect the image writer to be available for GC after the
request was processed, but I guess the request could have operations
after the ImageIO is actually done and you're right: the GC could
kick-in virtually at any time. If you use your wrapper class as a
fire-and-forget kind of thing while maintaining the original reference
to the OutputStream, I suppose you still have complete control over
flushing that underlying stream.

> Also, it seems that ImageIO is calling flush() a few times while 
> writing an image, and I wanted to avoid the unnecessary flush() 
> calls. ;-)

That's a different story :)

- -chris
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.10 (MingW32)
Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org/

iEYEARECAAYFAk5UEXkACgkQ9CaO5/Lv0PCiNQCgu1foU5uwo63iExja+Wf+WPys
8iIAoJRaIucq9losxjKp0kkhUs6ycZYj
=HDoE
-----END PGP SIGNATURE-----

---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@tomcat.apache.org
For additional commands, e-mail: users-help@tomcat.apache.org


RE: AJP-APR failures on Tomcat 7.0.16 with ISAPI Redirector 1.2.32

Posted by Konstantin Preißer <ve...@t-online.de>.
> -----Original Message-----
> From: Christopher Schultz [mailto:chris@christopherschultz.net]
> Sent: Tuesday, July 26, 2011 6:15 PM
> To: Tomcat Users List
> Subject: Re: AJP-APR failures on Tomcat 7.0.16 with ISAPI Redirector
> 1.2.32
> 
> Konstantin,
> 
> Such a class would definitely be useful to post on the Wiki.
> 

Hi Christopher,

Some days ago I made an entry in the Tomcat Wiki with such a OutputStream decorator class:
http://wiki.apache.org/tomcat/FAQ/KnownIssues#ImageIOIssues

I see that you changed the flush() method in the decorator class to pass flush() calls to the underlying stream as long as the stream is set to be "active".

The reason that I didn't make this call-through was because it seems that flush() is the only method called by the ImageIO (when the Image Writer is garbage collected), and by preventing any pass-through of flush(), no errors can occur.

When flush() of the decorator class passes its call to the original stream as long as it's active, there may be a race condition between the request processing thread of the Servlet and the GC thread which collects the Image Writer, which possibly (but highly unlikely) could cause a flush() call (from GC thread) on the already closed stream, even if the "isActive" flag is volatile (please correct me if I'm wrong - I'm not a expert in how GC is working).

Also, it seems that ImageIO is calling flush() a few times while writing an image, and I wanted to avoid the unnecessary flush() calls. ;-)


Regards,

Konstantin Preißer 


---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@tomcat.apache.org
For additional commands, e-mail: users-help@tomcat.apache.org


RE: AJP-APR failures on Tomcat 7.0.16 with ISAPI Redirector 1.2.32

Posted by eurotrans-Verlag <ve...@t-online.de>.
> -----Original Message-----
> From: Christopher Schultz [mailto:chris@christopherschultz.net]
> Sent: Tuesday, July 26, 2011 6:15 PM
> To: Tomcat Users List
> Subject: Re: AJP-APR failures on Tomcat 7.0.16 with ISAPI Redirector
> 1.2.32
> 
> You should also null-out the reference to Tomcat's output stream.
> 
> This would allow you to "leak" your own decorator objects but not
> interfere with Tomcat's ability to do it's own object management.
> 
> Such a class would definitely be useful to post on the Wiki.
> 

Hi Christopher,

thanks for your reply (and sorry for the delay).


What would be the best place to post such a class (plus the information about the ImageIO) on the Tomcat Wiki / is there any guide how to write articles there?


Thanks!

Konstantin Preißer


---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@tomcat.apache.org
For additional commands, e-mail: users-help@tomcat.apache.org


Re: AJP-APR failures on Tomcat 7.0.16 with ISAPI Redirector 1.2.32

Posted by Christopher Schultz <ch...@christopherschultz.net>.
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Konstantin,

On 7/14/2011 8:41 AM, eurotrans-Verlag wrote:
> An alternative that I could imagine, would be to create a class
> (that has a boolean flag) which extends OutputStream, and decorates
> another OutputStream that is given to the class in the constructor
> (that would be the OutputStream from the servlet's response). This
> class would pass all calls to it to the other OutputStream (as long
> as the flag is true), and as soon as close() or another special
> method is called, it sets the flag to false, which causes all other
> methods to do nothing (or throw an IOException). That way, Tomcat's
> OutputStream would also be protected from future calls from the
> ImageIO.

You should also null-out the reference to Tomcat's output stream.

This would allow you to "leak" your own decorator objects but not
interfere with Tomcat's ability to do it's own object management.

Such a class would definitely be useful to post on the Wiki.

> However, it seems also a bit strange to me that Tomcat is recycling 
> OutputStreams, because in my understanding, once an OutputStream is 
> closed, it should be impossible to do any further write() calls to 
> it.

True, but Tomcat tries to avoid as much memory churn as possible, and
re-uses objects whenever possible. You can change this behavior with
configuration if you want.

- -chris
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.10 (MingW32)
Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org/

iEYEARECAAYFAk4u6AQACgkQ9CaO5/Lv0PD6cACfW4BS55+FtwpK3ZonNjOuvfPV
v+MAn3iCTpTSI+FOBkgdI9UOZD4YvsM6
=oazD
-----END PGP SIGNATURE-----

---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@tomcat.apache.org
For additional commands, e-mail: users-help@tomcat.apache.org


RE: AJP-APR failures on Tomcat 7.0.16 with ISAPI Redirector 1.2.32

Posted by eurotrans-Verlag <ve...@t-online.de>.
Hi all,

> 
> An alternative that I could imagine, would be to create a class (that has
a
> boolean flag) which extends OutputStream, and decorates another
OutputStream
> that is given to the class in the constructor (that would be the
> OutputStream from the servlet's response). This class would pass all calls
> to it to the other OutputStream (as long as the flag is true), and as soon
> as close() or another special method is called, it sets the flag to false,
> which causes all other methods to do nothing (or throw an IOException).
That
> way, Tomcat's OutputStream would also be protected from future calls
> from the ImageIO.
> 

I now use a OutputStream decorator like this when calling ImageIO.write():

public class ImageIOBetterOutputStream extends OutputStream {
	private OutputStream out; // the actual stream
	private volatile boolean isActive = true;

	public ImageIOBetterOutputStream (OutputStream out) {
		this.out = out;
	}

	@Override
	public void close() throws IOException {
		if (isActive) {
			isActive = false; // deactivate
			try {
				out.close();
			} finally {
				out = null;
			}
		}
	}

	@Override
	public void flush() throws IOException {
		// do nothing
	}

	@Override
	public void write(byte[] b, int off, int len) throws IOException {
		if (isActive) {
			out.write(b, off, len);
		}
	}

	[...] (overwrite the other methods the same way)
}

That way, I don't have to use a ByteArrayOutputStream to buffer the contents
in memory, and Tomcat's OutputStream is also protected from future calls to
flush() from the ImageIO (I just have to make sure that the call to close()
is inside a finally-block). (If flush() is the only method that the ImageIO
calls after an IOException, it probably would be enough to overwrite flush()
only). Since I'm using this class as OutputStream for the ImageIO, there
also haven't been any more errors.


> I agree that this behavior of the ImageIO is very strange (flushing the
> OutputStream when the ImageWriter gets garbage-collected, if an
IOException
> was thrown when the IIO previously tried to write to the stream).
> However, it seems also a bit strange to me that Tomcat is recycling
OutputStreams,
> because in my understanding, once an OutputStream is closed, it should
> be impossible to do any further write() calls to it.
> 
> May I ask, what is the particular reason for Tomcat to recycle
> OutputStreams?

Does anyone have a clue about this? I can understand recycling objects like
the Request/Response objects (e.g. if they contain lots of fields), but at
the moment I don't have an idea why it would be useful to recycle
OutputStream objects.


> Also, is there any hint to this on the Tomcat documentation/wiki? Because
I
> don't think it would be unusual to dynamically generate images and
> serve them to clients using the ImageIO, and I think it could be a bit
> frustrating to find the actual problem if one doesn't know this.

I couldn't find any hints about this in the Tomcat documentation/wiki, but I
think it should be mentioned somewhere. Of course, the behavior of the
ImageIO is strange, but Tomcat's recycling of OutputStreams enable the
errors when using the ImageIO.
If it is desired, maybe I could contribute something to this topic for
docs/wiki?


Regards,

Konstantin Preißer


---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@tomcat.apache.org
For additional commands, e-mail: users-help@tomcat.apache.org


RE: AJP-APR failures on Tomcat 7.0.16 with ISAPI Redirector 1.2.32

Posted by eurotrans-Verlag <ve...@t-online.de>.
Hi André,

> -----Original Message-----
> From: André Warnier [mailto:aw@ice-sa.com]
> Sent: Thursday, July 14, 2011 1:00 PM
> To: Tomcat Users List
> Subject: Re: AJP-APR failures on Tomcat 7.0.16 with ISAPI Redirector
> 1.2.32
> 
> As a comment purely from a general programming point of view, not a
> Java/Tomcat
> programming point of view :
> 
> I am not familiar with the ByteArrayOutputStream, but from your usage
> of it above it seems
> to be a buffer in memory to which one can write, and with a special
> "writeTo" method which
> must be an efficient way to copy its contents to another stream.
> 
> If so, whether it is good practice or not would depend entirely on your
> particular
> circumstances : the size of the images you are handling this way, the
> number of
> simultaneous requests which you are handling, how much memory you have
> to play with, and
> how fast your CPU is.
> It is sometimes surprising to make the calculation.
> 
> (...)
> 
> So, compared to using the Response output stream directly, you would
> now use an additional
> (375 KB X 400) = 150,000 KB = about 150 MB additional Heap space
> 
> That seems reasonable to me.
> But of course it would be a problem if you are currently running Tomcat
> with a 128 MB heap.
> Or if your images, instead of being 250 KB on average, would be 250 MB.
> Or if filling up - and reading back - the ByteArrayOutputStream was
> very inefficient and
> used up all your CPU time.
> 
> On the other hand, the alternative is to have broken responses, so it
> may be better to add
> some RAM to the system.
> 


Thanks for your long response.

Your assumption about ByteArrayOutputStream is correct: It buffers the
contents written to it in a byte array, which automatically grows if its
capacity is exceeded, by factor 2.

However I think the memory is not a big issue here, because the data that is
written to the ByteArrayOutputStream is the compressed version of an image
that is already in RAM, and that is usually much bigger than the compressed
form. For example, when I have a BufferedImage of 800x600 pixel and 24 bit
per pixel (TYPE_INT_RGB), it consumes 800*600*3 bytes = 1,37 MiB in memory.
The size of the compressed form varies from file type (JPEG, PNG, ...) and
the contents of the image, but if I would save it as JPEG for example, it
will only take about 200 KiB, which is much less than the uncompressed form
in the memory.

An alternative that I could imagine, would be to create a class (that has a
boolean flag) which extends OutputStream, and decorates another OutputStream
that is given to the class in the constructor (that would be the
OutputStream from the servlet's response). This class would pass all calls
to it to the other OutputStream (as long as the flag is true), and as soon
as close() or another special method is called, it sets the flag to false,
which causes all other methods to do nothing (or throw an IOException). That
way, Tomcat's OutputStream would also be protected from future calls from
the ImageIO.


I agree that this behavior of the ImageIO is very strange (flushing the
OutputStream when the ImageWriter gets garbage-collected, if an IOException
was thrown when the IIO previously tried to write to the stream). However,
it seems also a bit strange to me that Tomcat is recycling OutputStreams,
because in my understanding, once an OutputStream is closed, it should be
impossible to do any further write() calls to it.

May I ask, what is the particular reason for Tomcat to recycle
OutputStreams?


Thanks!

Regards,
Konstantin Preißer


---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@tomcat.apache.org
For additional commands, e-mail: users-help@tomcat.apache.org


Re: AJP-APR failures on Tomcat 7.0.16 with ISAPI Redirector 1.2.32

Posted by André Warnier <aw...@ice-sa.com>.
eurotrans-Verlag wrote:
> Hi Rainer,
> 
>> -----Original Message-----
>> From: Rainer Jung [mailto:rainer.jung@kippdata.de]
>> Sent: Thursday, July 14, 2011 12:17 AM
>> At least there was trouble about Java2D for several users in the past.
>> One such issue:
>>
>> https://issues.apache.org/bugzilla/show_bug.cgi?id=41772
>> http://nerd.dk/blogs/bug-tomcat-or-java2d
>>
>> but you might find more.
>>
>> Regards,
>>
>> Rainer
>>
> 
> Thanks. In the meantime, I also came to that conclusion and replaced all
> instances of
> 
> ImageIO.write(img, "PNG", response.getOutputStream())
> 
> in my servlets/webapps with something like
> 
> ByteArrayOutputStream bout = new ByteArrayOutputStream();
> ImageIO.write(img, "PNG", bout);
> bout.writeTo(response.getOutputStream());
> 
> so that the ImageIO never sees the real OutputStream, and it seems to work
> fine (no more IllegalStateExceptions or "wrong message format" errors in the
> isapi log when using AJP-APR).
> 
> Is that a good practice (using ByteArrayOutputStream, then copy it to the
> response) to dynamically generate Images and serve them to the clients?
> Also, is there any hint to this on the Tomcat documentation/wiki? Because I
> don't think it would be unusual to dynamically generate images and serve
> them to clients using the ImageIO, and I think it could be a bit frustrating
> to find the actual problem if one doesn't know this.
> 

As a comment purely from a general programming point of view, not a Java/Tomcat 
programming point of view :

I am not familiar with the ByteArrayOutputStream, but from your usage of it above it seems 
to be a buffer in memory to which one can write, and with a special "writeTo" method which 
must be an efficient way to copy its contents to another stream.

If so, whether it is good practice or not would depend entirely on your particular 
circumstances : the size of the images you are handling this way, the number of 
simultaneous requests which you are handling, how much memory you have to play with, and 
how fast your CPU is.
It is sometimes surprising to make the calculation.

By writing an image first to a memory buffer, you use up the additional memory of that 
buffer, which is equal to the output size of your image, plus the overhead of the 
ByteArrayOutputStream structure.

So let's use some totally arbitrary parameters, just for the sake of an example :
- let's say that ByteArrayOutputStream has 50% overhead. So to store 250 KB of data, in 
reality uses up 375 KB of RAM
- you serve up to 100 basic browser page requests at a time (that is, the base html pages 
which include the images)
- each such page contains 4 (links to) images
- each image is on average 250 KB in size (a small jpeg)
- the browsers themselves, when finding image links in a page, will issue up to 4 
simultaneous requests for those images (the last time I looked, quite a long time ago, 
browsers only requested 2 things in parallel, but they might have improved since)

So you could in theory have 400 simultaneous requests, for 400 images, each 250 KB in size.
Thus your Tomcat server (supposing it can handle 400 threads at a time) would be creating 
400 instances of ByteArrayOutputStream, and
- first filling them up until they reach 250 KB of data
- then copying this data back onto the Response output stream
- then discarding the ByteArrayOutputStream

So, compared to using the Response output stream directly, you would now use an additional
(375 KB X 400) = 150,000 KB = about 150 MB additional Heap space

That seems reasonable to me.
But of course it would be a problem if you are currently running Tomcat with a 128 MB heap.
Or if your images, instead of being 250 KB on average, would be 250 MB.
Or if filling up - and reading back - the ByteArrayOutputStream was very inefficient and 
used up all your CPU time.

On the other hand, the alternative is to have broken responses, so it may be better to add 
some RAM to the system.

Note: the above calculation is probably quite questionable.  But it provides a quick 
estimate, that may be roughly within a factor 10 of reality.
I use this often at the beginning of a project, to at least get an idea whether something 
seems reasonable/feasible, or is totally off-kilter.

---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@tomcat.apache.org
For additional commands, e-mail: users-help@tomcat.apache.org


Re: AJP-APR failures on Tomcat 7.0.16 with ISAPI Redirector 1.2.32

Posted by Christopher Schultz <ch...@christopherschultz.net>.
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Konstantin,

On 7/13/2011 6:53 PM, eurotrans-Verlag wrote:
> Thanks. In the meantime, I also came to that conclusion and replaced
> all instances of
> 
> ImageIO.write(img, "PNG", response.getOutputStream())
> 
> in my servlets/webapps with something like
> 
> ByteArrayOutputStream bout = new ByteArrayOutputStream(); 
> ImageIO.write(img, "PNG", bout); 
> bout.writeTo(response.getOutputStream());
> 
> so that the ImageIO never sees the real OutputStream, and it seems to
> work fine (no more IllegalStateExceptions or "wrong message format"
> errors in the isapi log when using AJP-APR).

Wow, I'm surprised that had an effect. Or, rather, I'm surprised that
ImageIO doesn't have decent object reference management.

> Is that a good practice (using ByteArrayOutputStream, then copy it to
> the response) to dynamically generate Images and serve them to the
> clients?

There is a downside: you need a bunch of temporary memory available to
perform these image manipulations. ImageIO uses a lots of memory
already, and now you are going to have to buffer the entire output image
before the first byte is written back to the client. That means no
streaming whatsoever, which might strain your resources.

You might want to look at your heap size, average image size, and
estimated user load to determine if you want to do something like put a
hard limit on the number of image transformations that can be performed
simultaneously. Otherwise, you risk OOME.

> Also, is there any hint to this on the Tomcat documentation/wiki?
> Because I don't think it would be unusual to dynamically generate
> images and serve them to clients using the ImageIO, and I think it
> could be a bit frustrating to find the actual problem if one doesn't
> know this.

Tomcat obviously can't document all foreign API problems out there, but
it might be worth mentioning this one on the Wiki somewhere. Feel free
to create a wiki account and create a new page for these kinds of things.

- -chris
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.10 (MingW32)
Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org/

iEYEARECAAYFAk4u5yMACgkQ9CaO5/Lv0PDMGQCfSLZ1BpdK7GVqd5wh+ZjYzFTA
H50AoIzjIoX6r72h4k1/VMLLqBjNPSI8
=V6o8
-----END PGP SIGNATURE-----

---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@tomcat.apache.org
For additional commands, e-mail: users-help@tomcat.apache.org


RE: AJP-APR failures on Tomcat 7.0.16 with ISAPI Redirector 1.2.32

Posted by eurotrans-Verlag <ve...@t-online.de>.
Hi Rainer,

> -----Original Message-----
> From: Rainer Jung [mailto:rainer.jung@kippdata.de]
> Sent: Thursday, July 14, 2011 12:17 AM
> At least there was trouble about Java2D for several users in the past.
> One such issue:
> 
> https://issues.apache.org/bugzilla/show_bug.cgi?id=41772
> http://nerd.dk/blogs/bug-tomcat-or-java2d
> 
> but you might find more.
> 
> Regards,
> 
> Rainer
> 

Thanks. In the meantime, I also came to that conclusion and replaced all
instances of

ImageIO.write(img, "PNG", response.getOutputStream())

in my servlets/webapps with something like

ByteArrayOutputStream bout = new ByteArrayOutputStream();
ImageIO.write(img, "PNG", bout);
bout.writeTo(response.getOutputStream());

so that the ImageIO never sees the real OutputStream, and it seems to work
fine (no more IllegalStateExceptions or "wrong message format" errors in the
isapi log when using AJP-APR).

Is that a good practice (using ByteArrayOutputStream, then copy it to the
response) to dynamically generate Images and serve them to the clients?
Also, is there any hint to this on the Tomcat documentation/wiki? Because I
don't think it would be unusual to dynamically generate images and serve
them to clients using the ImageIO, and I think it could be a bit frustrating
to find the actual problem if one doesn't know this.


Thanks!


Regards,
Konstantin Preißer


---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@tomcat.apache.org
For additional commands, e-mail: users-help@tomcat.apache.org


Re: AJP-APR failures on Tomcat 7.0.16 with ISAPI Redirector 1.2.32

Posted by Rainer Jung <ra...@kippdata.de>.
On 13.07.2011 00:36, eurotrans-Verlag wrote:

> Hmm, could it be that the Java ImageIO is re-using OutputStreams after
> calling ImageIO.write(img, "PNG", out), so that I'm getting such a
> IllegalStateException? (I think I read somewhere that Tomcat is recycling
> OutputStream objects)
> Maybe that could also explain the AJP errors I got.

At least there was trouble about Java2D for several users in the past.
One such issue:

https://issues.apache.org/bugzilla/show_bug.cgi?id=41772
http://nerd.dk/blogs/bug-tomcat-or-java2d

but you might find more.

Regards,

Rainer


---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@tomcat.apache.org
For additional commands, e-mail: users-help@tomcat.apache.org


RE: AJP-APR failures on Tomcat 7.0.16 with ISAPI Redirector 1.2.32

Posted by eurotrans-Verlag <ve...@t-online.de>.
Hi André,

> -----Original Message-----
> From: André Warnier [mailto:aw@ice-sa.com]
> Sent: Tuesday, July 12, 2011 9:25 PM
> 
> Can you take a part of this setup out of the equation ?
> 
> For example, at the moment you have
> 
> browser <-> IIS <-> isapi_redir. <-> AJP Connector:8019 <->
> Tomcat+webapp
> 
> Could you eliminate the IIS + Isapi_redir part, having Tomcat listen on
> port 80/HTTP, like
> this :
> 
> browser <-> HTTP Connector:80 <-> Tomcat+webapp
> 
> ?
> 
> or like this, by using Apache httpd instead of IIS :
> 
> browser <-> Apache <-> mod_jk <-> AJP Connector:8019 <-> Tomcat+webapp
> 
> This may help pinpointing where the problem is, since you mentioned
> earlier that you can
> reproduce the problem by pressing F5 in Firefox.
> 

Unfortunately, I can't replace IIS with Apache or direct Tomcat HTTP
connector, as that webapp is on a public server where also other websites
are hosted, using IIS.
But perhaps I can see if I can reproduce the problem in a virtual machine.

Please note that I could only reproduce the problems that occurred before
switching from AJP-APR to AJP-BIO. There I could reproduce them by pressing
and holding F5 in Firefox for some seconds, but after I switched to AJP-BIO,
that didn't worked. The error message I wrote in the last mail did I see
when I read the isapi logs today.


Today I also got another strange exception in Tomcat (I don't know if it has
anything to do with the AJP errors):

13.07.2011 00:13:51 org.apache.catalina.core.StandardWrapperValve invoke
SCHWERWIEGEND: Servlet.service() for servlet [hauptSeite.HauptServlet] in
context with path [] threw exception
java.lang.IllegalStateException: Cannot create a session after the response
has been committed
	at
org.apache.catalina.connector.Request.doGetSession(Request.java:2734)
	at
org.apache.catalina.connector.Request.getSession(Request.java:2244)
	at
org.apache.catalina.connector.RequestFacade.getSession(RequestFacade.java:89
9)
	at common.Common2.getSession(Common2.java:102)
	at hauptSeite.HauptServlet.doThings(HauptServlet.java:136)
	at hauptSeite.HauptServlet.doGet(HauptServlet.java:98)
	at javax.servlet.http.HttpServlet.service(HttpServlet.java:621)
	at javax.servlet.http.HttpServlet.service(HttpServlet.java:722)
	at
org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(Application
FilterChain.java:304)
	at
org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterCh
ain.java:210)
	at
org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.ja
va:240)
	at
org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.ja
va:164)
	at
org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase
.java:462)
	at
org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:164
)
	at
org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:100
)
	at
org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java
:118)
	at
org.apache.catalina.valves.CrawlerSessionManagerValve.invoke(CrawlerSessionM
anagerValve.java:172)
	at
org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:403)
	at org.apache.coyote.ajp.AjpProcessor.process(AjpProcessor.java:292)
	at
org.apache.coyote.ajp.AjpProtocol$AjpConnectionHandler.process(AjpProtocol.j
ava:143)
	at
org.apache.coyote.ajp.AjpProtocol$AjpConnectionHandler.process(AjpProtocol.j
ava:129)
	at
org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:
309)
	at
java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.ja
va:886)
	at
java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:9
08)
	at java.lang.Thread.run(Thread.java:662)

This appeared some minutes ago. I also have seen this Exception some times
on JSP pages, but not on a normal Servlet (for JSP pages, the stack trace
contained "at
org.apache.jasper.runtime.JspFactoryImpl.getPageContext(JspFactoryImpl.java:
65)" and that was before any custom JSP code).

This above error is from a WebApp that I use for hosting images. The stack
trace seems to indicate that a response has been committed before a session
is created, however I absolutely never send any response before creating a
session in that Servlet (I call response.getWriter() or
response.getOutputStream several lines after I call request.getSession(true)
). 


Hmm, could it be that the Java ImageIO is re-using OutputStreams after
calling ImageIO.write(img, "PNG", out), so that I'm getting such a
IllegalStateException? (I think I read somewhere that Tomcat is recycling
OutputStream objects)
Maybe that could also explain the AJP errors I got.


Regards,

Konstantin Preißer


---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@tomcat.apache.org
For additional commands, e-mail: users-help@tomcat.apache.org


Re: AJP-APR failures on Tomcat 7.0.16 with ISAPI Redirector 1.2.32

Posted by André Warnier <aw...@ice-sa.com>.
eurotrans-Verlag wrote:
>> However, when I switch to AJP BIO, it seems that the errors go away.
>>
> 
> Although I now switched to AJP-BIO (by deleting/renaming tcnative-1.dll),
> today morning I got an error again in the ISAPI log:
> 
> [Tue Jul 12 06:04:49.812 2011] [4124:2444] [error]
> ajp_connection_tcp_get_message::jk_ajp_common.c (1296): wrong message format
> 0xdaed from 127.0.0.1:8019
> [Tue Jul 12 06:04:49.825 2011] [4124:2444] [error]
> ajp_get_reply::jk_ajp_common.c (2148): (worker1) Tomcat is down or network
> problems. Part of the response has already been sent to the client
> 
> This is how the AJP connector is configured in Tomcat:
> 
> <Connector port="8019" protocol="AJP/1.3" redirectPort="8743"
> URIEncoding="UTF-8" maxThreads="1024" />
> 
> 
> Any idea what could cause this errors?
> 
> 
> I don't know it that matters, but with one webapp, I'm using COM4J to access
> COM objects on the Windows system (but I want to get rid of it in the
> future).
> 
> 

Can you take a part of this setup out of the equation ?

For example, at the moment you have

browser <-> IIS <-> isapi_redir. <-> AJP Connector:8019 <-> Tomcat+webapp

Could you eliminate the IIS + Isapi_redir part, having Tomcat listen on port 80/HTTP, like 
this :

browser <-> HTTP Connector:80 <-> Tomcat+webapp

?

or like this, by using Apache httpd instead of IIS :

browser <-> Apache <-> mod_jk <-> AJP Connector:8019 <-> Tomcat+webapp

This may help pinpointing where the problem is, since you mentioned earlier that you can 
reproduce the problem by pressing F5 in Firefox.


---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@tomcat.apache.org
For additional commands, e-mail: users-help@tomcat.apache.org


RE: AJP-APR failures on Tomcat 7.0.16 with ISAPI Redirector 1.2.32

Posted by eurotrans-Verlag <ve...@t-online.de>.
> 
> However, when I switch to AJP BIO, it seems that the errors go away.
> 

Although I now switched to AJP-BIO (by deleting/renaming tcnative-1.dll),
today morning I got an error again in the ISAPI log:

[Tue Jul 12 06:04:49.812 2011] [4124:2444] [error]
ajp_connection_tcp_get_message::jk_ajp_common.c (1296): wrong message format
0xdaed from 127.0.0.1:8019
[Tue Jul 12 06:04:49.825 2011] [4124:2444] [error]
ajp_get_reply::jk_ajp_common.c (2148): (worker1) Tomcat is down or network
problems. Part of the response has already been sent to the client

This is how the AJP connector is configured in Tomcat:

<Connector port="8019" protocol="AJP/1.3" redirectPort="8743"
URIEncoding="UTF-8" maxThreads="1024" />


Any idea what could cause this errors?


I don't know it that matters, but with one webapp, I'm using COM4J to access
COM objects on the Windows system (but I want to get rid of it in the
future).


Thanks,

Konstantin Preißer


---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@tomcat.apache.org
For additional commands, e-mail: users-help@tomcat.apache.org