Skip to content

Commit 88d2190

Browse files
authored
Merge branch 'master' into lazy-checked
2 parents 480734c + c42eb5c commit 88d2190

File tree

6 files changed

+85
-56
lines changed

6 files changed

+85
-56
lines changed

inject-generator/src/main/java/io/avaje/inject/generator/ExternalProvider.java

Lines changed: 26 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
import java.util.ArrayList;
1111
import java.util.Arrays;
1212
import java.util.Collection;
13+
import java.util.HashMap;
1314
import java.util.HashSet;
1415
import java.util.List;
1516
import java.util.Map;
@@ -81,7 +82,6 @@ static void registerModuleProvidedTypes(Set<String> providedTypes) {
8182
}
8283
for (final var module : modules) {
8384
final var name = module.getClass().getTypeName();
84-
APContext.logNote("Detected Module: %s", name);
8585
final var provides = new TreeSet<String>();
8686
for (final var provide : module.provides()) {
8787
provides.add(provide.getTypeName());
@@ -120,6 +120,7 @@ static void registerPluginProvidedTypes(ScopeInfo defaultScope) {
120120

121121
List<InjectPlugin> plugins = LoadServices.loadPlugins(CLASS_LOADER);
122122
for (final var plugin : plugins) {
123+
ProcessingContext.addExternalInjectSPI(plugin.getClass().getCanonicalName());
123124
var name = plugin.getClass().getTypeName();
124125
if (avajePlugins.containsKey(name)) {
125126
continue;
@@ -143,6 +144,7 @@ private static boolean pluginExists(String relativeName) {
143144
}
144145

145146
static void registerExternalMetaData(String name) {
147+
ProcessingContext.addExternalInjectSPI(name);
146148
Optional.ofNullable(APContext.typeElement(name))
147149
.map(TypeElement::getEnclosedElements)
148150
.map(ElementFilter::methodsIn)
@@ -164,10 +166,13 @@ static void readMetaDataProvides(Collection<String> providedTypes) {
164166
}
165167

166168
static void scanAllInjectPlugins(ScopeInfo defaultScope) {
169+
Map<String, List<String>> plugins = new HashMap<>();
167170
final var hasPlugins = !defaultScope.pluginProvided().isEmpty();
168171
avajePlugins.forEach((k, v) -> {
169172
if (APContext.typeElement(k) != null) {
173+
plugins.put(k, v);
170174
APContext.logNote("Loaded Plugin: %s", k);
175+
ProcessingContext.addExternalInjectSPI(k);
171176
v.forEach(defaultScope::pluginProvided);
172177
}
173178
});
@@ -179,42 +184,50 @@ static void scanAllInjectPlugins(ScopeInfo defaultScope) {
179184
injectExtensions()
180185
.filter(PluginProvidesPrism::isPresent)
181186
.distinct()
182-
.forEach(pluginType -> addPluginToScope(defaultScope, pluginType));
187+
.forEach(pluginType -> addPluginToScope(defaultScope, pluginType, plugins));
183188

184189
if (defaultScope.pluginProvided().isEmpty()) {
185190
APContext.logNote("No external plugins detected");
186191
}
187-
writePluginProvides(defaultScope);
192+
writePluginProvides(plugins);
188193
}
189194

190-
private static void writePluginProvides(ScopeInfo defaultScope) {
195+
private static void writePluginProvides(Map<String, List<String>> plugins) {
191196
// write detected plugins to a text file for test compilation
192-
try (final var pluginWriter = new FileWriter(APContext.getBuildResource("avaje-plugin-provides.txt").toFile())) {
193-
for (var providedType : defaultScope.pluginProvided()) {
194-
pluginWriter.write(providedType);
197+
try (final var pluginWriter = new FileWriter(APContext.getBuildResource("avaje-plugins.csv").toFile())) {
198+
pluginWriter.write("External Plugin Type|Provides");
199+
for (final var plugin : plugins.entrySet()) {
195200
pluginWriter.write("\n");
201+
pluginWriter.write(plugin.getKey());
202+
pluginWriter.write("|");
203+
var provides = String.join(",", plugin.getValue());
204+
pluginWriter.write(provides.isEmpty() ? " " : provides);
196205
}
197206
} catch (IOException e) {
198-
APContext.logWarn("Failed to write avaje-plugin-provides.txt due to %s", e.getMessage());
207+
APContext.logWarn("Failed to write avaje-plugins.csv due to %s", e.getMessage());
199208
}
200209
}
201210

202-
private static void addPluginToScope(ScopeInfo defaultScope, TypeElement pluginType) {
211+
private static void addPluginToScope(ScopeInfo defaultScope, TypeElement pluginType, Map<String, List<String>> plugins) {
203212
final var name = pluginType.getQualifiedName().toString();
204-
if (avajePlugins.containsKey(name)) {
205-
return;
206-
}
213+
ProcessingContext.addExternalInjectSPI(name);
207214
var prism = PluginProvidesPrism.getInstanceOn(pluginType);
215+
List<String> provides = new ArrayList<>();
208216
for (final var provide : prism.value()) {
209217
defaultScope.pluginProvided(provide.toString());
218+
provides.add(provide.toString());
210219
}
211220
for (final var provide : prism.providesStrings()) {
212221
defaultScope.pluginProvided(provide);
222+
provides.add(provide);
213223
}
214224
for (final var provide : prism.providesAspects()) {
215-
defaultScope.pluginProvided(Util.wrapAspect(provide.toString()));
225+
final var wrapAspect = Util.wrapAspect(provide.toString());
226+
defaultScope.pluginProvided(wrapAspect);
227+
provides.add(wrapAspect);
216228
}
217229
APContext.logNote("Loaded Plugin: %s", name);
230+
plugins.put(name, provides);
218231
}
219232

220233
static void scanAllAvajeModules(Collection<String> providedTypes) {

inject-generator/src/main/java/io/avaje/inject/generator/InjectProcessor.java

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@
1010
import javax.lang.model.element.Element;
1111
import javax.lang.model.element.ElementKind;
1212
import javax.lang.model.element.ExecutableElement;
13-
import javax.lang.model.element.Modifier;
1413
import javax.lang.model.element.TypeElement;
1514
import javax.lang.model.util.ElementFilter;
1615
import javax.lang.model.util.Elements;
@@ -29,6 +28,7 @@
2928
@GenerateUtils
3029
@GenerateAPContext
3130
@GenerateModuleInfoReader
31+
@SupportedOptions("mergeServices")
3232
@SupportedAnnotationTypes({
3333
AspectImportPrism.PRISM_TYPE,
3434
AssistFactoryPrism.PRISM_TYPE,
@@ -66,7 +66,7 @@ public synchronized void init(ProcessingEnvironment processingEnv) {
6666
super.init(processingEnv);
6767
APContext.init(processingEnv);
6868
loadProvidedFiles();
69-
ProcessingContext.init(moduleFileProvided);
69+
ProcessingContext.registerProvidedTypes(moduleFileProvided);
7070
moduleData.forEach(ProcessingContext::addModule);
7171
this.elementUtils = processingEnv.getElementUtils();
7272
this.allScopes = new AllScopes();
@@ -98,7 +98,6 @@ public synchronized void init(ProcessingEnvironment processingEnv) {
9898
*/
9999
void loadProvidedFiles() {
100100
pluginFileProvided.addAll(lines("avaje-plugin-provides.txt"));
101-
102101
lines("avaje-module-dependencies.csv").stream()
103102
.filter(s -> s.contains("|") && !s.startsWith("External Module Type"))
104103
.distinct()
@@ -110,6 +109,11 @@ void loadProvidedFiles() {
110109
ExternalProvider.readMetaDataProvides(moduleFileProvided);
111110
this.moduleData.add(m);
112111
});
112+
lines("avaje-plugins.csv").stream()
113+
.filter(s -> s.contains("|") && !s.startsWith("External Plugin Type"))
114+
.distinct()
115+
.map(l -> l.split("\\|")[1])
116+
.forEach(pluginFileProvided::add);
113117
}
114118

115119
private List<String> lines(String relativeName) {

inject-generator/src/main/java/io/avaje/inject/generator/ProcessingContext.java

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@
2020
final class ProcessingContext {
2121

2222
private static final String EVENTS_SPI = "io.avaje.inject.events.spi.ObserverManagerPlugin";
23-
private static final ThreadLocal<Ctx> CTX = new ThreadLocal<>();
23+
private static final ThreadLocal<Ctx> CTX = ThreadLocal.withInitial(Ctx::new);
2424
private static boolean processingOver;
2525
private ProcessingContext() {}
2626

@@ -33,15 +33,15 @@ static final class Ctx {
3333
private final List<TypeElement> delayQueue = new ArrayList<>();
3434
private final Set<String> spiServices = new TreeSet<>();
3535
private boolean strictWiring;
36+
private final boolean mergeServices = APContext.getOption("mergeServices").map(Boolean::valueOf).orElse(true);
3637

3738
void registerProvidedTypes(Set<String> moduleFileProvided) {
3839
ExternalProvider.registerModuleProvidedTypes(providedTypes);
3940
providedTypes.addAll(moduleFileProvided);
4041
}
4142
}
4243

43-
static void init(Set<String> moduleFileProvided) {
44-
CTX.set(new Ctx());
44+
static void registerProvidedTypes(Set<String> moduleFileProvided) {
4545
CTX.get().registerProvidedTypes(moduleFileProvided);
4646
addEventSPI();
4747
}
@@ -105,6 +105,12 @@ static void addInjectSPI(String type) {
105105
CTX.get().spiServices.add(type);
106106
}
107107

108+
static void addExternalInjectSPI(String type) {
109+
if (CTX.get().mergeServices) {
110+
CTX.get().spiServices.add(type);
111+
}
112+
}
113+
108114
static FileObject createMetaInfWriterFor(String interfaceType) throws IOException {
109115
return filer().createResource(StandardLocation.CLASS_OUTPUT, "", interfaceType);
110116
}
@@ -205,10 +211,6 @@ static void processingOver(boolean over) {
205211
}
206212

207213
static void writeSPIServicesFile() {
208-
Optional.ofNullable(APContext.getProjectModuleElement())
209-
.filter(m -> "io.avaje.inject.test".equals(m.getQualifiedName().toString()))
210-
.ifPresent(m -> CTX.get().spiServices.remove(EVENTS_SPI));
211-
212214
readExistingMetaInfServices();
213215
if (CTX.get().spiServices.isEmpty()) {
214216
// no services to register

inject-gradle-plugin/src/main/java/io/avaje/inject/plugin/AvajeInjectPlugin.java

Lines changed: 21 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@
77
import io.avaje.inject.spi.InjectPlugin;
88
import io.avaje.inject.spi.InjectExtension;
99
import io.avaje.inject.spi.Module;
10+
import io.avaje.inject.spi.Plugin;
11+
1012
import org.gradle.api.*;
1113

1214
import java.io.File;
@@ -47,7 +49,7 @@ private void writeProvides(Project project) {
4749
}
4850

4951
try (var classLoader = classLoader(project);
50-
var pluginWriter = createFileWriter(outputDir.getPath(), "avaje-plugin-provides.txt");
52+
var pluginWriter = createFileWriter(outputDir.getPath(), "avaje-plugins.csv");
5153
var moduleCSV = createFileWriter(outputDir.getPath(), "avaje-module-dependencies.csv")) {
5254
writeProvidedPlugins(classLoader, pluginWriter);
5355
writeModuleCSV(classLoader, moduleCSV);
@@ -61,29 +63,36 @@ private FileWriter createFileWriter(String dir, String file) throws IOException
6163
}
6264

6365
private void writeProvidedPlugins(ClassLoader classLoader, FileWriter pluginWriter) throws IOException {
64-
final Set<String> providedTypes = new HashSet<>();
65-
66-
List<InjectPlugin> allPlugins = new ArrayList<>();
67-
ServiceLoader.load(io.avaje.inject.spi.Plugin.class, classLoader).forEach(allPlugins::add);
66+
final List<InjectPlugin> plugins = new ArrayList<>();
67+
ServiceLoader.load(Plugin.class, classLoader).forEach(plugins::add);
6868
ServiceLoader.load(InjectExtension.class, classLoader).stream()
6969
.map(Provider::get)
7070
.filter(InjectPlugin.class::isInstance)
7171
.map(InjectPlugin.class::cast)
72-
.forEach(allPlugins::add);
72+
.forEach(plugins::add);
73+
74+
final Map<String, List<String>> pluginEntries = new HashMap<>();
75+
for (final var plugin : plugins) {
7376

74-
for (final var plugin : allPlugins) {
75-
System.out.println("Loaded Plugin: " + plugin.getClass().getCanonicalName());
77+
final List<String> provides = new ArrayList<>();
78+
final var typeName = plugin.getClass().getTypeName();
79+
System.out.println("Loaded Plugin: " + typeName);
7680
for (final var provide : plugin.provides()) {
77-
providedTypes.add(provide.getTypeName());
81+
provides.add(provide.getTypeName());
7882
}
7983
for (final var provide : plugin.providesAspects()) {
80-
providedTypes.add(wrapAspect(provide.getCanonicalName()));
84+
provides.add(wrapAspect(provide.getCanonicalName()));
8185
}
86+
pluginEntries.put(typeName, provides);
8287
}
8388

84-
for (final var providedType : providedTypes) {
85-
pluginWriter.write(providedType);
89+
pluginWriter.write("External Plugin Type|Provides");
90+
for (final var providedType : pluginEntries.entrySet()) {
8691
pluginWriter.write("\n");
92+
pluginWriter.write(providedType.getKey());
93+
pluginWriter.write("|");
94+
var provides = providedType.getValue().stream().collect(joining(","));
95+
pluginWriter.write(provides.isEmpty() ? " " : provides);
8796
}
8897
}
8998

inject-maven-plugin/src/main/java/io/avaje/inject/mojo/AutoProvidesMojo.java

Lines changed: 21 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
package io.avaje.inject.mojo;
22

3-
import static java.util.stream.Collectors.joining;
43
import static java.util.stream.Collectors.toList;
54

65
import java.io.File;
@@ -12,11 +11,11 @@
1211
import java.net.URLClassLoader;
1312
import java.util.ArrayList;
1413
import java.util.Arrays;
15-
import java.util.HashSet;
14+
import java.util.HashMap;
1615
import java.util.List;
16+
import java.util.Map;
1717
import java.util.ServiceLoader;
1818
import java.util.ServiceLoader.Provider;
19-
import java.util.Set;
2019

2120
import org.apache.maven.artifact.Artifact;
2221
import org.apache.maven.artifact.resolver.filter.ScopeArtifactFilter;
@@ -53,8 +52,6 @@ public class AutoProvidesMojo extends AbstractMojo {
5352
@Parameter(defaultValue = "${project}", readonly = true, required = true)
5453
private MavenProject project;
5554

56-
private final List<ModuleData> modules = new ArrayList<>();
57-
5855
@Override
5956
public void execute() throws MojoExecutionException {
6057
final var listUrl = compileDependencies();
@@ -65,7 +62,7 @@ public void execute() throws MojoExecutionException {
6562
}
6663

6764
try (var newClassLoader = createClassLoader(listUrl);
68-
var pluginWriter = createFileWriter("avaje-plugin-provides.txt");
65+
var pluginWriter = createFileWriter("avaje-plugins.csv");
6966
var moduleCSV = createFileWriter("avaje-module-dependencies.csv")) {
7067

7168
writeProvidedPlugins(newClassLoader, pluginWriter);
@@ -79,9 +76,7 @@ public void execute() throws MojoExecutionException {
7976
private List<URL> compileDependencies() throws MojoExecutionException {
8077
final List<URL> listUrl = new ArrayList<>();
8178
project.setArtifactFilter(new ScopeArtifactFilter("compile"));
82-
final var deps = project.getArtifacts();
83-
84-
for (final Artifact artifact : deps) {
79+
for (final Artifact artifact : project.getArtifacts()) {
8580
try {
8681
listUrl.add(artifact.getFile().toURI().toURL());
8782
} catch (final MalformedURLException e) {
@@ -100,8 +95,6 @@ private FileWriter createFileWriter(String string) throws IOException {
10095
}
10196

10297
private void writeProvidedPlugins(URLClassLoader newClassLoader, FileWriter pluginWriter) throws IOException {
103-
final Set<String> providedTypes = new HashSet<>();
104-
10598
final Log log = getLog();
10699

107100
final List<InjectPlugin> plugins = new ArrayList<>();
@@ -112,24 +105,31 @@ private void writeProvidedPlugins(URLClassLoader newClassLoader, FileWriter plug
112105
.map(InjectPlugin.class::cast)
113106
.forEach(plugins::add);
114107

108+
final Map<String, List<String>> pluginEntries = new HashMap<>();
115109
for (final var plugin : plugins) {
116-
log.info("Loaded Plugin: " + plugin.getClass().getTypeName());
110+
final List<String> provides = new ArrayList<>();
111+
final var typeName = plugin.getClass().getTypeName();
112+
log.info("Loaded Plugin: " + typeName);
117113
for (final var provide : plugin.provides()) {
118-
providedTypes.add(provide.getTypeName());
114+
provides.add(provide.getTypeName());
119115
}
120116
for (final var provide : plugin.providesAspects()) {
121-
providedTypes.add(wrapAspect(provide.getCanonicalName()));
117+
provides.add(wrapAspect(provide.getCanonicalName()));
122118
}
119+
pluginEntries.put(typeName, provides);
123120
}
124121

125-
for (final var providedType : providedTypes) {
126-
pluginWriter.write(providedType);
122+
pluginWriter.write("External Plugin Type|Provides");
123+
for (final var providedType : pluginEntries.entrySet()) {
127124
pluginWriter.write("\n");
125+
pluginWriter.write(providedType.getKey());
126+
pluginWriter.write("|");
127+
var provides = String.join(",", providedType.getValue());
128+
pluginWriter.write(provides.isEmpty() ? " " : provides);
128129
}
129130
}
130131

131132
private void writeModuleCSV(ClassLoader newClassLoader, FileWriter moduleWriter) throws IOException {
132-
133133
final Log log = getLog();
134134
final List<AvajeModule> avajeModules = new ArrayList<>();
135135
ServiceLoader.load(Module.class, newClassLoader).forEach(avajeModules::add);
@@ -138,6 +138,8 @@ private void writeModuleCSV(ClassLoader newClassLoader, FileWriter moduleWriter)
138138
.filter(AvajeModule.class::isInstance)
139139
.map(AvajeModule.class::cast)
140140
.forEach(avajeModules::add);
141+
142+
List<ModuleData> modules = new ArrayList<>();
141143
for (final var module : avajeModules) {
142144
final var name = module.getClass().getTypeName();
143145
log.info("Detected External Module: " + name);
@@ -175,10 +177,10 @@ private void writeModuleCSV(ClassLoader newClassLoader, FileWriter moduleWriter)
175177
moduleWriter.write("\n");
176178
moduleWriter.write(avajeModule.name());
177179
moduleWriter.write("|");
178-
var provides = avajeModule.provides().stream().collect(joining(","));
180+
var provides = String.join(",", avajeModule.provides());
179181
moduleWriter.write(provides.isEmpty() ? " " : provides);
180182
moduleWriter.write("|");
181-
var requires = avajeModule.requires().stream().collect(joining(","));
183+
var requires = String.join(",", avajeModule.requires());
182184
moduleWriter.write(requires.isEmpty() ? " " : requires);
183185
}
184186
}

inject/src/main/java/io/avaje/inject/DBeanScopeBuilder.java

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -290,8 +290,7 @@ public BeanScope build() {
290290
"Could not find any AvajeModule instances to wire. Possible Causes: \n"
291291
+ "1. No beans have been defined.\n"
292292
+ "2. The avaje-inject-generator depedency was not available during compilation\n"
293-
+ "3. Perhaps using Gradle and a misconfigured IDE? Refer to https://avaje.io/inject#gradle"
294-
+ "4. Perhaps this is a fat jar and you have not configured your maven asembly/shade or gradle build task to merge META-INF/services");
293+
+ "3. Perhaps using Gradle and a misconfigured IDE? Refer to https://avaje.io/inject#gradle");
295294
}
296295

297296
postConstructList.forEach(builder::addPostConstruct);

0 commit comments

Comments
 (0)