Skip to content

Commit 40fe1dc

Browse files
authored
[MNG-8220] Fix loading DI-powered beans from extensions (#1683)
1 parent acec540 commit 40fe1dc

File tree

5 files changed

+65
-42
lines changed

5 files changed

+65
-42
lines changed

maven-core/src/main/java/org/apache/maven/internal/impl/SisuDiBridgeModule.java

Lines changed: 41 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -55,13 +55,16 @@
5555
import org.codehaus.plexus.component.repository.exception.ComponentLookupException;
5656

5757
@Named
58-
class SisuDiBridgeModule extends AbstractModule {
58+
public class SisuDiBridgeModule extends AbstractModule {
59+
60+
InjectorImpl injector;
61+
final Set<String> loaded = new HashSet<>();
5962

6063
@Override
6164
protected void configure() {
6265
Provider<PlexusContainer> containerProvider = getProvider(PlexusContainer.class);
6366

64-
InjectorImpl injector = new InjectorImpl() {
67+
injector = new InjectorImpl() {
6568
@Override
6669
public <Q> Supplier<Q> getCompiledBinding(Key<Q> key) {
6770
Set<Binding<Q>> res = getBindings(key);
@@ -142,38 +145,12 @@ public <Q> Supplier<Q> getCompiledBinding(Key<Q> key) {
142145
});
143146
injector.bindInstance(Injector.class, injector);
144147
bind(Injector.class).toInstance(injector);
148+
bind(SisuDiBridgeModule.class).toInstance(this);
145149
ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
146150
if (classLoader == null) {
147151
classLoader = getClass().getClassLoader();
148152
}
149-
try {
150-
for (Iterator<URL> it = classLoader
151-
.getResources("META-INF/maven/org.apache.maven.api.di.Inject")
152-
.asIterator();
153-
it.hasNext(); ) {
154-
URL url = it.next();
155-
List<String> lines;
156-
try (InputStream is = url.openStream();
157-
BufferedReader reader = new BufferedReader(new InputStreamReader(is, StandardCharsets.UTF_8))) {
158-
lines = reader.lines()
159-
.map(String::trim)
160-
.filter(s -> !s.isEmpty() && !s.startsWith("#"))
161-
.toList();
162-
}
163-
for (String className : lines) {
164-
try {
165-
Class<?> clazz = classLoader.loadClass(className);
166-
injector.bindImplicit(clazz);
167-
} catch (ClassNotFoundException e) {
168-
// ignore
169-
e.printStackTrace();
170-
}
171-
}
172-
}
173-
174-
} catch (IOException e) {
175-
throw new MavenException(e);
176-
}
153+
loadFromClassLoader(classLoader);
177154
injector.getBindings().keySet().stream()
178155
.filter(k -> k.getQualifier() != null)
179156
.sorted(Comparator.comparing(k -> k.getRawType().getName()))
@@ -185,7 +162,7 @@ public <Q> Supplier<Q> getCompiledBinding(Key<Q> key) {
185162
: (Class<Object>) (clazz.getInterfaces().length > 0 ? clazz.getInterfaces()[0] : clazz));
186163
if (itf != null) {
187164
AnnotatedBindingBuilder<Object> binder = bind(itf);
188-
if (key.getQualifier() instanceof String s) {
165+
if (key.getQualifier() instanceof String s && !s.isEmpty()) {
189166
binder.annotatedWith(Names.named(s));
190167
} else if (key.getQualifier() instanceof Annotation a) {
191168
binder.annotatedWith(a);
@@ -194,4 +171,37 @@ public <Q> Supplier<Q> getCompiledBinding(Key<Q> key) {
194171
}
195172
});
196173
}
174+
175+
public void loadFromClassLoader(ClassLoader classLoader) {
176+
try {
177+
for (Iterator<URL> it = classLoader
178+
.getResources("META-INF/maven/org.apache.maven.api.di.Inject")
179+
.asIterator();
180+
it.hasNext(); ) {
181+
URL url = it.next();
182+
if (loaded.add(url.toExternalForm())) {
183+
List<String> lines;
184+
try (InputStream is = url.openStream();
185+
BufferedReader reader =
186+
new BufferedReader(new InputStreamReader(is, StandardCharsets.UTF_8))) {
187+
lines = reader.lines()
188+
.map(String::trim)
189+
.filter(s -> !s.isEmpty() && !s.startsWith("#"))
190+
.toList();
191+
}
192+
for (String className : lines) {
193+
try {
194+
Class<?> clazz = classLoader.loadClass(className);
195+
injector.bindImplicit(clazz);
196+
} catch (ClassNotFoundException e) {
197+
// ignore
198+
e.printStackTrace();
199+
}
200+
}
201+
}
202+
}
203+
} catch (IOException e) {
204+
throw new MavenException(e);
205+
}
206+
}
197207
}

maven-core/src/main/java/org/apache/maven/session/scope/internal/SessionScope.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -138,7 +138,8 @@ private Class<?>[] getInterfaces(Class<?> superType) {
138138
} else {
139139
for (Annotation a : superType.getAnnotations()) {
140140
Class<? extends Annotation> annotationType = a.annotationType();
141-
if ("org.eclipse.sisu.Typed".equals(annotationType.getName())
141+
if ("org.apache.maven.api.di.Typed".equals(annotationType.getName())
142+
|| "org.eclipse.sisu.Typed".equals(annotationType.getName())
142143
|| "javax.enterprise.inject.Typed".equals(annotationType.getName())
143144
|| "jakarta.enterprise.inject.Typed".equals(annotationType.getName())) {
144145
try {

maven-di/src/main/java/org/apache/maven/di/Key.java

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -128,8 +128,15 @@ public <U> Key<U> getTypeParameter(int index) {
128128
* and prepended qualifier display string if this key has a qualifier.
129129
*/
130130
public String getDisplayString() {
131-
return (qualifier != null ? Utils.getDisplayString(qualifier) + " " : "")
132-
+ ReflectionUtils.getDisplayName(type);
131+
return (qualifier != null ? getQualifierDisplayString() + " " : "") + ReflectionUtils.getDisplayName(type);
132+
}
133+
134+
private String getQualifierDisplayString() {
135+
if (qualifier instanceof String s) {
136+
return s.isEmpty() ? "@Named" : "@Named(\"" + s + "\")";
137+
}
138+
String s = Utils.getDisplayString(qualifier);
139+
return s;
133140
}
134141

135142
@Override
@@ -155,6 +162,6 @@ public int hashCode() {
155162

156163
@Override
157164
public String toString() {
158-
return (qualifier != null ? qualifier + " " : "") + type.getTypeName();
165+
return getDisplayString();
159166
}
160167
}

maven-di/src/main/java/org/apache/maven/di/impl/InjectorImpl.java

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -137,15 +137,18 @@ private Injector doBind(Key<?> key, Binding<?> binding) {
137137
current.add(key);
138138
throw new DIException("Circular references: " + current);
139139
}
140-
doBindImplicit(key, binding);
141-
Class<?> cls = key.getRawType().getSuperclass();
142-
while (cls != Object.class && cls != null) {
143-
key = Key.of(cls, key.getQualifier());
140+
try {
144141
doBindImplicit(key, binding);
145-
cls = cls.getSuperclass();
142+
Class<?> cls = key.getRawType().getSuperclass();
143+
while (cls != Object.class && cls != null) {
144+
key = Key.of(cls, key.getQualifier());
145+
doBindImplicit(key, binding);
146+
cls = cls.getSuperclass();
147+
}
148+
return this;
149+
} finally {
150+
current.remove(key);
146151
}
147-
current.remove(key);
148-
return this;
149152
}
150153

151154
protected <U> Injector bind(Key<U> key, Binding<U> b) {

maven-embedder/src/main/java/org/apache/maven/cli/MavenCli.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,7 @@
9595
import org.apache.maven.execution.scope.internal.MojoExecutionScopeModule;
9696
import org.apache.maven.extension.internal.CoreExports;
9797
import org.apache.maven.extension.internal.CoreExtensionEntry;
98+
import org.apache.maven.internal.impl.SisuDiBridgeModule;
9899
import org.apache.maven.jline.JLineMessageBuilderFactory;
99100
import org.apache.maven.jline.MessageUtils;
100101
import org.apache.maven.lifecycle.LifecycleExecutionException;
@@ -715,6 +716,7 @@ public Object getValue(String expression) {
715716
new SessionScopeModule(container.lookup(SessionScope.class)),
716717
new MojoExecutionScopeModule(container.lookup(MojoExecutionScope.class)),
717718
new ExtensionConfigurationModule(extension, extensionSource));
719+
container.lookup(SisuDiBridgeModule.class).loadFromClassLoader(extension.getClassRealm());
718720
}
719721

720722
customizeContainer(container);

0 commit comments

Comments
 (0)