Skip to content

Commit 356a686

Browse files
authored
Merge pull request #1826 from ajsutton/service-loader-race
Fix ArrayIndexOutOfBoundsException when multiple threads use FunctionEncoder
2 parents 678efa8 + c8930a5 commit 356a686

File tree

1 file changed

+15
-21
lines changed

1 file changed

+15
-21
lines changed

abi/src/main/java/org/web3j/abi/FunctionEncoder.java

Lines changed: 15 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -37,30 +37,36 @@
3737
*/
3838
public abstract class FunctionEncoder {
3939

40-
private static FunctionEncoder DEFAULT_ENCODER;
40+
private static final FunctionEncoder FUNCTION_ENCODER;
4141

42-
private static final ServiceLoader<FunctionEncoderProvider> loader =
43-
ServiceLoader.load(FunctionEncoderProvider.class);
42+
static {
43+
ServiceLoader<FunctionEncoderProvider> loader =
44+
ServiceLoader.load(FunctionEncoderProvider.class);
45+
final Iterator<FunctionEncoderProvider> iterator = loader.iterator();
46+
47+
FUNCTION_ENCODER =
48+
iterator.hasNext() ? iterator.next().get() : new DefaultFunctionEncoder();
49+
}
4450

4551
public static String encode(final Function function) {
46-
return encoder().encodeFunction(function);
52+
return FUNCTION_ENCODER.encodeFunction(function);
4753
}
4854

4955
/** Encode function when we know function method Id / Selector. */
5056
public static String encode(final String methodId, final List<Type> parameters) {
51-
return encoder().encodeWithSelector(methodId, parameters);
57+
return FUNCTION_ENCODER.encodeWithSelector(methodId, parameters);
5258
}
5359

5460
public static String encodeConstructor(final List<Type> parameters) {
55-
return encoder().encodeParameters(parameters);
61+
return FUNCTION_ENCODER.encodeParameters(parameters);
5662
}
5763

5864
public static String encodeConstructorPacked(final List<Type> parameters) {
59-
return encoder().encodePackedParameters(parameters);
65+
return FUNCTION_ENCODER.encodePackedParameters(parameters);
6066
}
6167

6268
public static Function makeFunction(
63-
String fnname,
69+
String fnName,
6470
List<String> solidityInputTypes,
6571
List<Object> arguments,
6672
List<String> solidityOutputTypes)
@@ -75,7 +81,7 @@ public static Function makeFunction(
7581
for (String st : solidityOutputTypes) {
7682
encodedOutput.add(makeTypeReference(st));
7783
}
78-
return new Function(fnname, encodedInput, encodedOutput);
84+
return new Function(fnName, encodedInput, encodedOutput);
7985
}
8086

8187
protected abstract String encodeFunction(Function function);
@@ -106,16 +112,4 @@ protected static String buildMethodId(final String methodSignature) {
106112
final byte[] hash = Hash.sha3(input);
107113
return Numeric.toHexString(hash).substring(0, 10);
108114
}
109-
110-
private static FunctionEncoder encoder() {
111-
final Iterator<FunctionEncoderProvider> iterator = loader.iterator();
112-
return iterator.hasNext() ? iterator.next().get() : defaultEncoder();
113-
}
114-
115-
private static FunctionEncoder defaultEncoder() {
116-
if (DEFAULT_ENCODER == null) {
117-
DEFAULT_ENCODER = new DefaultFunctionEncoder();
118-
}
119-
return DEFAULT_ENCODER;
120-
}
121115
}

0 commit comments

Comments
 (0)