You are viewing a plain text version of this content. The canonical link for it is here.
Posted to users@tomcat.apache.org by Steffen Heil <li...@steffen-heil.de> on 2010/08/31 00:38:06 UTC

OFFTOPIC: Java String problem - possible VM bug

Hi

I am sorry, I am asking something not really related to tomcat here.
While this may sound like a beginners question, I think I really what I am
doing in java, but this time I suspect I have found a scenario where the
sun/oracle VM exposes a bug with pure String handling.

So anyone who can find a bug in the procedure posted below is very welcome.
So is everyone who can direct me to some place better suited to ask this
question.

Finding bugs in a static method that only takes immutable arguments usually
seems easy... Turns out, it is not.

However, please note that I already tried to debug this in various ways and
the exception does NOT occur, as soon as a debugger is attached. The
exception is only thrown under 64bit Linux Server-VM, within tomcat. It is
neither thrown under 64bit Windows, nor on the very same Linux VM as
standalone testcase, nor when a debugger is remotely attached. The JREs
testest are 1.6u20 and 1.6u21.

The code in question is the following:


	@SuppressWarnings( "null" )
	public final static String replaceAll( String stack, String ...
replacements )
	{
		try {
			if ( stack == null )
				return stack;
			int index, pos;
			String niddle = null, string;
			int niddleLength, stringLength;
			for ( index = 0; true; index += 2 ) {
				if ( index >= replacements.length )
					return stack;
				niddle = replacements[ index ];
				pos = stack.indexOf( niddle );
				if ( pos != - 1 )
					break;
			}
			StringBuilder buffer = new StringBuilder( stack );
			niddleLength = niddle.length();
			string = replacements[ index + 1 ];
			if ( string == null )
				do
					buffer.delete( pos, pos +
niddleLength );
				while ( ( pos = buffer.indexOf( niddle, pos
) ) != - 1 );
			else {
				stringLength = string.length();
				do {
/*331*/				buffer.replace( pos, pos + niddleLength,
string );
					pos += stringLength;
				} while ( ( pos = buffer.indexOf( niddle,
pos ) ) != - 1 );
			}
			index += 2;
			for ( ; index < replacements.length; index += 2 ) {
				niddle = replacements[ index ];
				string = replacements[ index + 1 ];
				niddleLength = niddle.length();
				if ( string == null )
					for ( pos = 0; ( pos =
buffer.indexOf( niddle, pos ) ) != - 1; )
						buffer.delete( pos, pos +
niddleLength );
				else {
					stringLength = string.length();
					for ( pos = 0; ( pos =
buffer.indexOf( niddle, pos ) ) != - 1; pos += stringLength )
						buffer.replace( pos, pos +
niddleLength, string );
				}
			}
			return buffer.toString();
		} catch ( Throwable t ) {
.... (code to dump the arguments and the stack trace) ...
		}
	}


Note, that when the method is called, there are two arguments: one String
and a String[] with a length of 1004 Strings.... (I guarantee that this
String array is NOT modified during execution, not even afterwards.)
The execption is (it is thrown indirectly in the marked line 331):

java.lang.StringIndexOutOfBoundsException: start > length()
	at
java.lang.AbstractStringBuilder.replace(AbstractStringBuilder.java:799)
	at java.lang.StringBuilder.replace(StringBuilder.java:271)
	at
com.osiris4.core.utils.StringUtils.replaceAll(StringUtils.java:331)
	....


I can provide real arguments that lead to this exception, however, as there
are more than 1000 Strings (partially large ones) involved, I will skip them
here.
Anyone interested will get them by mail. I have various samples.


Currently this prevents loading my web application in about one of three
times. (And it also happens during internal computations which prevents
further work.) Sometimes this error can be "reproduced" (by restarting
tomcat) 10 times in a row, sometimes it does not occur within 20 restarts at
all. (Without changing anything in the systems configuration.)


Sorry again, for asking off-topic, but I don't know where to ask for help
anymore.

Regards,
  Steffen


RE: OFFTOPIC: Java String problem - possible VM bug

Posted by "Caldarale, Charles R" <Ch...@unisys.com>.
> From: Steffen Heil [mailto:lists@steffen-heil.de] 
> Subject: AW: OFFTOPIC: Java String problem - possible VM bug

> > There is a -XX option to limit or disable SSE usage:
> > -XX:UseSSE=n

> Hard to find more infomation on the web though. Even sun
> does not list that option.

There are many, many undocumented -XX options - you have to look at the JVM code.

> However -XX:UseSSE=3 seems to have solved it.

Good to know.

> -Xincgc 

Using the above depends mostly on your webapp and throughput requirements; Tomcat itself won't care.  With incremental GC, you will get shorter pauses for full GC events, but slightly less overall throughput.  Only you and your users can decide what's best.

More information here:
http://www.oracle.com/technetwork/java/javase/gc-tuning-6-140523.html#cms

> I read a bit about the new G1 collector? Is it better?

Probably a bit faster, but I have not put it under any real heavy loads.  I'd be concerned about stability with it until it's had a bit more seasoning.

 - Chuck


THIS COMMUNICATION MAY CONTAIN CONFIDENTIAL AND/OR OTHERWISE PROPRIETARY MATERIAL and is thus for use only by the intended recipient. If you received this in error, please contact the sender and delete the e-mail and its attachments from all computers.


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


AW: OFFTOPIC: Java String problem - possible VM bug

Posted by Steffen Heil <li...@steffen-heil.de>.
Hi

> You're right, it doesn't, at least on Windows.

Just verified that:

root@www:/opt/java/jdk1.6.0_21# ./bin/java -server -version
java version "1.6.0_21"
Java(TM) SE Runtime Environment (build 1.6.0_21-b06)
Java HotSpot(TM) 64-Bit Server VM (build 17.0-b16, mixed mode)

root@www:/opt/java/jdk1.6.0_21# ./bin/java -client -version
java version "1.6.0_21"
Java(TM) SE Runtime Environment (build 1.6.0_21-b06)
Java HotSpot(TM) 64-Bit Server VM (build 17.0-b16, mixed mode)

So, there really is no client vm.


> There is a -XX option to limit or disable SSE usage:
> 
> -XX:UseSSE=n

Thanks, great tip. Hard to find more infomation on the web though. Even sun
does not list that option.
However -XX:UseSSE=3 seems to have solved it. At least I could restart
tomcat 32 times without exception.
Without that switch I did not get above 5 times today.


Allow me a side question: A long time ago, I decided to use the following
options for tomcat:
-server // even no other choice
-Xmx1024m // differs per machine
-Xincgc 
-Djava.net.preferIPv4Stack=true
-XX:UseSSE=3 // that's new...

So what about that gc choice? Is it sane for tomcat? I read a bit about the
new G1 collector? Is it better?
Is there any recommendation for tomcat?


And once again: Thanks a lot, you solved my original problem! Owe you one.

Regards,
  Steffen



RE: OFFTOPIC: Java String problem - possible VM bug

Posted by "Caldarale, Charles R" <Ch...@unisys.com>.
> From: Steffen Heil [mailto:lists@steffen-heil.de] 
> Subject: AW: OFFTOPIC: Java String problem - possible VM bug

> java version "1.6.0_21"
> Java(TM) SE Runtime Environment (build 1.6.0_21-b06)
> Java HotSpot(TM) 64-Bit Server VM (build 17.0-b16, mixed mode)

> So I should update, right?

It's worth trying.

> The linux box has intel core i7 920 (xen domU), the windows host 
> has intel core2duo t5670.

I think that means the Windows box does not have SSE4 (or at least not 4.2), which has been the recent problem with String handling.

> 2) I thougth 64bit vms would not have a client mode....

You're right, it doesn't, at least on Windows.

There is a -XX option to limit or disable SSE usage:

-XX:UseSSE=n

where n is the highest SSE version to use.  Might try setting it to 3 or less and see if anything changes.

There's also -XX:-UseSSE42Intrinsics, but that should be off by default already.

 - Chuck


THIS COMMUNICATION MAY CONTAIN CONFIDENTIAL AND/OR OTHERWISE PROPRIETARY MATERIAL and is thus for use only by the intended recipient. If you received this in error, please contact the sender and delete the e-mail and its attachments from all computers.



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


AW: OFFTOPIC: Java String problem - possible VM bug

Posted by Steffen Heil <li...@steffen-heil.de>.
Hi


> Which 6u21?  Just to be confusing, Sun/Oracle has released two 6u21
levels:
> b06 and b07.

java version "1.6.0_21"
Java(TM) SE Runtime Environment (build 1.6.0_21-b06)
Java HotSpot(TM) 64-Bit Server VM (build 17.0-b16, mixed mode)

So I should update, right?


> http://marc.info/?l=tomcat-user&m=127855283122103&w=2

Interesting.
However, the neweset should be fixed sind b04:

http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=2192460


> Note that the Windows vs Linux may be a bit of a red herring if the CPU
chips
> are not identical, since different instructions are generated for
different
> chips.

The linux box has intel core i7 920 (xen domU), the windows host has intel
core2duo t5670.


> Does it fail if run in -client mode?

Didn't test that, as 
1) I always run tomcat in server mode.
2) I thougth 64bit vms would not have a client mode....

Should I test that?


Regards,
  Steffen


Re: OFFTOPIC: Java String problem - possible VM bug

Posted by Konstantin Kolinko <kn...@gmail.com>.
2010/8/31 Caldarale, Charles R <Ch...@unisys.com>:
>> From: Steffen Heil [mailto:lists@steffen-heil.de]
>> Subject: AW: OFFTOPIC: Java String problem - possible VM bug
>
>> I just looked at the sun/oracle download page and the most
>> recent jdk there (jdk-6u21-linux-x64.bin) is still the very
>> same I downloaded, that is b06.
>
> That's a bit weird - I'm running 6u21b07 on my Windows boxes, downloaded from Sun/Oracle.  I'll have to boot up a Linux and try an install for that - after dinner.
>

It was written somewhere [1] that b07 was released for Windows only.
The other versions remain to be at b06. (I do not see this explained
anywhere on the Oracle site).

[1] http://blog.eisele.net/2010/07/jdk-16021-b06-eclipse-vs-16021-b07.html

Best regards,
Konstantin Kolinko

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


RE: OFFTOPIC: Java String problem - possible VM bug

Posted by "Caldarale, Charles R" <Ch...@unisys.com>.
> From: Steffen Heil [mailto:lists@steffen-heil.de] 
> Subject: AW: OFFTOPIC: Java String problem - possible VM bug

> I just looked at the sun/oracle download page and the most 
> recent jdk there (jdk-6u21-linux-x64.bin) is still the very
> same I downloaded, that is b06.

That's a bit weird - I'm running 6u21b07 on my Windows boxes, downloaded from Sun/Oracle.  I'll have to boot up a Linux and try an install for that - after dinner.

 - Chuck


THIS COMMUNICATION MAY CONTAIN CONFIDENTIAL AND/OR OTHERWISE PROPRIETARY MATERIAL and is thus for use only by the intended recipient. If you received this in error, please contact the sender and delete the e-mail and its attachments from all computers.


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


AW: OFFTOPIC: Java String problem - possible VM bug

Posted by Steffen Heil <li...@steffen-heil.de>.
Strange. I just looked at the sun/oracle download page and the most recent
jdk there (jdk-6u21-linux-x64.bin) is still the very same I downloaded, that
is b06.
I downloaded it again and checked the md5sum, it is identical.....

Where can I get that b07 ?

> -----Ursprüngliche Nachricht-----
> Von: Steffen Heil [mailto:lists@steffen-heil.de]
> Gesendet: Dienstag, 31. August 2010 01:46
> An: 'Tomcat Users List'
> Betreff: AW: OFFTOPIC: Java String problem - possible VM bug
> 
> Hi
> 
> 
> > Which 6u21?  Just to be confusing, Sun/Oracle has released two 6u21
> levels:
> > b06 and b07.
> 
> java version "1.6.0_21"
> Java(TM) SE Runtime Environment (build 1.6.0_21-b06)
> Java HotSpot(TM) 64-Bit Server VM (build 17.0-b16, mixed mode)
> 
> So I should update, right?
> 
> 
> > http://marc.info/?l=tomcat-user&m=127855283122103&w=2
> 
> Interesting.
> However, the neweset should be fixed sind b04:
> 
> http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=2192460
> 
> 
> > Note that the Windows vs Linux may be a bit of a red herring if the CPU
> chips
> > are not identical, since different instructions are generated for
> different
> > chips.
> 
> The linux box has intel core i7 920 (xen domU), the windows host has intel
> core2duo t5670.
> 
> 
> > Does it fail if run in -client mode?
> 
> Didn't test that, as
> 1) I always run tomcat in server mode.
> 2) I thougth 64bit vms would not have a client mode....
> 
> Should I test that?
> 
> 
> Regards,
>   Steffen


RE: OFFTOPIC: Java String problem - possible VM bug

Posted by "Caldarale, Charles R" <Ch...@unisys.com>.
> From: Steffen Heil [mailto:lists@steffen-heil.de] 
> Subject: OFFTOPIC: Java String problem - possible VM bug

> The JREs testest are 1.6u20 and 1.6u21.

Which 6u21?  Just to be confusing, Sun/Oracle has released two 6u21 levels: b06 and b07.

There were several fixes for spurious out-of-range errors in 6u21-b06 server mode, so I'm surprised this one is still there.  Look at this thread for a bit more information:

http://marc.info/?l=tomcat-user&m=127855283122103&w=2

Note that the Windows vs Linux may be a bit of a red herring if the CPU chips are not identical, since different instructions are generated for different chips.

Does it fail if run in -client mode?

 - Chuck


THIS COMMUNICATION MAY CONTAIN CONFIDENTIAL AND/OR OTHERWISE PROPRIETARY MATERIAL and is thus for use only by the intended recipient. If you received this in error, please contact the sender and delete the e-mail and its attachments from all computers.



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


AW: OFFTOPIC: Java String problem - possible VM bug

Posted by Steffen Heil <li...@steffen-heil.de>.
Hi

> From your original post
> "The exception is only thrown under 64bit Linux Server-VM, within tomcat.
It
> is neither thrown under 64bit Windows, nor on the very same Linux VM as
> standalone testcase, nor when a debugger is remotely attached.
> "
> 
> Sounds like you're saying it only happens within Tomcat, sooo..... kinda
> would seem version(s) of tomcat this has manifested itself within would be
> helpful for those debugging to have exact same environment from which to
> try and replicate the *bug.  Either you misposted or I'm misunderstanding.
> Either way, I have same environment, I'll try and reproduce.

That standalone application that i used as testcase never threw that
exception.
I noted, that the exception only occurred within tomcat, as I suspected it a
problem with compiler optimizations and concurrency, which I don't have in a
standalone test case.

Regards,
  Steffen


Re: OFFTOPIC: Java String problem - possible VM bug

Posted by Jason Britton <jb...@gmail.com>.
>From your original post
"The exception is only thrown under 64bit Linux Server-VM, within tomcat. It
is neither thrown under 64bit Windows, nor on the very same Linux VM as
standalone testcase, nor when a debugger is remotely attached.
"

Sounds like you're saying it only happens within Tomcat, sooo..... kinda
would seem version(s) of tomcat this has manifested itself within would be
helpful for those debugging to have exact same environment from which to try
and replicate the *bug.  Either you misposted or I'm misunderstanding.
Either way, I have same environment, I'll try and reproduce.




On Mon, Aug 30, 2010 at 4:01 PM, Steffen Heil <li...@steffen-heil.de> wrote:

> Hi
>
> > What version tomcat?
>
> I see this under 6.0.29 [and I think under 6.0.18 before, but I am not
> sure], but as this is pure java code, not calling any tomcat code and not
> probably affected by tomcat code, I don't think that matters. (That's why I
> labeled that off-topic.)
>
> However, if it even could be of any help solving this mystery, I will
> provide any information needed.
>
> Regards,
>   Steffen
>
> >
> >
> > On Mon, Aug 30, 2010 at 3:38 PM, Steffen Heil <li...@steffen-heil.de>
> wrote:
> >
> > > Hi
> > >
> > > I am sorry, I am asking something not really related to tomcat here.
> > > While this may sound like a beginners question, I think I really what
> > > I am doing in java, but this time I suspect I have found a scenario
> > > where the sun/oracle VM exposes a bug with pure String handling.
> > >
> > > So anyone who can find a bug in the procedure posted below is very
> > welcome.
> > > So is everyone who can direct me to some place better suited to ask
> > > this question.
> > >
> > > Finding bugs in a static method that only takes immutable arguments
> > > usually seems easy... Turns out, it is not.
> > >
> > > However, please note that I already tried to debug this in various
> > > ways and the exception does NOT occur, as soon as a debugger is
> > > attached. The exception is only thrown under 64bit Linux Server-VM,
> > > within tomcat. It is neither thrown under 64bit Windows, nor on the
> > > very same Linux VM as standalone testcase, nor when a debugger is
> > > remotely attached. The JREs testest are 1.6u20 and 1.6u21.
> > >
> > > The code in question is the following:
> > >
> > >
> > >        @SuppressWarnings( "null" )
> > >        public final static String replaceAll( String stack, String ...
> > > replacements )
> > >        {
> > >                try {
> > >                        if ( stack == null )
> > >                                return stack;
> > >                        int index, pos;
> > >                        String niddle = null, string;
> > >                        int niddleLength, stringLength;
> > >                        for ( index = 0; true; index += 2 ) {
> > >                                if ( index >= replacements.length )
> > >                                        return stack;
> > >                                niddle = replacements[ index ];
> > >                                pos = stack.indexOf( niddle );
> > >                                if ( pos != - 1 )
> > >                                        break;
> > >                        }
> > >                        StringBuilder buffer = new StringBuilder( stack
> );
> > >                        niddleLength = niddle.length();
> > >                        string = replacements[ index + 1 ];
> > >                        if ( string == null )
> > >                                do
> > >                                        buffer.delete( pos, pos +
> > > niddleLength );
> > >                                while ( ( pos = buffer.indexOf( niddle,
> > > pos
> > > ) ) != - 1 );
> > >                        else {
> > >                                stringLength = string.length();
> > >                                do {
> > > /*331*/                         buffer.replace( pos, pos +
> niddleLength,
> > > string );
> > >                                        pos += stringLength;
> > >                                } while ( ( pos = buffer.indexOf(
> > > niddle, pos ) ) != - 1 );
> > >                        }
> > >                        index += 2;
> > >                        for ( ; index < replacements.length; index += 2
> )
> {
> > >                                niddle = replacements[ index ];
> > >                                string = replacements[ index + 1 ];
> > >                                niddleLength = niddle.length();
> > >                                if ( string == null )
> > >                                        for ( pos = 0; ( pos =
> > > buffer.indexOf( niddle, pos ) ) != - 1; )
> > >                                                buffer.delete( pos, pos
> > > + niddleLength );
> > >                                else {
> > >                                        stringLength = string.length();
> > >                                        for ( pos = 0; ( pos =
> > > buffer.indexOf( niddle, pos ) ) != - 1; pos += stringLength )
> > >                                                buffer.replace( pos,
> > > pos + niddleLength, string );
> > >                                }
> > >                        }
> > >                        return buffer.toString();
> > >                } catch ( Throwable t ) { .... (code to dump the
> > > arguments and the stack trace) ...
> > >                }
> > >        }
> > >
> > >
> > > Note, that when the method is called, there are two arguments: one
> > > String and a String[] with a length of 1004 Strings.... (I guarantee
> > > that this String array is NOT modified during execution, not even
> > > afterwards.) The execption is (it is thrown indirectly in the marked
> line 331):
> > >
> > > java.lang.StringIndexOutOfBoundsException: start > length()
> > >        at
> > > java.lang.AbstractStringBuilder.replace(AbstractStringBuilder.java:799)
> > >        at java.lang.StringBuilder.replace(StringBuilder.java:271)
> > >        at
> > > com.osiris4.core.utils.StringUtils.replaceAll(StringUtils.java:331)
> > >        ....
> > >
> > >
> > > I can provide real arguments that lead to this exception, however, as
> > > there are more than 1000 Strings (partially large ones) involved, I
> > > will skip them here.
> > > Anyone interested will get them by mail. I have various samples.
> > >
> > >
> > > Currently this prevents loading my web application in about one of
> > > three times. (And it also happens during internal computations which
> > > prevents further work.) Sometimes this error can be "reproduced" (by
> > > restarting
> > > tomcat) 10 times in a row, sometimes it does not occur within 20
> > > restarts at all. (Without changing anything in the systems
> > > configuration.)
> > >
> > >
> > > Sorry again, for asking off-topic, but I don't know where to ask for
> > > help anymore.
> > >
> > > Regards,
> > >   Steffen
> > >
> > >
>

AW: OFFTOPIC: Java String problem - possible VM bug

Posted by Steffen Heil <li...@steffen-heil.de>.
Hi

> What version tomcat?

I see this under 6.0.29 [and I think under 6.0.18 before, but I am not
sure], but as this is pure java code, not calling any tomcat code and not
probably affected by tomcat code, I don't think that matters. (That's why I
labeled that off-topic.)

However, if it even could be of any help solving this mystery, I will
provide any information needed.

Regards,
  Steffen

> 
> 
> On Mon, Aug 30, 2010 at 3:38 PM, Steffen Heil <li...@steffen-heil.de>
wrote:
> 
> > Hi
> >
> > I am sorry, I am asking something not really related to tomcat here.
> > While this may sound like a beginners question, I think I really what
> > I am doing in java, but this time I suspect I have found a scenario
> > where the sun/oracle VM exposes a bug with pure String handling.
> >
> > So anyone who can find a bug in the procedure posted below is very
> welcome.
> > So is everyone who can direct me to some place better suited to ask
> > this question.
> >
> > Finding bugs in a static method that only takes immutable arguments
> > usually seems easy... Turns out, it is not.
> >
> > However, please note that I already tried to debug this in various
> > ways and the exception does NOT occur, as soon as a debugger is
> > attached. The exception is only thrown under 64bit Linux Server-VM,
> > within tomcat. It is neither thrown under 64bit Windows, nor on the
> > very same Linux VM as standalone testcase, nor when a debugger is
> > remotely attached. The JREs testest are 1.6u20 and 1.6u21.
> >
> > The code in question is the following:
> >
> >
> >        @SuppressWarnings( "null" )
> >        public final static String replaceAll( String stack, String ...
> > replacements )
> >        {
> >                try {
> >                        if ( stack == null )
> >                                return stack;
> >                        int index, pos;
> >                        String niddle = null, string;
> >                        int niddleLength, stringLength;
> >                        for ( index = 0; true; index += 2 ) {
> >                                if ( index >= replacements.length )
> >                                        return stack;
> >                                niddle = replacements[ index ];
> >                                pos = stack.indexOf( niddle );
> >                                if ( pos != - 1 )
> >                                        break;
> >                        }
> >                        StringBuilder buffer = new StringBuilder( stack
);
> >                        niddleLength = niddle.length();
> >                        string = replacements[ index + 1 ];
> >                        if ( string == null )
> >                                do
> >                                        buffer.delete( pos, pos +
> > niddleLength );
> >                                while ( ( pos = buffer.indexOf( niddle,
> > pos
> > ) ) != - 1 );
> >                        else {
> >                                stringLength = string.length();
> >                                do {
> > /*331*/                         buffer.replace( pos, pos + niddleLength,
> > string );
> >                                        pos += stringLength;
> >                                } while ( ( pos = buffer.indexOf(
> > niddle, pos ) ) != - 1 );
> >                        }
> >                        index += 2;
> >                        for ( ; index < replacements.length; index += 2 )
{
> >                                niddle = replacements[ index ];
> >                                string = replacements[ index + 1 ];
> >                                niddleLength = niddle.length();
> >                                if ( string == null )
> >                                        for ( pos = 0; ( pos =
> > buffer.indexOf( niddle, pos ) ) != - 1; )
> >                                                buffer.delete( pos, pos
> > + niddleLength );
> >                                else {
> >                                        stringLength = string.length();
> >                                        for ( pos = 0; ( pos =
> > buffer.indexOf( niddle, pos ) ) != - 1; pos += stringLength )
> >                                                buffer.replace( pos,
> > pos + niddleLength, string );
> >                                }
> >                        }
> >                        return buffer.toString();
> >                } catch ( Throwable t ) { .... (code to dump the
> > arguments and the stack trace) ...
> >                }
> >        }
> >
> >
> > Note, that when the method is called, there are two arguments: one
> > String and a String[] with a length of 1004 Strings.... (I guarantee
> > that this String array is NOT modified during execution, not even
> > afterwards.) The execption is (it is thrown indirectly in the marked
line 331):
> >
> > java.lang.StringIndexOutOfBoundsException: start > length()
> >        at
> > java.lang.AbstractStringBuilder.replace(AbstractStringBuilder.java:799)
> >        at java.lang.StringBuilder.replace(StringBuilder.java:271)
> >        at
> > com.osiris4.core.utils.StringUtils.replaceAll(StringUtils.java:331)
> >        ....
> >
> >
> > I can provide real arguments that lead to this exception, however, as
> > there are more than 1000 Strings (partially large ones) involved, I
> > will skip them here.
> > Anyone interested will get them by mail. I have various samples.
> >
> >
> > Currently this prevents loading my web application in about one of
> > three times. (And it also happens during internal computations which
> > prevents further work.) Sometimes this error can be "reproduced" (by
> > restarting
> > tomcat) 10 times in a row, sometimes it does not occur within 20
> > restarts at all. (Without changing anything in the systems
> > configuration.)
> >
> >
> > Sorry again, for asking off-topic, but I don't know where to ask for
> > help anymore.
> >
> > Regards,
> >   Steffen
> >
> >

Re: OFFTOPIC: Java String problem - possible VM bug

Posted by Jason Britton <jb...@gmail.com>.
What version tomcat?


On Mon, Aug 30, 2010 at 3:38 PM, Steffen Heil <li...@steffen-heil.de> wrote:

> Hi
>
> I am sorry, I am asking something not really related to tomcat here.
> While this may sound like a beginners question, I think I really what I am
> doing in java, but this time I suspect I have found a scenario where the
> sun/oracle VM exposes a bug with pure String handling.
>
> So anyone who can find a bug in the procedure posted below is very welcome.
> So is everyone who can direct me to some place better suited to ask this
> question.
>
> Finding bugs in a static method that only takes immutable arguments usually
> seems easy... Turns out, it is not.
>
> However, please note that I already tried to debug this in various ways and
> the exception does NOT occur, as soon as a debugger is attached. The
> exception is only thrown under 64bit Linux Server-VM, within tomcat. It is
> neither thrown under 64bit Windows, nor on the very same Linux VM as
> standalone testcase, nor when a debugger is remotely attached. The JREs
> testest are 1.6u20 and 1.6u21.
>
> The code in question is the following:
>
>
>        @SuppressWarnings( "null" )
>        public final static String replaceAll( String stack, String ...
> replacements )
>        {
>                try {
>                        if ( stack == null )
>                                return stack;
>                        int index, pos;
>                        String niddle = null, string;
>                        int niddleLength, stringLength;
>                        for ( index = 0; true; index += 2 ) {
>                                if ( index >= replacements.length )
>                                        return stack;
>                                niddle = replacements[ index ];
>                                pos = stack.indexOf( niddle );
>                                if ( pos != - 1 )
>                                        break;
>                        }
>                        StringBuilder buffer = new StringBuilder( stack );
>                        niddleLength = niddle.length();
>                        string = replacements[ index + 1 ];
>                        if ( string == null )
>                                do
>                                        buffer.delete( pos, pos +
> niddleLength );
>                                while ( ( pos = buffer.indexOf( niddle, pos
> ) ) != - 1 );
>                        else {
>                                stringLength = string.length();
>                                do {
> /*331*/                         buffer.replace( pos, pos + niddleLength,
> string );
>                                        pos += stringLength;
>                                } while ( ( pos = buffer.indexOf( niddle,
> pos ) ) != - 1 );
>                        }
>                        index += 2;
>                        for ( ; index < replacements.length; index += 2 ) {
>                                niddle = replacements[ index ];
>                                string = replacements[ index + 1 ];
>                                niddleLength = niddle.length();
>                                if ( string == null )
>                                        for ( pos = 0; ( pos =
> buffer.indexOf( niddle, pos ) ) != - 1; )
>                                                buffer.delete( pos, pos +
> niddleLength );
>                                else {
>                                        stringLength = string.length();
>                                        for ( pos = 0; ( pos =
> buffer.indexOf( niddle, pos ) ) != - 1; pos += stringLength )
>                                                buffer.replace( pos, pos +
> niddleLength, string );
>                                }
>                        }
>                        return buffer.toString();
>                } catch ( Throwable t ) {
> .... (code to dump the arguments and the stack trace) ...
>                }
>        }
>
>
> Note, that when the method is called, there are two arguments: one String
> and a String[] with a length of 1004 Strings.... (I guarantee that this
> String array is NOT modified during execution, not even afterwards.)
> The execption is (it is thrown indirectly in the marked line 331):
>
> java.lang.StringIndexOutOfBoundsException: start > length()
>        at
> java.lang.AbstractStringBuilder.replace(AbstractStringBuilder.java:799)
>        at java.lang.StringBuilder.replace(StringBuilder.java:271)
>        at
> com.osiris4.core.utils.StringUtils.replaceAll(StringUtils.java:331)
>        ....
>
>
> I can provide real arguments that lead to this exception, however, as there
> are more than 1000 Strings (partially large ones) involved, I will skip
> them
> here.
> Anyone interested will get them by mail. I have various samples.
>
>
> Currently this prevents loading my web application in about one of three
> times. (And it also happens during internal computations which prevents
> further work.) Sometimes this error can be "reproduced" (by restarting
> tomcat) 10 times in a row, sometimes it does not occur within 20 restarts
> at
> all. (Without changing anything in the systems configuration.)
>
>
> Sorry again, for asking off-topic, but I don't know where to ask for help
> anymore.
>
> Regards,
>   Steffen
>
>