Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit f1fde23

Browse filesBrowse files
authored
Ensured *Builder instances are no longer created with reflection (#989)
Ensured *Builder instances are no longer created with reflection using `Classes.newInstance`. Instead, `Classes.newInstance` is used to create static/thread-safe Supplier singletons when the api module is loaded, and those singletons will directly instantiate *Builder instances at runtime using the `new` keyword`. Resolves #988.
1 parent 0b34b21 commit f1fde23
Copy full SHA for f1fde23
Expand file treeCollapse file tree

13 files changed

+151
-19
lines changed

‎CHANGELOG.md

Copy file name to clipboardExpand all lines: CHANGELOG.md
+12Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,17 @@
11
## Release Notes
22

3+
### 0.12.7
4+
5+
This patch release:
6+
7+
* Improves performance slightly by ensuring all `jjwt-api` utility methods that create `*Builder` instances (`Jwts.builder()`, `Jwts.parserBuilder()`, `Jwks.builder()`, etc) no longer use reflection.
8+
9+
Instead,`static` factories are created via reflection only once during initial `jjwt-api` classloading, and then `*Builder`s are created via standard instantiation using the `new` operator thereafter. This also benefits certain environments that may not have ideal `ClassLoader` implementations (e.g. Tomcat in some cases).
10+
11+
**NOTE: because this changes which classes are loaded via reflection, any environments that must explicitly reference reflective class names (e.g. GraalVM applications) will need to be updated to reflect the new factory class names**.
12+
13+
See [Issue 988](https://github.com/jwtk/jjwt/issues/988).
14+
315
### 0.12.6
416

517
This patch release:

‎api/src/main/java/io/jsonwebtoken/Jwts.java

Copy file name to clipboardExpand all lines: api/src/main/java/io/jsonwebtoken/Jwts.java
+21-4Lines changed: 21 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
import io.jsonwebtoken.lang.Builder;
2020
import io.jsonwebtoken.lang.Classes;
2121
import io.jsonwebtoken.lang.Registry;
22+
import io.jsonwebtoken.lang.Supplier;
2223
import io.jsonwebtoken.security.AeadAlgorithm;
2324
import io.jsonwebtoken.security.KeyAlgorithm;
2425
import io.jsonwebtoken.security.KeyPairBuilderSupplier;
@@ -1001,6 +1002,22 @@ private ZIP() {
10011002
}
10021003
}
10031004

1005+
// @since JJWT_RELEASE_VERSION
1006+
private static final Supplier<JwtBuilder> JWT_BUILDER_SUPPLIER =
1007+
Classes.newInstance("io.jsonwebtoken.impl.DefaultJwtBuilder$Supplier");
1008+
1009+
// @since JJWT_RELEASE_VERSION
1010+
private static final Supplier<JwtParserBuilder> JWT_PARSER_BUILDER_SUPPLIER =
1011+
Classes.newInstance("io.jsonwebtoken.impl.DefaultJwtParserBuilder$Supplier");
1012+
1013+
// @since JJWT_RELEASE_VERSION
1014+
private static final Supplier<HeaderBuilder> HEADER_BUILDER_SUPPLIER =
1015+
Classes.newInstance("io.jsonwebtoken.impl.DefaultJwtHeaderBuilder$Supplier");
1016+
1017+
// @since JJWT_RELEASE_VERSION
1018+
private static final Supplier<ClaimsBuilder> CLAIMS_BUILDER_SUPPLIER =
1019+
Classes.newInstance("io.jsonwebtoken.impl.DefaultClaimsBuilder$Supplier");
1020+
10041021
/**
10051022
* A {@link Builder} that dynamically determines the type of {@link Header} to create based on builder state.
10061023
*
@@ -1018,7 +1035,7 @@ public interface HeaderBuilder extends JweHeaderMutator<HeaderBuilder>, X509Buil
10181035
* @since 0.12.0
10191036
*/
10201037
public static HeaderBuilder header() {
1021-
return Classes.newInstance("io.jsonwebtoken.impl.DefaultJwtHeaderBuilder");
1038+
return HEADER_BUILDER_SUPPLIER.get();
10221039
}
10231040

10241041
/**
@@ -1029,7 +1046,7 @@ public static HeaderBuilder header() {
10291046
* the JWT payload.
10301047
*/
10311048
public static ClaimsBuilder claims() {
1032-
return Classes.newInstance("io.jsonwebtoken.impl.DefaultClaimsBuilder");
1049+
return CLAIMS_BUILDER_SUPPLIER.get();
10331050
}
10341051

10351052
/**
@@ -1057,7 +1074,7 @@ public static Claims claims(Map<String, Object> claims) {
10571074
* strings.
10581075
*/
10591076
public static JwtBuilder builder() {
1060-
return Classes.newInstance("io.jsonwebtoken.impl.DefaultJwtBuilder");
1077+
return JWT_BUILDER_SUPPLIER.get();
10611078
}
10621079

10631080
/**
@@ -1066,7 +1083,7 @@ public static JwtBuilder builder() {
10661083
* @return a new {@link JwtParser} instance that can be configured create an immutable/thread-safe {@link JwtParser}.
10671084
*/
10681085
public static JwtParserBuilder parser() {
1069-
return Classes.newInstance("io.jsonwebtoken.impl.DefaultJwtParserBuilder");
1086+
return JWT_PARSER_BUILDER_SUPPLIER.get();
10701087
}
10711088

10721089
/**

‎api/src/main/java/io/jsonwebtoken/security/Jwks.java

Copy file name to clipboardExpand all lines: api/src/main/java/io/jsonwebtoken/security/Jwks.java
+29-14Lines changed: 29 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
import io.jsonwebtoken.io.Parser;
2020
import io.jsonwebtoken.lang.Classes;
2121
import io.jsonwebtoken.lang.Registry;
22+
import io.jsonwebtoken.lang.Supplier;
2223

2324
/**
2425
* Utility methods for creating
@@ -42,18 +43,30 @@ private Jwks() {
4243
} //prevent instantiation
4344

4445
private static final String JWKS_BRIDGE_FQCN = "io.jsonwebtoken.impl.security.JwksBridge";
45-
private static final String BUILDER_FQCN = "io.jsonwebtoken.impl.security.DefaultDynamicJwkBuilder";
46-
private static final String PARSER_BUILDER_FQCN = "io.jsonwebtoken.impl.security.DefaultJwkParserBuilder";
47-
private static final String SET_BUILDER_FQCN = "io.jsonwebtoken.impl.security.DefaultJwkSetBuilder";
48-
private static final String SET_PARSER_BUILDER_FQCN = "io.jsonwebtoken.impl.security.DefaultJwkSetParserBuilder";
46+
47+
// @since JJWT_RELEASE_VERSION per https://github.com/jwtk/jjwt/issues/988
48+
private static final Supplier<DynamicJwkBuilder<?, ?>> BUILDER_SUPPLIER =
49+
Classes.newInstance("io.jsonwebtoken.impl.security.DefaultDynamicJwkBuilder$Supplier");
50+
51+
// @since JJWT_RELEASE_VERSION per https://github.com/jwtk/jjwt/issues/988
52+
private static final Supplier<JwkParserBuilder> PARSER_BUILDER_SUPPLIER =
53+
Classes.newInstance("io.jsonwebtoken.impl.security.DefaultJwkParserBuilder$Supplier");
54+
55+
// @since JJWT_RELEASE_VERSION per https://github.com/jwtk/jjwt/issues/988
56+
private static final Supplier<JwkSetBuilder> SET_BUILDER_SUPPLIER =
57+
Classes.newInstance("io.jsonwebtoken.impl.security.DefaultJwkSetBuilder$Supplier");
58+
59+
// @since JJWT_RELEASE_VERSION per https://github.com/jwtk/jjwt/issues/988
60+
private static final Supplier<JwkSetParserBuilder> SET_PARSER_BUILDER_SUPPLIER =
61+
Classes.newInstance("io.jsonwebtoken.impl.security.DefaultJwkSetParserBuilder$Supplier");
4962

5063
/**
5164
* Return a new JWK builder instance, allowing for type-safe JWK builder coercion based on a specified key or key pair.
5265
*
5366
* @return a new JWK builder instance, allowing for type-safe JWK builder coercion based on a specified key or key pair.
5467
*/
5568
public static DynamicJwkBuilder<?, ?> builder() {
56-
return Classes.newInstance(BUILDER_FQCN);
69+
return BUILDER_SUPPLIER.get();
5770
}
5871

5972
/**
@@ -69,7 +82,7 @@ private Jwks() {
6982
* @return a new builder used to create {@link Parser}s that parse JSON into {@link Jwk} instances.
7083
*/
7184
public static JwkParserBuilder parser() {
72-
return Classes.newInstance(PARSER_BUILDER_FQCN);
85+
return PARSER_BUILDER_SUPPLIER.get();
7386
}
7487

7588
/**
@@ -87,7 +100,7 @@ public static JwkParserBuilder parser() {
87100
* @return a new builder used to create {@link JwkSet}s
88101
*/
89102
public static JwkSetBuilder set() {
90-
return Classes.newInstance(SET_BUILDER_FQCN);
103+
return SET_BUILDER_SUPPLIER.get();
91104
}
92105

93106
/**
@@ -103,7 +116,7 @@ public static JwkSetBuilder set() {
103116
* @return a new builder used to create {@link Parser}s that parse JSON into {@link JwkSet} instances.
104117
*/
105118
public static JwkSetParserBuilder setParser() {
106-
return Classes.newInstance(SET_PARSER_BUILDER_FQCN);
119+
return SET_PARSER_BUILDER_SUPPLIER.get();
107120
}
108121

109122
/**
@@ -370,19 +383,21 @@ public static final class OP {
370383
private static final String IMPL_CLASSNAME = "io.jsonwebtoken.impl.security.StandardKeyOperations";
371384
private static final Registry<String, KeyOperation> REGISTRY = Classes.newInstance(IMPL_CLASSNAME);
372385

373-
private static final String BUILDER_CLASSNAME = "io.jsonwebtoken.impl.security.DefaultKeyOperationBuilder";
374-
386+
// @since JJWT_RELEASE_VERSION per https://github.com/jwtk/jjwt/issues/988
387+
private static final Supplier<KeyOperationBuilder> BUILDER_SUPPLIER =
388+
Classes.newInstance("io.jsonwebtoken.impl.security.DefaultKeyOperationBuilder$Supplier");
375389

376-
private static final String POLICY_BUILDER_CLASSNAME =
377-
"io.jsonwebtoken.impl.security.DefaultKeyOperationPolicyBuilder";
390+
// @since JJWT_RELEASE_VERSION per https://github.com/jwtk/jjwt/issues/988
391+
private static final Supplier<KeyOperationPolicyBuilder> POLICY_BUILDER_SUPPLIER =
392+
Classes.newInstance("io.jsonwebtoken.impl.security.DefaultKeyOperationPolicyBuilder$Supplier");
378393

379394
/**
380395
* Creates a new {@link KeyOperationBuilder} for creating custom {@link KeyOperation} instances.
381396
*
382397
* @return a new {@link KeyOperationBuilder} for creating custom {@link KeyOperation} instances.
383398
*/
384399
public static KeyOperationBuilder builder() {
385-
return Classes.newInstance(BUILDER_CLASSNAME);
400+
return BUILDER_SUPPLIER.get();
386401
}
387402

388403
/**
@@ -391,7 +406,7 @@ public static KeyOperationBuilder builder() {
391406
* @return a new {@link KeyOperationPolicyBuilder} for creating custom {@link KeyOperationPolicy} instances.
392407
*/
393408
public static KeyOperationPolicyBuilder policy() {
394-
return Classes.newInstance(POLICY_BUILDER_CLASSNAME);
409+
return POLICY_BUILDER_SUPPLIER.get();
395410
}
396411

397412
/**

‎impl/src/main/java/io/jsonwebtoken/impl/DefaultClaimsBuilder.java

Copy file name to clipboardExpand all lines: impl/src/main/java/io/jsonwebtoken/impl/DefaultClaimsBuilder.java
+9-1Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,6 @@
2121
/**
2222
* @since 0.12.0
2323
*/
24-
@SuppressWarnings("unused") // used via reflection via Jwts.claims()
2524
public final class DefaultClaimsBuilder extends DelegatingClaimsMutator<ClaimsBuilder>
2625
implements ClaimsBuilder {
2726

@@ -34,4 +33,13 @@ public Claims build() {
3433
// ensure a new instance is returned so that the builder may be re-used:
3534
return new DefaultClaims(this.DELEGATE);
3635
}
36+
37+
// @since JJWT_RELEASE_VERSION per https://github.com/jwtk/jjwt/issues/988
38+
@SuppressWarnings("unused") // used via reflection in the api module's Jwts class.
39+
public static final class Supplier implements io.jsonwebtoken.lang.Supplier<ClaimsBuilder> {
40+
@Override
41+
public ClaimsBuilder get() {
42+
return new DefaultClaimsBuilder();
43+
}
44+
}
3745
}

‎impl/src/main/java/io/jsonwebtoken/impl/DefaultJwtBuilder.java

Copy file name to clipboardExpand all lines: impl/src/main/java/io/jsonwebtoken/impl/DefaultJwtBuilder.java
+8Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -818,4 +818,12 @@ private InputStream toInputStream(final String name, Payload payload) {
818818
}
819819
}
820820

821+
// @since JJWT_RELEASE_VERSION per https://github.com/jwtk/jjwt/issues/988
822+
@SuppressWarnings("unused") // used via reflection in the api module's Jwts class.
823+
public static final class Supplier implements io.jsonwebtoken.lang.Supplier<JwtBuilder> {
824+
@Override
825+
public JwtBuilder get() {
826+
return new DefaultJwtBuilder();
827+
}
828+
}
821829
}

‎impl/src/main/java/io/jsonwebtoken/impl/DefaultJwtHeaderBuilder.java

Copy file name to clipboardExpand all lines: impl/src/main/java/io/jsonwebtoken/impl/DefaultJwtHeaderBuilder.java
+9Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,4 +84,13 @@ public Header build() {
8484
return new DefaultHeader(sanitizeCrit(m, false));
8585
}
8686
}
87+
88+
// @since JJWT_RELEASE_VERSION per https://github.com/jwtk/jjwt/issues/988
89+
@SuppressWarnings("unused") // used via reflection in the api module's Jwts class.
90+
public static final class Supplier implements io.jsonwebtoken.lang.Supplier<Jwts.HeaderBuilder> {
91+
@Override
92+
public Jwts.HeaderBuilder get() {
93+
return new DefaultJwtHeaderBuilder();
94+
}
95+
}
8796
}

‎impl/src/main/java/io/jsonwebtoken/impl/DefaultJwtParserBuilder.java

Copy file name to clipboardExpand all lines: impl/src/main/java/io/jsonwebtoken/impl/DefaultJwtParserBuilder.java
+9Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -426,4 +426,13 @@ public JwtParser build() {
426426
encAlgs
427427
);
428428
}
429+
430+
// @since JJWT_RELEASE_VERSION per https://github.com/jwtk/jjwt/issues/988
431+
@SuppressWarnings("unused") // used via reflection in the api module's Jwts class.
432+
public static final class Supplier implements io.jsonwebtoken.lang.Supplier<JwtParserBuilder> {
433+
@Override
434+
public JwtParserBuilder get() {
435+
return new DefaultJwtParserBuilder();
436+
}
437+
}
429438
}

‎impl/src/main/java/io/jsonwebtoken/impl/security/DefaultDynamicJwkBuilder.java

Copy file name to clipboardExpand all lines: impl/src/main/java/io/jsonwebtoken/impl/security/DefaultDynamicJwkBuilder.java
+9Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -209,4 +209,13 @@ public J build() {
209209
}
210210
return super.build();
211211
}
212+
213+
// @since JJWT_RELEASE_VERSION per https://github.com/jwtk/jjwt/issues/988
214+
@SuppressWarnings("unused") // used via reflection in the api module's Jwks class.
215+
public static final class Supplier<K extends Key, J extends Jwk<K>> implements io.jsonwebtoken.lang.Supplier<DynamicJwkBuilder<K, J>> {
216+
@Override
217+
public DynamicJwkBuilder<K, J> get() {
218+
return new DefaultDynamicJwkBuilder<>();
219+
}
220+
}
212221
}

‎impl/src/main/java/io/jsonwebtoken/impl/security/DefaultJwkParserBuilder.java

Copy file name to clipboardExpand all lines: impl/src/main/java/io/jsonwebtoken/impl/security/DefaultJwkParserBuilder.java
+9Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,4 +29,13 @@ public Parser<Jwk<?>> doBuild() {
2929
JwkConverter<Jwk<?>> converter = new JwkConverter<>(supplier);
3030
return new ConvertingParser<>(deserializer, converter);
3131
}
32+
33+
// @since JJWT_RELEASE_VERSION per https://github.com/jwtk/jjwt/issues/988
34+
@SuppressWarnings("unused") // used via reflection in the api module's Jwks class.
35+
public static final class Supplier implements io.jsonwebtoken.lang.Supplier<JwkParserBuilder> {
36+
@Override
37+
public JwkParserBuilder get() {
38+
return new DefaultJwkParserBuilder();
39+
}
40+
}
3241
}

‎impl/src/main/java/io/jsonwebtoken/impl/security/DefaultJwkSetBuilder.java

Copy file name to clipboardExpand all lines: impl/src/main/java/io/jsonwebtoken/impl/security/DefaultJwkSetBuilder.java
+9Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -129,4 +129,13 @@ public JwkSetBuilder keys(Collection<Jwk<?>> c) {
129129
public JwkSet build() {
130130
return converter.applyFrom(this.map);
131131
}
132+
133+
// @since JJWT_RELEASE_VERSION per https://github.com/jwtk/jjwt/issues/988
134+
@SuppressWarnings("unused") // used via reflection in the api module's Jwks class.
135+
public static final class Supplier implements io.jsonwebtoken.lang.Supplier<JwkSetBuilder> {
136+
@Override
137+
public JwkSetBuilder get() {
138+
return new DefaultJwkSetBuilder();
139+
}
140+
}
132141
}

‎impl/src/main/java/io/jsonwebtoken/impl/security/DefaultJwkSetParserBuilder.java

Copy file name to clipboardExpand all lines: impl/src/main/java/io/jsonwebtoken/impl/security/DefaultJwkSetParserBuilder.java
+9Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,4 +38,13 @@ public Parser<JwkSet> doBuild() {
3838
JwkSetConverter converter = new JwkSetConverter(supplier, this.ignoreUnsupported);
3939
return new ConvertingParser<>(deserializer, converter);
4040
}
41+
42+
// @since JJWT_RELEASE_VERSION per https://github.com/jwtk/jjwt/issues/988
43+
@SuppressWarnings("unused") // used via reflection in the api module's Jwks class.
44+
public static final class Supplier implements io.jsonwebtoken.lang.Supplier<JwkSetParserBuilder> {
45+
@Override
46+
public JwkSetParserBuilder get() {
47+
return new DefaultJwkSetParserBuilder();
48+
}
49+
}
4150
}

‎impl/src/main/java/io/jsonwebtoken/impl/security/DefaultKeyOperationBuilder.java

Copy file name to clipboardExpand all lines: impl/src/main/java/io/jsonwebtoken/impl/security/DefaultKeyOperationBuilder.java
+9Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,4 +52,13 @@ public KeyOperationBuilder related(String related) {
5252
public KeyOperation build() {
5353
return new DefaultKeyOperation(this.id, this.description, this.related);
5454
}
55+
56+
// @since JJWT_RELEASE_VERSION per https://github.com/jwtk/jjwt/issues/988
57+
@SuppressWarnings("unused") // used via reflection in the api module's Jwks class.
58+
public static final class Supplier implements io.jsonwebtoken.lang.Supplier<KeyOperationBuilder> {
59+
@Override
60+
public KeyOperationBuilder get() {
61+
return new DefaultKeyOperationBuilder();
62+
}
63+
}
5564
}

‎impl/src/main/java/io/jsonwebtoken/impl/security/DefaultKeyOperationPolicyBuilder.java

Copy file name to clipboardExpand all lines: impl/src/main/java/io/jsonwebtoken/impl/security/DefaultKeyOperationPolicyBuilder.java
+9Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,4 +41,13 @@ public KeyOperationPolicyBuilder unrelated() {
4141
public KeyOperationPolicy build() {
4242
return new DefaultKeyOperationPolicy(Collections.immutable(getCollection()), this.unrelated);
4343
}
44+
45+
// @since JJWT_RELEASE_VERSION per https://github.com/jwtk/jjwt/issues/988
46+
@SuppressWarnings("unused") // used via reflection in the api module's Jwks class.
47+
public static final class Supplier implements io.jsonwebtoken.lang.Supplier<KeyOperationPolicyBuilder> {
48+
@Override
49+
public KeyOperationPolicyBuilder get() {
50+
return new DefaultKeyOperationPolicyBuilder();
51+
}
52+
}
4453
}

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.