mirror of
https://github.com/jlengrand/quarkus.git
synced 2026-03-10 08:41:22 +00:00
Add initial support for indexing additional classes
This commit is contained in:
19
README.md
19
README.md
@@ -212,4 +212,21 @@ mode, however there are some differences. The two basic modes are:
|
||||
* Runtime Mode
|
||||
Runtime mode involves generating the wiring bytecode at startup time. This is useful when developing apps with Shamrock,
|
||||
as it allows you to test and run things without a full maven. This is currently used for the JUnit test runner,
|
||||
and for the `mvn shamrock:run` command.
|
||||
and for the `mvn shamrock:run` command.
|
||||
|
||||
## Indexing
|
||||
|
||||
By default only the classes in the current application are indexed, however it is possible to include additional classes.
|
||||
|
||||
Two different mechanisms are provided to do this. In both cases these files are loaded from the class path, so all files
|
||||
present on the class path will be honoured.
|
||||
|
||||
* `META-INF/shamrock-index-dependencies`
|
||||
This file is a list of maven artifacts, in either group:artifact or group:artiface:classifer format. If an artifact
|
||||
is listed in this file then it will be indexed. Note that this should not be used for artifacts that are part of the
|
||||
current project. When running from an IDE it is not possible to reliably determine the artifactId. In this case you
|
||||
should use the method below.
|
||||
|
||||
* `META-INF/shamrock-index.marker`
|
||||
If this file is present in an archive then that archive will be indexed. This is mostly intended for use in
|
||||
multi-module projects.
|
||||
@@ -40,10 +40,12 @@ import java.util.Set;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
import java.util.function.Function;
|
||||
|
||||
import org.jboss.jandex.Index;
|
||||
import org.jboss.jandex.CompositeIndex;
|
||||
import org.jboss.jandex.IndexView;
|
||||
import org.jboss.jandex.Indexer;
|
||||
import org.jboss.shamrock.deployment.codegen.BytecodeRecorder;
|
||||
import org.jboss.shamrock.deployment.codegen.BytecodeRecorderImpl;
|
||||
import org.jboss.shamrock.deployment.index.IndexLoader;
|
||||
import org.jboss.shamrock.runtime.StartupContext;
|
||||
import org.jboss.shamrock.runtime.StartupTask;
|
||||
import org.objectweb.asm.AnnotationVisitor;
|
||||
@@ -73,10 +75,6 @@ public class BuildTimeGenerator {
|
||||
private final boolean useStaticInit;
|
||||
private final List<Function<String, Function<ClassVisitor, ClassVisitor>>> bytecodeTransformers = new ArrayList<>();
|
||||
|
||||
public BuildTimeGenerator(ClassOutput classOutput, boolean useStaticInit) {
|
||||
this(classOutput, BuildTimeGenerator.class.getClassLoader(), useStaticInit);
|
||||
}
|
||||
|
||||
public BuildTimeGenerator(ClassOutput classOutput, ClassLoader cl, boolean useStaticInit) {
|
||||
this.useStaticInit = useStaticInit;
|
||||
Iterator<ResourceProcessor> loader = ServiceLoader.load(ResourceProcessor.class, cl).iterator();
|
||||
@@ -126,8 +124,12 @@ public class BuildTimeGenerator {
|
||||
return FileVisitResult.CONTINUE;
|
||||
}
|
||||
});
|
||||
Index index = indexer.complete();
|
||||
ArchiveContext context = new ArchiveContextImpl(index, root);
|
||||
List<IndexView> composite = new ArrayList<>();
|
||||
composite.add(indexer.complete());
|
||||
composite.addAll(IndexLoader.scanForOtherIndexes(classLoader));
|
||||
|
||||
|
||||
ArchiveContext context = new ArchiveContextImpl(CompositeIndex.create(composite), root);
|
||||
ProcessorContextImpl processorContext = new ProcessorContextImpl();
|
||||
for (ResourceProcessor processor : processors) {
|
||||
try {
|
||||
@@ -147,16 +149,16 @@ public class BuildTimeGenerator {
|
||||
|
||||
private static class ArchiveContextImpl implements ArchiveContext {
|
||||
|
||||
private final Index index;
|
||||
private final IndexView index;
|
||||
private final Path root;
|
||||
|
||||
private ArchiveContextImpl(Index index, Path root) {
|
||||
private ArchiveContextImpl(IndexView index, Path root) {
|
||||
this.index = index;
|
||||
this.root = root;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Index getIndex() {
|
||||
public IndexView getIndex() {
|
||||
return index;
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,46 @@
|
||||
package org.jboss.shamrock.deployment.index;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.util.Enumeration;
|
||||
import java.util.jar.JarEntry;
|
||||
import java.util.jar.JarFile;
|
||||
|
||||
import org.jboss.jandex.IndexView;
|
||||
import org.jboss.jandex.Indexer;
|
||||
|
||||
public class ArtifactIndex {
|
||||
|
||||
private final ArtifactResolver resolver;
|
||||
|
||||
public ArtifactIndex(ArtifactResolver resolver) {
|
||||
this.resolver = resolver;
|
||||
}
|
||||
|
||||
public IndexView getIndex(String groupId, String artifactId, String classifier) {
|
||||
ResolvedArtifact artifact = resolver.getArtifact(groupId, artifactId, classifier);
|
||||
if (artifact == null) {
|
||||
throw new RuntimeException("Unable to resolve artifact " + groupId + ":" + artifactId + ":" + classifier);
|
||||
}
|
||||
Indexer indexer = new Indexer();
|
||||
try {
|
||||
try (JarFile file = new JarFile(artifact.getArtifactPath().toFile())) {
|
||||
Enumeration<JarEntry> e = file.entries();
|
||||
while (e.hasMoreElements()) {
|
||||
JarEntry entry = e.nextElement();
|
||||
if (entry.getName().endsWith(".class")) {
|
||||
try (InputStream inputStream = file.getInputStream(entry)) {
|
||||
indexer.index(inputStream);
|
||||
}
|
||||
} else if (entry.getName().equals(IndexLoader.INDEX_MARKER)) {
|
||||
//TODO: we can probably handle this more gracefully
|
||||
throw new RuntimeException(artifact + " has a " + IndexLoader.INDEX_MARKER + " file, but was also listed in META-INF/shamrock-index-dependencies");
|
||||
}
|
||||
}
|
||||
}
|
||||
return indexer.complete();
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
package org.jboss.shamrock.deployment.index;
|
||||
|
||||
/**
|
||||
* Resolves maven artifacts for indexing.
|
||||
*/
|
||||
public interface ArtifactResolver {
|
||||
|
||||
ResolvedArtifact getArtifact(String groupId, String artifactId, String classifier);
|
||||
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
package org.jboss.shamrock.deployment.index;
|
||||
|
||||
public class CachedIndexProvider {
|
||||
}
|
||||
@@ -0,0 +1,95 @@
|
||||
package org.jboss.shamrock.deployment.index;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.URL;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Enumeration;
|
||||
import java.util.List;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
/**
|
||||
* Class path based runner that can resolve artifacts from the current class path.
|
||||
* <p>
|
||||
* This assumes that all artifacts to be resolved have a META-INF/MANIFEST.MF file,
|
||||
* and are layed out in the maven repository structure on the file system.
|
||||
*/
|
||||
public class ClassPathArtifactResolver implements ArtifactResolver {
|
||||
|
||||
private static final String META_INF_MANIFEST_MF = "META-INF/MANIFEST.MF";
|
||||
private final List<StoredUrl> pathList = new ArrayList<>();
|
||||
|
||||
public ClassPathArtifactResolver(ClassLoader classLoader) {
|
||||
ClassLoader cl = classLoader;
|
||||
try {
|
||||
Enumeration<URL> res = cl.getResources(META_INF_MANIFEST_MF);
|
||||
while (res.hasMoreElements()) {
|
||||
URL jarUrl = res.nextElement();
|
||||
String path = jarUrl.getPath();
|
||||
if (path.startsWith("file:")) {
|
||||
path = path.substring(5, path.length() - META_INF_MANIFEST_MF.length() - 2);
|
||||
String[] parts = path.split("/"); //TODO: windows?
|
||||
String fileName = parts[parts.length - 1];
|
||||
List<String> fileParts = new ArrayList<>();
|
||||
for (int i = parts.length - 2; i >= 0; --i) {
|
||||
fileParts.add(parts[i]);
|
||||
}
|
||||
pathList.add(new StoredUrl(Paths.get(path), fileName, fileParts));
|
||||
}
|
||||
}
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public ResolvedArtifact getArtifact(String groupId, String artifactId, String classifier) {
|
||||
Pattern filePatten;
|
||||
if (classifier == null || classifier.isEmpty()) {
|
||||
filePatten = Pattern.compile(artifactId + "-(\\d.*)\\.jar");
|
||||
} else {
|
||||
filePatten = Pattern.compile(artifactId + "-" + classifier + "-(\\d.*)\\.jar");
|
||||
}
|
||||
for (StoredUrl url : pathList) {
|
||||
Matcher matcher = filePatten.matcher(url.fileName);
|
||||
if (matcher.matches()) {
|
||||
String[] groupParts = groupId.split("\\.");
|
||||
if (url.reverseParts.size() < groupParts.length + 2) {
|
||||
continue;
|
||||
}
|
||||
|
||||
boolean matches = true;
|
||||
for (int i = 0; i < groupParts.length; ++i) {
|
||||
String up = url.reverseParts.get(groupParts.length + 1 - i);
|
||||
if (!up.equals(groupParts[i])) {
|
||||
matches = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (matches) {
|
||||
try {
|
||||
return new ResolvedArtifact(groupId, artifactId, matcher.group(1), classifier, url.path);
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
throw new RuntimeException("Could not resolve artifact " + groupId + ":" + artifactId + ":" + classifier);
|
||||
}
|
||||
|
||||
static class StoredUrl {
|
||||
final Path path;
|
||||
final String fileName;
|
||||
final List<String> reverseParts;
|
||||
|
||||
private StoredUrl(Path path, String fileName, List<String> reverseParts) {
|
||||
this.path = path;
|
||||
this.fileName = fileName;
|
||||
this.reverseParts = reverseParts;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,113 @@
|
||||
package org.jboss.shamrock.deployment.index;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.InputStreamReader;
|
||||
import java.net.URL;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Enumeration;
|
||||
import java.util.List;
|
||||
import java.util.function.Consumer;
|
||||
import java.util.jar.JarEntry;
|
||||
import java.util.jar.JarFile;
|
||||
|
||||
import org.jboss.jandex.IndexView;
|
||||
import org.jboss.jandex.Indexer;
|
||||
|
||||
/**
|
||||
* Class that is responsible for loading indexes from outside the deployment
|
||||
*/
|
||||
public class IndexLoader {
|
||||
|
||||
|
||||
private static final String META_INF_SHAMROCK_INDEX_DEPENDENCIES = "META-INF/shamrock-index-dependencies";
|
||||
static final String INDEX_MARKER = "META-INF/shamrock-index.marker";
|
||||
|
||||
public static List<IndexView> scanForOtherIndexes(ClassLoader classLoader) throws IOException {
|
||||
ArtifactIndex artifactIndex = new ArtifactIndex(new ClassPathArtifactResolver(classLoader));
|
||||
Enumeration<URL> resources = classLoader.getResources(META_INF_SHAMROCK_INDEX_DEPENDENCIES);
|
||||
List<IndexView> ret = new ArrayList<>();
|
||||
while (resources.hasMoreElements()) {
|
||||
URL resource = resources.nextElement();
|
||||
try (final BufferedReader in = new BufferedReader(new InputStreamReader(resource.openStream()))) {
|
||||
String line = in.readLine();
|
||||
if (line.startsWith("#")) {
|
||||
continue;
|
||||
}
|
||||
int commentPos = line.indexOf('#');
|
||||
if (commentPos > 0) {
|
||||
line = line.substring(0, commentPos);
|
||||
}
|
||||
line = line.trim();
|
||||
if (line.isEmpty()) {
|
||||
continue;
|
||||
}
|
||||
String[] parts = line.split(":");
|
||||
|
||||
if (parts.length == 2) {
|
||||
ret.add(artifactIndex.getIndex(parts[0], parts[1], null));
|
||||
} else if (parts.length == 3) {
|
||||
ret.add(artifactIndex.getIndex(parts[0], parts[1], parts[2]));
|
||||
} else {
|
||||
throw new RuntimeException("Invalid dependencies to index " + line);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException("Exception resolving dependencies from " + resource, e);
|
||||
}
|
||||
}
|
||||
ret.add(getMarkerIndexes(classLoader));
|
||||
return ret;
|
||||
}
|
||||
|
||||
public static IndexView getMarkerIndexes(ClassLoader classLoader) {
|
||||
try {
|
||||
Indexer indexer = new Indexer();
|
||||
Enumeration<URL> urls = classLoader.getResources(INDEX_MARKER);
|
||||
while (urls.hasMoreElements()) {
|
||||
URL url = urls.nextElement();
|
||||
if (url.getProtocol().equals("jar")) {
|
||||
handleJarPath(url.getPath().substring(5, url.getPath().length() - INDEX_MARKER.length() - 2), indexer);
|
||||
} else if (url.getProtocol().equals("file")) {
|
||||
handleFilePath(url.getPath().substring(0, url.getPath().length() - INDEX_MARKER.length() - 1), indexer);
|
||||
}
|
||||
}
|
||||
return indexer.complete();
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
private static void handleFilePath(String path, Indexer indexer) throws IOException {
|
||||
Files.walk(Paths.get(path)).forEach(new Consumer<Path>() {
|
||||
@Override
|
||||
public void accept(Path path) {
|
||||
if (path.toString().endsWith(".class")) {
|
||||
try (FileInputStream in = new FileInputStream(path.toFile())) {
|
||||
indexer.index(in);
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private static void handleJarPath(String path, Indexer indexer) throws IOException {
|
||||
try (JarFile file = new JarFile(path)) {
|
||||
Enumeration<JarEntry> e = file.entries();
|
||||
while (e.hasMoreElements()) {
|
||||
JarEntry entry = e.nextElement();
|
||||
if (entry.getName().endsWith(".class")) {
|
||||
try (InputStream inputStream = file.getInputStream(entry)) {
|
||||
indexer.index(inputStream);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,54 @@
|
||||
package org.jboss.shamrock.deployment.index;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
|
||||
public class MapArtifactResolver implements ArtifactResolver {
|
||||
|
||||
private final Map<Key, ResolvedArtifact> artifacts;
|
||||
|
||||
public MapArtifactResolver(List<ResolvedArtifact> artifacts) {
|
||||
Map<Key, ResolvedArtifact> map = new HashMap<>();
|
||||
for (ResolvedArtifact i : artifacts) {
|
||||
map.put(new Key(i.getGroupId(), i.getArtifactId(), i.getClassifier()), i);
|
||||
}
|
||||
this.artifacts = map;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ResolvedArtifact getArtifact(String groupId, String artifactId, String classifier) {
|
||||
return artifacts.get(new Key(groupId, artifactId, classifier));
|
||||
}
|
||||
|
||||
private static class Key {
|
||||
final String groupId;
|
||||
final String artifactId;
|
||||
final String classifier;
|
||||
|
||||
private Key(String groupId, String artifactId, String classifier) {
|
||||
this.groupId = groupId;
|
||||
this.artifactId = artifactId;
|
||||
this.classifier = classifier;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
if (o == null || getClass() != o.getClass()) return false;
|
||||
Key key = (Key) o;
|
||||
return Objects.equals(groupId, key.groupId) &&
|
||||
Objects.equals(artifactId, key.artifactId) &&
|
||||
Objects.equals(classifier, key.classifier);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
|
||||
return Objects.hash(groupId, artifactId, classifier);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,51 @@
|
||||
package org.jboss.shamrock.deployment.index;
|
||||
|
||||
import java.nio.file.Path;
|
||||
|
||||
|
||||
public class ResolvedArtifact {
|
||||
|
||||
private final String groupId;
|
||||
private final String artifactId;
|
||||
private final String version;
|
||||
private final String classifier;
|
||||
private final Path artifactPath;
|
||||
|
||||
public ResolvedArtifact(String groupId, String artifactId, String version, String classifier, Path artifactPath) {
|
||||
this.groupId = groupId;
|
||||
this.artifactId = artifactId;
|
||||
this.version = version;
|
||||
this.classifier = classifier;
|
||||
this.artifactPath = artifactPath;
|
||||
}
|
||||
|
||||
public String getGroupId() {
|
||||
return groupId;
|
||||
}
|
||||
|
||||
public String getArtifactId() {
|
||||
return artifactId;
|
||||
}
|
||||
|
||||
public String getVersion() {
|
||||
return version;
|
||||
}
|
||||
|
||||
public String getClassifier() {
|
||||
return classifier;
|
||||
}
|
||||
|
||||
public Path getArtifactPath() {
|
||||
return artifactPath;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "ResolvedArtifact{" +
|
||||
"groupId='" + groupId + '\'' +
|
||||
", artifactId='" + artifactId + '\'' +
|
||||
", version='" + version + '\'' +
|
||||
", classifier='" + classifier + '\'' +
|
||||
'}';
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
package org.jboss.shamrock.runtime;
|
||||
package org.jboss.shamrock.runner;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
@@ -1,4 +1,4 @@
|
||||
package org.jboss.shamrock.runtime;
|
||||
package org.jboss.shamrock.runner;
|
||||
|
||||
import java.io.Closeable;
|
||||
import java.io.IOException;
|
||||
@@ -12,10 +12,15 @@ import java.util.function.Consumer;
|
||||
import java.util.function.Function;
|
||||
|
||||
import org.jboss.shamrock.deployment.BuildTimeGenerator;
|
||||
import org.jboss.shamrock.deployment.index.ClassPathArtifactResolver;
|
||||
import org.objectweb.asm.ClassReader;
|
||||
import org.objectweb.asm.ClassVisitor;
|
||||
import org.objectweb.asm.ClassWriter;
|
||||
|
||||
/**
|
||||
* Class that can be used to run shamrock directly, ececuting the build and runtime
|
||||
* steps in the same JVM
|
||||
*/
|
||||
public class RuntimeRunner implements Runnable, Closeable {
|
||||
|
||||
private final Path target;
|
||||
@@ -3,17 +3,19 @@
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<parent>
|
||||
<artifactId>shamrock-parent</artifactId>
|
||||
<artifactId>shamrock-examples-parent</artifactId>
|
||||
<groupId>org.jboss.shamrock</groupId>
|
||||
<version>1.0.0.Alpha1-SNAPSHOT</version>
|
||||
<relativePath>../../</relativePath>
|
||||
<relativePath>../</relativePath>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<artifactId>shamrock-class-transformer-example</artifactId>
|
||||
<description>An example deployment time processor that tests
|
||||
out the class transformation ability by adding an additional
|
||||
route to all JAX-RS endpoints.
|
||||
<description>
|
||||
|
||||
An example deployment time processor that tests
|
||||
out the class transformation ability by adding an additional
|
||||
route to all JAX-RS endpoints.
|
||||
|
||||
This should probably be deleted once we have a proper test framework.
|
||||
|
||||
|
||||
@@ -3,10 +3,10 @@
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<parent>
|
||||
<artifactId>shamrock-parent</artifactId>
|
||||
<artifactId>shamrock-examples-parent</artifactId>
|
||||
<groupId>org.jboss.shamrock</groupId>
|
||||
<version>1.0.0.Alpha1-SNAPSHOT</version>
|
||||
<relativePath>../../</relativePath>
|
||||
<relativePath>../</relativePath>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
||||
21
examples/pom.xml
Normal file
21
examples/pom.xml
Normal file
@@ -0,0 +1,21 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<parent>
|
||||
<artifactId>shamrock-parent</artifactId>
|
||||
<groupId>org.jboss.shamrock</groupId>
|
||||
<version>1.0.0.Alpha1-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<artifactId>shamrock-examples-parent</artifactId>
|
||||
<packaging>pom</packaging>
|
||||
<modules>
|
||||
<module>class-transformer</module>
|
||||
<module>everything</module>
|
||||
<module>shared-library</module>
|
||||
<module>strict</module>
|
||||
</modules>
|
||||
|
||||
</project>
|
||||
31
examples/shared-library/pom.xml
Normal file
31
examples/shared-library/pom.xml
Normal file
@@ -0,0 +1,31 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<parent>
|
||||
<artifactId>shamrock-examples-parent</artifactId>
|
||||
<groupId>org.jboss.shamrock</groupId>
|
||||
<version>1.0.0.Alpha1-SNAPSHOT</version>
|
||||
<relativePath>../</relativePath>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<artifactId>shamrock-shared-library-example</artifactId>
|
||||
<description>
|
||||
|
||||
An example/test of a componentised application. This is indexed at build time by shamrock
|
||||
and components it provides should be included as normal.
|
||||
|
||||
</description>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.jboss.spec.javax.servlet</groupId>
|
||||
<artifactId>jboss-servlet-api_4.0_spec</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.jboss.spec.javax.ws.rs</groupId>
|
||||
<artifactId>jboss-jaxrs-api_2.1_spec</artifactId>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
</project>
|
||||
@@ -0,0 +1,13 @@
|
||||
package org.jboss.shamrock.example.shared;
|
||||
|
||||
import javax.ws.rs.GET;
|
||||
import javax.ws.rs.Path;
|
||||
|
||||
@Path("/shared")
|
||||
public class SharedResource {
|
||||
|
||||
@GET
|
||||
public String shared() {
|
||||
return "Shared Resource";
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
This is a marker file that can be empty. Any jar with this marker file will automatically be indexed
|
||||
by shamrock.
|
||||
|
||||
The main use case for this is IDE integration for multi-module projects. When running from the IDE it is
|
||||
not possible to determine the artifact ID of other artifacts in the project.
|
||||
@@ -3,10 +3,10 @@
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<parent>
|
||||
<artifactId>shamrock-parent</artifactId>
|
||||
<artifactId>shamrock-examples-parent</artifactId>
|
||||
<groupId>org.jboss.shamrock</groupId>
|
||||
<version>1.0.0.Alpha1-SNAPSHOT</version>
|
||||
<relativePath>../../</relativePath>
|
||||
<relativePath>../</relativePath>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
@@ -24,6 +24,10 @@
|
||||
<artifactId>shamrock-class-transformer-example</artifactId>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.jboss.shamrock</groupId>
|
||||
<artifactId>shamrock-shared-library-example</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.jboss.resteasy</groupId>
|
||||
<artifactId>resteasy-json-p-provider</artifactId>
|
||||
|
||||
@@ -0,0 +1,30 @@
|
||||
package org.jboss.shamrock.example.test;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.InputStream;
|
||||
import java.net.URL;
|
||||
import java.net.URLConnection;
|
||||
|
||||
import org.jboss.shamrock.junit.ShamrockTest;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
|
||||
@RunWith(ShamrockTest.class)
|
||||
public class ExternalIndexTestCase {
|
||||
|
||||
@Test
|
||||
public void testJAXRSResourceFromExternalLibrary() throws Exception {
|
||||
URL uri = new URL("http://localhost:8080/rest/shared");
|
||||
URLConnection connection = uri.openConnection();
|
||||
InputStream in = connection.getInputStream();
|
||||
byte[] buf = new byte[100];
|
||||
int r;
|
||||
ByteArrayOutputStream out = new ByteArrayOutputStream();
|
||||
while ((r = in.read(buf)) > 0) {
|
||||
out.write(buf, 0, r);
|
||||
}
|
||||
Assert.assertEquals("Shared Resource", new String(out.toByteArray()));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -11,8 +11,6 @@ import org.jboss.shamrock.undertow.ServletData;
|
||||
import org.jboss.shamrock.undertow.ServletDeployment;
|
||||
import org.jboss.shamrock.weld.deployment.WeldDeployment;
|
||||
|
||||
import io.smallrye.health.SmallRyeHealthReporter;
|
||||
|
||||
public class HealthProcessor implements ResourceProcessor {
|
||||
|
||||
|
||||
@@ -30,7 +28,6 @@ public class HealthProcessor implements ResourceProcessor {
|
||||
ServletData servletData = new ServletData("health", HealthServlet.class.getName());
|
||||
servletData.getMapings().add(config.getConfig("health.path", "/health"));
|
||||
servletDeployment.addServlet(servletData);
|
||||
weldDeployment.addAdditionalBean(SmallRyeHealthReporter.class);
|
||||
weldDeployment.addAdditionalBean(HealthServlet.class);
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
io.smallrye:smallrye-health
|
||||
@@ -125,7 +125,9 @@ public class JaxrsScanningProcessor implements ResourceProcessor {
|
||||
}
|
||||
}
|
||||
|
||||
undertow.addServletContextParameter(null, ResteasyContextParameters.RESTEASY_SCANNED_RESOURCES, sb.toString());
|
||||
if(sb.length() > 0) {
|
||||
undertow.addServletContextParameter(null, ResteasyContextParameters.RESTEASY_SCANNED_RESOURCES, sb.toString());
|
||||
}
|
||||
undertow.addServletContextParameter(null, "resteasy.servlet.mapping.prefix", path);
|
||||
undertow.addServletContextParameter(null, "resteasy.injector.factory", ShamrockInjectorFactory.class.getName());
|
||||
processorContext.addReflectiveClass(HttpServlet30Dispatcher.class.getName());
|
||||
|
||||
@@ -36,6 +36,8 @@ import org.apache.maven.plugins.annotations.ResolutionScope;
|
||||
import org.apache.maven.project.MavenProject;
|
||||
import org.jboss.shamrock.deployment.BuildTimeGenerator;
|
||||
import org.jboss.shamrock.deployment.ClassOutput;
|
||||
import org.jboss.shamrock.deployment.index.MapArtifactResolver;
|
||||
import org.jboss.shamrock.deployment.index.ResolvedArtifact;
|
||||
import org.objectweb.asm.ClassReader;
|
||||
import org.objectweb.asm.ClassVisitor;
|
||||
import org.objectweb.asm.ClassWriter;
|
||||
@@ -43,6 +45,8 @@ import org.objectweb.asm.ClassWriter;
|
||||
@Mojo(name = "build", defaultPhase = LifecyclePhase.PREPARE_PACKAGE, requiresDependencyResolution = ResolutionScope.COMPILE_PLUS_RUNTIME)
|
||||
public class BuildMojo extends AbstractMojo {
|
||||
|
||||
private static final String DEPENDENCIES_RUNTIME = "dependencies.runtime";
|
||||
private static final String PROVIDED = "provided";
|
||||
/**
|
||||
* The directory for compiled classes.
|
||||
*/
|
||||
@@ -88,11 +92,11 @@ public class BuildMojo extends AbstractMojo {
|
||||
for (Artifact a : project.getArtifacts()) {
|
||||
try (ZipFile zip = new ZipFile(a.getFile())) {
|
||||
if (zip.getEntry("META-INF/services/org.jboss.shamrock.deployment.ResourceProcessor") != null) {
|
||||
if (!a.getScope().equals("provided")) {
|
||||
if (!a.getScope().equals(PROVIDED)) {
|
||||
problems.add("Artifact " + a + " is a deployment artifact, however it does not have scope required. This will result in unnecessary jars being included in the final image");
|
||||
}
|
||||
}
|
||||
ZipEntry deps = zip.getEntry("dependencies.runtime");
|
||||
ZipEntry deps = zip.getEntry(DEPENDENCIES_RUNTIME);
|
||||
if (deps != null) {
|
||||
whitelist.add(a.getDependencyConflictId());
|
||||
try (InputStream in = zip.getInputStream(deps)) {
|
||||
@@ -125,7 +129,7 @@ public class BuildMojo extends AbstractMojo {
|
||||
}
|
||||
|
||||
for (Artifact a : project.getArtifacts()) {
|
||||
if (a.getScope().equals("provided") && !whitelist.contains(a.getDependencyConflictId())) {
|
||||
if (a.getScope().equals(PROVIDED) && !whitelist.contains(a.getDependencyConflictId())) {
|
||||
continue;
|
||||
}
|
||||
try (FileInputStream in = new FileInputStream(a.getFile())) {
|
||||
@@ -140,14 +144,21 @@ public class BuildMojo extends AbstractMojo {
|
||||
}
|
||||
}
|
||||
|
||||
List<ResolvedArtifact> artifactList = new ArrayList<>();
|
||||
List<URL> classPathUrls = new ArrayList<>();
|
||||
for (Artifact artifact : project.getArtifacts()) {
|
||||
classPathUrls.add(artifact.getFile().toURL());
|
||||
artifactList.add(new ResolvedArtifact(artifact.getGroupId(), artifact.getArtifactId(), artifact.getVersion(), artifact.getClassifier(), Paths.get(artifact.getFile().getAbsolutePath())));
|
||||
}
|
||||
|
||||
//we need to make sure all the deployment artifacts are on the class path
|
||||
//to do this we need to create a new class loader to actually use for the runner
|
||||
URLClassLoader runnerClassLoader = new URLClassLoader(classPathUrls.toArray(new URL[0]), getClass().getClassLoader());
|
||||
List<URL> cpCopy = new ArrayList<>();
|
||||
|
||||
cpCopy.add(outputDirectory.toURL());
|
||||
cpCopy.addAll(classPathUrls);
|
||||
|
||||
URLClassLoader runnerClassLoader = new URLClassLoader(cpCopy.toArray(new URL[0]), getClass().getClassLoader());
|
||||
BuildTimeGenerator buildTimeGenerator = new BuildTimeGenerator(new ClassOutput() {
|
||||
@Override
|
||||
public void writeClass(String className, byte[] data) throws IOException {
|
||||
|
||||
@@ -29,7 +29,7 @@ public class RunMojoMain {
|
||||
ClassLoader old = Thread.currentThread().getContextClassLoader();
|
||||
try {
|
||||
Thread.currentThread().setContextClassLoader(runtimeCl);
|
||||
Class<?> runnerClass = runtimeCl.loadClass("org.jboss.shamrock.runtime.RuntimeRunner");
|
||||
Class<?> runnerClass = runtimeCl.loadClass("org.jboss.shamrock.runner.RuntimeRunner");
|
||||
Constructor ctor = runnerClass.getDeclaredConstructor(Path.class, ClassLoader.class);
|
||||
Object runner = ctor.newInstance(classesRoot.toPath(), runtimeCl);
|
||||
((Runnable) runner).run();
|
||||
|
||||
9
pom.xml
9
pom.xml
@@ -44,9 +44,7 @@
|
||||
<module>weld</module>
|
||||
<module>health</module>
|
||||
<module>metrics</module>
|
||||
<module>examples/class-transformer</module>
|
||||
<module>examples/everything</module>
|
||||
<module>examples/strict</module>
|
||||
<module>examples</module>
|
||||
</modules>
|
||||
<build>
|
||||
<pluginManagement>
|
||||
@@ -128,6 +126,11 @@
|
||||
<artifactId>shamrock-junit</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.jboss.shamrock</groupId>
|
||||
<artifactId>shamrock-shared-library-example</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.jboss.shamrock</groupId>
|
||||
<artifactId>shamrock-undertow-deployment</artifactId>
|
||||
|
||||
@@ -4,7 +4,7 @@ import java.net.URL;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
|
||||
import org.jboss.shamrock.runtime.RuntimeRunner;
|
||||
import org.jboss.shamrock.runner.RuntimeRunner;
|
||||
import org.junit.runner.Description;
|
||||
import org.junit.runner.notification.Failure;
|
||||
import org.junit.runner.notification.RunListener;
|
||||
|
||||
Reference in New Issue
Block a user