2

I met a quite strange case in a program with jdk1.8, that I got a null pointer exception in String.length (which is in StringBuilder.append()) method,

the exact position of the null pointer exception is here in String of jdk,

public int length() {
        return value.length;  //line 623
    }

and it's called in AbstractStringBuilder class :

public AbstractStringBuilder append(String str) {
        if (str == null)
            return appendNull();
        int len = str.length();  //here line 447
        ensureCapacityInternal(count + len);
        str.getChars(0, len, value, count);
        count += len;
        return this;
    }

I can't understand how this can happen, as there is a null check before str.length() called.

And maybe due to the same reason, all the way I tried to print the string content crashed, so I can't get what string content caused this.

Now, what I want to know is what can cause this, can I build a string content to reproduce this? Thanks for any ideas.

the stacktrace

java.lang.NullPointerException
at java.lang.String.length(String.java:623)
at java.lang.AbstractStringBuilder.append(AbstractStringBuilder.java:447)
at java.lang.StringBuilder.append(StringBuilder.java:141)
at ....toString(....java:14)  //a toString method of some class
at java.lang.String.valueOf(String.java:2994)
at java.lang.StringBuilder.append(StringBuilder.java:136)
at java.util.AbstractCollection.toString(AbstractCollection.java:462)
at java.lang.String.valueOf(String.java:2994)
at java.lang.StringBuilder.append(StringBuilder.java:136)
at com

I got this in both these two enviroments:

java version "1.8.0_102" Java(TM) SE Runtime Environment (build 1.8.0_102-b14) Java HotSpot(TM) 64-Bit Server VM (build 25.102-b14, mixed mode)

and

openjdk version "1.8.0_345" OpenJDK Runtime Environment (Temurin)(build 1.8.0_345-b01) OpenJDK 64-Bit Server VM (Temurin)(build 25.345-b01, mixed mode)

12
  • 2
    @Stultuske it's the source code of jdk, with no change Commented Jul 25, 2024 at 8:13
  • 1
    Are you sure you're looking at the right version of AbstractStringBuilder? Where did you find the source code? There may be differences between jdk versions (both between, say, 1.8.1 and 1.8.100, and also between the same version but from different vendors, e.g. Oracle and Amazon). This may have made you look at the wrong line. Commented Jul 25, 2024 at 8:21
  • 2
    Note that stack trace claims the NPE is being thrown from here inside String::length. And the only way for an NPE to be thrown on that line is for the internal char[] of String to be null. I don't know how that can happen. Commented Jul 25, 2024 at 8:33
  • 4
    My point is mostly that the snippet of AbstractStringBuilder is misleading. The problem isn't in that class's append method--it's in the String::length method. More specifically, the problem is that somehow a String is being created with its internal value field set to null. But as far as I know that's not possible (except maybe through instrumentation/reflection). You will likely have to provide a minimal reproducible example (including exact Java version and vendor information) if you want help. Commented Jul 25, 2024 at 8:44
  • 3
    It sounds like you're using reflection somewhere in your code, or perhaps a third-party library that uses reflection, and is changing the value of the array inside the string. Commented Jul 25, 2024 at 8:47

1 Answer 1

3

I was able to reproduce this error in a pretty convoluted way, which I doubt could happen by mistake. The String class has a package-protected constructor that takes a char[] and a boolean (that isn't actually used). This constructor is meant for internal use, and just naively stores the char[] without performing any validation on it.

You can use reflection to invoke it, and produce the described NullPointerExcpetion:

// Use reflection to invoke "new String((char[]) null, true)";
Constructor<String> ctor =
    String.class.getDeclaredConstructor(char[].class, boolean.class);
ctor.setAccessible(true);
String s = ctor.newInstance(null, true);

StringBuilder sb = new StringBuilder();
sb.append(s); // Null pointer exception when calling String.length
Sign up to request clarification or add additional context in comments.

2 Comments

then again, this is fairly specific and elaborate, hardly something the OP would've done "by accident" :)
Perhaps it was done by a buggy version of, for example, a mocking framework, an AOP framework, or similar.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.