Skip to content

Commit 015908e

Browse files
committed
GH-974, GH-976: remove class references
1 parent b7b966e commit 015908e

1 file changed

Lines changed: 29 additions & 44 deletions

File tree

protobuf-maven-plugin/src/main/java/io/github/ascopes/protobufmavenplugin/plexus/ImmutablesDataPlexusConverter.java

Lines changed: 29 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -17,11 +17,9 @@
1717

1818
import java.lang.reflect.ParameterizedType;
1919
import java.lang.reflect.Type;
20-
import java.util.Collections;
2120
import java.util.Map;
2221
import java.util.NoSuchElementException;
2322
import java.util.Optional;
24-
import java.util.WeakHashMap;
2523
import javax.inject.Named;
2624
import javax.inject.Singleton;
2725
import org.codehaus.plexus.component.configurator.ComponentConfigurationException;
@@ -42,19 +40,15 @@
4240
* <strong>and</strong> {@link org.immutables.datatype.Data}, otherwise deserialization will fail at
4341
* runtime.
4442
*
43+
* <p>This will not store any references to the datatypes, to allow for sharing across classloaders
44+
* safely (see GH-974 and GH-976).
45+
*
4546
* @author Ashley Scopes
4647
* @since TBC
4748
*/
4849
@Named
4950
@Singleton
5051
final class ImmutablesDataPlexusConverter extends AbstractBasicConverter {
51-
private final Map<Class<Object>, Datatype<Object>> knownDatatypes;
52-
53-
ImmutablesDataPlexusConverter() {
54-
// Weak hashmap keys will be deregistered upon classloader destruction safely.
55-
knownDatatypes = Collections.synchronizedMap(new WeakHashMap<>());
56-
}
57-
5852
@Override
5953
public boolean canConvert(Class<?> cls) {
6054
return datatypeFor(cls).isPresent();
@@ -81,6 +75,32 @@ public Object fromConfiguration(
8175
return builder.build();
8276
}
8377

78+
private Optional<Datatype<Object>> datatypeFor(Class<?> cls) {
79+
if (cls.isPrimitive() || cls.getClassLoader() == null) {
80+
return Optional.empty();
81+
}
82+
83+
var loader = cls.getClassLoader();
84+
var outerClsName = cls.getPackageName() + ".Datatypes_" + cls.getSimpleName();
85+
86+
try {
87+
var outerCls = loader.loadClass(outerClsName);
88+
var method = outerCls.getMethod("_" + cls.getSimpleName());
89+
90+
@SuppressWarnings("unchecked")
91+
var result = (Datatype<Object>) method.invoke(null);
92+
93+
return Optional.of(result);
94+
} catch (ClassNotFoundException ex) {
95+
return Optional.empty();
96+
} catch (ReflectiveOperationException ex) {
97+
throw new IllegalStateException(
98+
"Failed to find datatype for " + cls.getName() + ": " + ex,
99+
ex
100+
);
101+
}
102+
}
103+
84104
private void consumeChild(
85105
Datatype.Builder<Object> builder,
86106
PlexusConfiguration child,
@@ -134,41 +154,6 @@ private void consumeChild(
134154
}
135155
}
136156

137-
private Optional<Datatype<Object>> datatypeFor(Class<?> cls) {
138-
if (cls.isPrimitive() || cls.getClassLoader() == null) {
139-
return Optional.empty();
140-
}
141-
142-
// Horrible generic voodoo that probably is not safe, but the APIs have conflicting types
143-
// and the compiler is not smart enough to help us.
144-
@SuppressWarnings("unchecked")
145-
var castCls = (Class<Object>) cls;
146-
147-
var datatype = knownDatatypes.computeIfAbsent(castCls, ignored -> {
148-
var loader = cls.getClassLoader();
149-
var outerClsName = cls.getPackageName() + ".Datatypes_" + cls.getSimpleName();
150-
151-
try {
152-
var outerCls = loader.loadClass(outerClsName);
153-
var method = outerCls.getMethod("_" + cls.getSimpleName());
154-
155-
@SuppressWarnings("unchecked")
156-
var result = (Datatype<Object>) method.invoke(null);
157-
158-
return result;
159-
} catch (ClassNotFoundException ex) {
160-
return null;
161-
} catch (ReflectiveOperationException ex) {
162-
throw new IllegalStateException(
163-
"Failed to find datatype for " + cls.getName() + ": " + ex,
164-
ex
165-
);
166-
}
167-
});
168-
169-
return Optional.ofNullable(datatype);
170-
}
171-
172157
private static Class<?> rawTypeOf(Type type) {
173158
return type instanceof ParameterizedType parameterizedType
174159
? rawTypeOf(parameterizedType.getRawType())

0 commit comments

Comments
 (0)