StringBuilder: ArrayIndexOutOfBoundsException
Asked Answered
P

2

2

We're experiencing a strange issue with WebSphere 7/ IBM JDK 6, where one of the nodes has some initialization issue.

We have some code which calls InitialContext.lookup and on this node we're getting sometimes the following exception:

Caused by: java.lang.ArrayIndexOutOfBoundsException
         at java.lang.String.getChars(String.java:666)
         at java.lang.StringBuilder.append(StringBuilder.java:207)
         at javax.naming.spi.NamingManager.getURLContext(NamingManager.java:646)
         at javax.naming.InitialContext.getURLOrDefaultInitCtx(InitialContext.java:422)
         at javax.naming.InitialContext.lookup(InitialContext.java:436)
         [...]

We had a look at the source code of javax.naming.spi.NamingManager.getURLContext:

public static Context getURLContext(String schema, Hashtable<?, ?> envmt)
        throws NamingException {

    if (null == schema || 0 == schema.length() || null == envmt) {
        return null;
    }

    // obtain pkg prefixes from hashtable
    String pkgPrefixes[] = EnvironmentReader
            .getFactoryNamesFromEnvironmentAndProviderResource(envmt, null,
                    Context.URL_PKG_PREFIXES);

    for (String element : pkgPrefixes) {
        // create factory instance
        ObjectFactory factory;
        String clsName = element + "." //$NON-NLS-1$
                + schema + "." //$NON-NLS-1$
                + schema + "URLContextFactory"; //$NON-NLS-1$
    [...]

Line 646 is the enhanced for-loop, but the next statement is a String concatenation and is probably replaced with a StringBuilder by the compiler.

We did some quick unit tests on StringBuilder but couldn't provoke an ArrayIndexOutOfBoundsException.

How can an ArrayIndexOutOfBoundsException be thrown here and how can we avoid it?

Edit:

We are using the following java version:

java version "1.6.0"
Java(TM) SE Runtime Environment (build pxa6460sr9fp2ifix-20110913_02(SR9 FP2+IV03622+IZ99243))
IBM J9 VM (build 2.4, JRE 1.6.0 IBM J9 2.4 Linux amd64-64 jvmxa6460sr9-20110912_90359 (JIT enabled, AOT enabled)
J9VM - 20110912_090359
JIT  - r9_20101028_17488ifx31
GC   - 20101027_AA)
JCL  - 20110727_04
Photokinesis answered 17/4, 2013 at 12:17 Comment(6)
Have you tried setting a breakpoint to see what actually happens there?Tomcat
Too late, the problematic node as already been restarted. :-/Photokinesis
Don't you have a test system? ;-| Could you additionally post the code of the for-loop you've mentioned?Tomcat
It happened on the test system. ;-) But I'm not sure how easy it is to get one of the nodes in that state again on purpose.Photokinesis
@user714965 see my updated quesionPhotokinesis
@Udo Held: Thanks for the edit, I missed that. :-)Photokinesis
T
2

This is a known bug of the JIT compiler of the IBM JVM. The workaround seems to be the exclusion of getChars from the JIT compilation:

-Xjit:exclude={ProgramClass.callStringGetChars*}

See IZ78413: JIT-COMPILED STRING.GETCHARS THROWS UNEXPECTED ARRAYINDEXOUTOFBO UNDSEXCEPTION for reference.

Tomcat answered 17/4, 2013 at 13:6 Comment(3)
Thanks, I'll double check which version we have.Photokinesis
The issue says: "This defect will be fixed in: 6.0.0 SR9 . The JIT compiler has been updated to correct its algorithms. . To obtain the fix: Install build 20100622 or later" So we should have this fix (see my edited question, which mentions the java version we use)Photokinesis
I still don't know why the version we're using doesn't contain the fix, but I guess this answer goes in the right direction, so I'm accepting it.Photokinesis
T
0

The code above seems to return null if you pass a null environment hashtable.

This makes me wonder if you are instantiating InitialContext with an argument of some sort.

If the code above is indeed the source, passing a null environment hashtable will short-circuit getURLContext() to return null prior to the string concatenation loop.

Can you try new InitialContext() or new InitialContext(null) if you do not need to specify JNDI environment vars (e.g. use default JNDI env)?

Tagmemic answered 18/4, 2013 at 1:36 Comment(1)
We're using the no-argument constructor. If envmt were null, this wouldn't match the stack trace, I think.Photokinesis

© 2022 - 2024 — McMap. All rights reserved.