[MNG-8220] Fix loading DI-powered beans from extensions (#1683)

This commit is contained in:
Guillaume Nodet 2024-08-29 17:32:53 +02:00 committed by GitHub
parent acec540547
commit 40fe1dc167
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
5 changed files with 65 additions and 42 deletions

View File

@ -55,13 +55,16 @@ import org.codehaus.plexus.PlexusContainer;
import org.codehaus.plexus.component.repository.exception.ComponentLookupException;
@Named
class SisuDiBridgeModule extends AbstractModule {
public class SisuDiBridgeModule extends AbstractModule {
InjectorImpl injector;
final Set<String> loaded = new HashSet<>();
@Override
protected void configure() {
Provider<PlexusContainer> containerProvider = getProvider(PlexusContainer.class);
InjectorImpl injector = new InjectorImpl() {
injector = new InjectorImpl() {
@Override
public <Q> Supplier<Q> getCompiledBinding(Key<Q> key) {
Set<Binding<Q>> res = getBindings(key);
@ -142,38 +145,12 @@ class SisuDiBridgeModule extends AbstractModule {
});
injector.bindInstance(Injector.class, injector);
bind(Injector.class).toInstance(injector);
bind(SisuDiBridgeModule.class).toInstance(this);
ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
if (classLoader == null) {
classLoader = getClass().getClassLoader();
}
try {
for (Iterator<URL> it = classLoader
.getResources("META-INF/maven/org.apache.maven.api.di.Inject")
.asIterator();
it.hasNext(); ) {
URL url = it.next();
List<String> lines;
try (InputStream is = url.openStream();
BufferedReader reader = new BufferedReader(new InputStreamReader(is, StandardCharsets.UTF_8))) {
lines = reader.lines()
.map(String::trim)
.filter(s -> !s.isEmpty() && !s.startsWith("#"))
.toList();
}
for (String className : lines) {
try {
Class<?> clazz = classLoader.loadClass(className);
injector.bindImplicit(clazz);
} catch (ClassNotFoundException e) {
// ignore
e.printStackTrace();
}
}
}
} catch (IOException e) {
throw new MavenException(e);
}
loadFromClassLoader(classLoader);
injector.getBindings().keySet().stream()
.filter(k -> k.getQualifier() != null)
.sorted(Comparator.comparing(k -> k.getRawType().getName()))
@ -185,7 +162,7 @@ class SisuDiBridgeModule extends AbstractModule {
: (Class<Object>) (clazz.getInterfaces().length > 0 ? clazz.getInterfaces()[0] : clazz));
if (itf != null) {
AnnotatedBindingBuilder<Object> binder = bind(itf);
if (key.getQualifier() instanceof String s) {
if (key.getQualifier() instanceof String s && !s.isEmpty()) {
binder.annotatedWith(Names.named(s));
} else if (key.getQualifier() instanceof Annotation a) {
binder.annotatedWith(a);
@ -194,4 +171,37 @@ class SisuDiBridgeModule extends AbstractModule {
}
});
}
public void loadFromClassLoader(ClassLoader classLoader) {
try {
for (Iterator<URL> it = classLoader
.getResources("META-INF/maven/org.apache.maven.api.di.Inject")
.asIterator();
it.hasNext(); ) {
URL url = it.next();
if (loaded.add(url.toExternalForm())) {
List<String> lines;
try (InputStream is = url.openStream();
BufferedReader reader =
new BufferedReader(new InputStreamReader(is, StandardCharsets.UTF_8))) {
lines = reader.lines()
.map(String::trim)
.filter(s -> !s.isEmpty() && !s.startsWith("#"))
.toList();
}
for (String className : lines) {
try {
Class<?> clazz = classLoader.loadClass(className);
injector.bindImplicit(clazz);
} catch (ClassNotFoundException e) {
// ignore
e.printStackTrace();
}
}
}
}
} catch (IOException e) {
throw new MavenException(e);
}
}
}

View File

@ -138,7 +138,8 @@ public class SessionScope implements Scope, org.apache.maven.di.Scope {
} else {
for (Annotation a : superType.getAnnotations()) {
Class<? extends Annotation> annotationType = a.annotationType();
if ("org.eclipse.sisu.Typed".equals(annotationType.getName())
if ("org.apache.maven.api.di.Typed".equals(annotationType.getName())
|| "org.eclipse.sisu.Typed".equals(annotationType.getName())
|| "javax.enterprise.inject.Typed".equals(annotationType.getName())
|| "jakarta.enterprise.inject.Typed".equals(annotationType.getName())) {
try {

View File

@ -128,8 +128,15 @@ public abstract class Key<T> {
* and prepended qualifier display string if this key has a qualifier.
*/
public String getDisplayString() {
return (qualifier != null ? Utils.getDisplayString(qualifier) + " " : "")
+ ReflectionUtils.getDisplayName(type);
return (qualifier != null ? getQualifierDisplayString() + " " : "") + ReflectionUtils.getDisplayName(type);
}
private String getQualifierDisplayString() {
if (qualifier instanceof String s) {
return s.isEmpty() ? "@Named" : "@Named(\"" + s + "\")";
}
String s = Utils.getDisplayString(qualifier);
return s;
}
@Override
@ -155,6 +162,6 @@ public abstract class Key<T> {
@Override
public String toString() {
return (qualifier != null ? qualifier + " " : "") + type.getTypeName();
return getDisplayString();
}
}

View File

@ -137,15 +137,18 @@ public class InjectorImpl implements Injector {
current.add(key);
throw new DIException("Circular references: " + current);
}
doBindImplicit(key, binding);
Class<?> cls = key.getRawType().getSuperclass();
while (cls != Object.class && cls != null) {
key = Key.of(cls, key.getQualifier());
try {
doBindImplicit(key, binding);
cls = cls.getSuperclass();
Class<?> cls = key.getRawType().getSuperclass();
while (cls != Object.class && cls != null) {
key = Key.of(cls, key.getQualifier());
doBindImplicit(key, binding);
cls = cls.getSuperclass();
}
return this;
} finally {
current.remove(key);
}
current.remove(key);
return this;
}
protected <U> Injector bind(Key<U> key, Binding<U> b) {

View File

@ -95,6 +95,7 @@ import org.apache.maven.execution.scope.internal.MojoExecutionScope;
import org.apache.maven.execution.scope.internal.MojoExecutionScopeModule;
import org.apache.maven.extension.internal.CoreExports;
import org.apache.maven.extension.internal.CoreExtensionEntry;
import org.apache.maven.internal.impl.SisuDiBridgeModule;
import org.apache.maven.jline.JLineMessageBuilderFactory;
import org.apache.maven.jline.MessageUtils;
import org.apache.maven.lifecycle.LifecycleExecutionException;
@ -715,6 +716,7 @@ public class MavenCli {
new SessionScopeModule(container.lookup(SessionScope.class)),
new MojoExecutionScopeModule(container.lookup(MojoExecutionScope.class)),
new ExtensionConfigurationModule(extension, extensionSource));
container.lookup(SisuDiBridgeModule.class).loadFromClassLoader(extension.getClassRealm());
}
customizeContainer(container);