File: remove-boolean-string-constructor.patch

package info (click to toggle)
openhft-chronicle-core 2.17.5-v1.1.8-2
  • links: PTS, VCS
  • area: main
  • in suites: bookworm, bullseye, buster
  • size: 532 kB
  • sloc: java: 2,589; xml: 230; makefile: 4
file content (82 lines) | stat: -rw-r--r-- 3,100 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
Subject: Update String access in StringUtils
Date: Thu, 28 Feb 2019 13:55:04 +0100
From: Andrej Shadura <andrewsh@debian.org>

See https://stackoverflow.com/questions/52620885/string-to-object-conversion-not-working-in-java-11:

> The message “class [B cannot be cast to class [C” indicates that
> the method is trying to cast a byte[] array to a char[] array. Since
> the code location also has a name like FastStringUtils.toCharArray,
> I can guess what happens here.
> 
> This class seems to hack into the java.lang.String class and read its
> value field in a questionable attempt of performance improvement. Since
> Java 9, this internal array is a byte[] array instead of a char[] array,
> which makes this hack fail at runtime.

Initially based on:

commit a8af29f932d73d8d1c6e44e49b68f9bb44905685
Author: Peter Lawrey <peter.lawrey@higherfrequencytrading.com>
Date:   Wed Mar 2 14:00:44 2016 +0000

    Tuning FIX to minimise garbage.

--- a/src/main/java/net/openhft/chronicle/core/util/StringUtils.java
+++ b/src/main/java/net/openhft/chronicle/core/util/StringUtils.java
@@ -19,7 +19,6 @@
 import net.openhft.chronicle.core.annotation.ForceInline;
 import org.jetbrains.annotations.NotNull;
 
-import java.lang.reflect.Constructor;
 import java.lang.reflect.Field;
 
 import static java.lang.Character.toLowerCase;
@@ -30,14 +29,11 @@
 public enum StringUtils {
     ;
 
-    private static final Constructor<String> STRING_CONSTRUCTOR;
     private static final Field S_VALUE, SB_VALUE, SB_COUNT;
     private static final long MAX_VALUE_DIVIDE_10 = Long.MAX_VALUE / 10;
 
     static {
         try {
-            STRING_CONSTRUCTOR = String.class.getDeclaredConstructor(char[].class, boolean.class);
-            STRING_CONSTRUCTOR.setAccessible(true);
             S_VALUE = String.class.getDeclaredField("value");
             S_VALUE.setAccessible(true);
             SB_VALUE = Class.forName("java.lang.AbstractStringBuilder").getDeclaredField("value");
@@ -93,6 +89,10 @@
     public static char[] extractChars(StringBuilder sb) {
         try {
             return (char[]) SB_VALUE.get(sb);
+        } catch (ClassCastException e) {
+            final char[] data = new char[sb.length()];
+            sb.getChars(0, sb.length(), data, 0);
+            return data;
         } catch (IllegalAccessException | IllegalArgumentException e) {
             throw new AssertionError(e);
         }
@@ -101,6 +101,8 @@
     public static char[] extractChars(String s) {
         try {
             return (char[]) S_VALUE.get(s);
+        } catch (ClassCastException e) {
+            return s.toCharArray();
         } catch (IllegalAccessException | IllegalArgumentException e) {
             throw new AssertionError(e);
         }
@@ -115,11 +117,7 @@
     }
 
     public static String newString(char[] chars) {
-        try {
-            return STRING_CONSTRUCTOR.newInstance(chars, true);
-        } catch (Exception e) {
-            throw new AssertionError(e);
-        }
+        return new String(chars);
     }
 
     public static String firstLowerCase(String str) {