Initial arc support

- weld is still used by default
- arc can be tested with permissive example using a maven profile
This commit is contained in:
Martin Kouba
2018-07-30 09:20:53 +02:00
committed by Stuart Douglas
parent 5b7051a1ed
commit 2a04d27dd5
40 changed files with 547 additions and 125 deletions

30
arc/deployment/pom.xml Normal file
View File

@@ -0,0 +1,30 @@
<?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-weld</artifactId>
<groupId>org.jboss.shamrock</groupId>
<version>1.0.0.Alpha1-SNAPSHOT</version>
<relativePath>../</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>shamrock-arc-deployment</artifactId>
<dependencies>
<dependency>
<groupId>org.jboss.shamrock</groupId>
<artifactId>shamrock-core-deployment</artifactId>
</dependency>
<dependency>
<groupId>org.jboss.shamrock</groupId>
<artifactId>shamrock-arc-runtime</artifactId>
</dependency>
<dependency>
<groupId>org.jboss.protean.arc</groupId>
<artifactId>arc-processor</artifactId>
</dependency>
</dependencies>
</project>

View File

@@ -0,0 +1,138 @@
package org.jboss.shamrock.arc.deployment;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;
import javax.inject.Inject;
import org.jboss.jandex.ClassInfo;
import org.jboss.jandex.CompositeIndex;
import org.jboss.jandex.DotName;
import org.jboss.jandex.IndexView;
import org.jboss.jandex.Indexer;
import org.jboss.protean.arc.ArcContainer;
import org.jboss.protean.arc.processor.BeanProcessor;
import org.jboss.protean.arc.processor.BeanProcessor.Builder;
import org.jboss.protean.arc.processor.ResourceOutput;
import org.jboss.shamrock.arc.runtime.ArcDeploymentTemplate;
import org.jboss.shamrock.deployment.ArchiveContext;
import org.jboss.shamrock.deployment.BeanArchiveIndex;
import org.jboss.shamrock.deployment.BeanDeployment;
import org.jboss.shamrock.deployment.ProcessorContext;
import org.jboss.shamrock.deployment.ResourceProcessor;
import org.jboss.shamrock.deployment.RuntimePriority;
import org.jboss.shamrock.deployment.codegen.BytecodeRecorder;
import io.smallrye.config.inject.ConfigProducer;
public class ArcAnnotationProcessor implements ResourceProcessor {
@Inject
BeanDeployment beanDeployment;
@Inject
BeanArchiveIndex beanArchiveIndex;
@Override
public void process(ArchiveContext archiveContext, ProcessorContext processorContext) throws Exception {
try (BytecodeRecorder recorder = processorContext.addStaticInitTask(RuntimePriority.ARC_DEPLOYMENT)) {
ArcDeploymentTemplate template = recorder.getRecordingProxy(ArcDeploymentTemplate.class);
List<DotName> additionalBeanDefiningAnnotations = new ArrayList<>();
additionalBeanDefiningAnnotations.add(DotName.createSimple("javax.servlet.annotation.WebServlet"));
additionalBeanDefiningAnnotations.add(DotName.createSimple("javax.ws.rs.Path"));
// TODO MP config
beanDeployment.addAdditionalBean(ConfigProducer.class);
// Index bean classes registered by shamrock
Indexer indexer = new Indexer();
Set<DotName> additionalIndex = new HashSet<>();
for (Class<?> beanClass : beanDeployment.getAdditionalBeans()) {
indexBeanClass(beanClass, indexer, beanArchiveIndex.getIndex(), additionalIndex);
}
CompositeIndex index = CompositeIndex.create(indexer.complete(), beanArchiveIndex.getIndex());
Set<String> frameworkPackages = additionalIndex.stream().map(dotName -> {
String name = dotName.toString();
return name.toString().substring(0, name.lastIndexOf("."));
}).collect(Collectors.toSet());
Builder builder = BeanProcessor.builder();
builder.setIndex(index);
builder.setAdditionalBeanDefiningAnnotations(additionalBeanDefiningAnnotations);
builder.setSharedAnnotationLiterals(false);
builder.setOutput(new ResourceOutput() {
@Override
public void writeResource(Resource resource) throws IOException {
switch (resource.getType()) {
case JAVA_CLASS:
// TODO a better way to identify app classes
boolean isAppClass = true;
for (String frameworkPackage : frameworkPackages) {
if (resource.getFullyQualifiedName().startsWith(frameworkPackage)) {
isAppClass = false;
}
}
System.out.println("Add " + (isAppClass ? "APP" : "FWK") + " class: " + resource.getFullyQualifiedName());
processorContext.addGeneratedClass(isAppClass, resource.getName(), resource.getData());
break;
case SERVICE_PROVIDER:
processorContext.addResource("META-INF/services/" + resource.getName(), resource.getData());
default:
break;
}
}
});
BeanProcessor beanProcessor = builder.build();
beanProcessor.process();
ArcContainer container = template.getContainer();
template.initBeanContainer(container);
template.setupInjection(container);
}
}
@Override
public int getPriority() {
return RuntimePriority.ARC_DEPLOYMENT;
}
private void indexBeanClass(Class<?> beanClass, Indexer indexer, IndexView shamrockIndex, Set<DotName> additionalIndex) {
DotName beanClassName = DotName.createSimple(beanClass.getName());
if (additionalIndex.contains(beanClassName)) {
return;
}
ClassInfo beanInfo = shamrockIndex.getClassByName(beanClassName);
if (beanInfo == null) {
System.out.println("Index bean class: " + beanClass);
try (InputStream stream = ArcAnnotationProcessor.class.getClassLoader().getResourceAsStream(beanClass.getName().replace('.', '/') + ".class")) {
beanInfo = indexer.index(stream);
additionalIndex.add(beanInfo.name());
} catch (IOException e) {
throw new IllegalStateException("Failed to index: " + beanClass);
}
} else {
// The class could be indexed by shamrock - we still need to distinguish framework classes
additionalIndex.add(beanClassName);
}
for (DotName annotationName : beanInfo.annotations().keySet()) {
if (!additionalIndex.contains(annotationName) && shamrockIndex.getClassByName(annotationName) == null) {
try (InputStream annotationStream = ArcAnnotationProcessor.class.getClassLoader()
.getResourceAsStream(annotationName.toString().replace('.', '/') + ".class")) {
System.out.println("Index annotation: " + annotationName);
indexer.index(annotationStream);
additionalIndex.add(annotationName);
} catch (IOException e) {
throw new IllegalStateException("Failed to index: " + beanClass);
}
}
}
}
}

View File

@@ -0,0 +1,12 @@
package org.jboss.shamrock.arc.deployment;
import org.jboss.shamrock.deployment.SetupContext;
import org.jboss.shamrock.deployment.ShamrockSetup;
public class ArcSetup implements ShamrockSetup {
@Override
public void setup(SetupContext context) {
context.addResourceProcessor(new ArcAnnotationProcessor());
}
}

View File

@@ -0,0 +1 @@
org.jboss.shamrock.arc.deployment.ArcSetup

19
arc/pom.xml Normal file
View File

@@ -0,0 +1,19 @@
<?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-arc</artifactId>
<packaging>pom</packaging>
<modules>
<module>deployment</module>
<module>runtime</module>
</modules>
</project>

34
arc/runtime/pom.xml Normal file
View File

@@ -0,0 +1,34 @@
<?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-weld</artifactId>
<groupId>org.jboss.shamrock</groupId>
<version>1.0.0.Alpha1-SNAPSHOT</version>
<relativePath>../</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>shamrock-arc-runtime</artifactId>
<dependencies>
<dependency>
<groupId>org.jboss.protean.arc</groupId>
<artifactId>arc-runtime</artifactId>
</dependency>
<dependency>
<groupId>org.jboss.shamrock</groupId>
<artifactId>shamrock-core-runtime</artifactId>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<artifactId>maven-dependency-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>

View File

@@ -0,0 +1,69 @@
package org.jboss.shamrock.arc.runtime;
import java.lang.annotation.Annotation;
import org.jboss.protean.arc.Arc;
import org.jboss.protean.arc.ArcContainer;
import org.jboss.protean.arc.InstanceHandle;
import org.jboss.shamrock.runtime.BeanContainer;
import org.jboss.shamrock.runtime.ContextObject;
import org.jboss.shamrock.runtime.InjectionFactory;
import org.jboss.shamrock.runtime.InjectionInstance;
import org.jboss.shamrock.runtime.RuntimeInjector;
/**
*
* @author Martin Kouba
*/
public class ArcDeploymentTemplate {
@ContextObject("arc.container")
public ArcContainer getContainer() throws Exception {
ArcContainer container = Arc.container();
return container;
}
@ContextObject("bean.container")
public BeanContainer initBeanContainer(ArcContainer container) throws Exception {
return new BeanContainer() {
@Override
public <T> T instance(Class<T> type, Annotation... qualifiers) {
InstanceHandle<T> handle = container.instance(type, qualifiers);
if (!handle.isAvailable()) {
throw new IllegalStateException(type + " instance not available in container: " + container);
}
return handle.get();
}
};
}
public void setupInjection(ArcContainer container) {
RuntimeInjector.setFactory(new InjectionFactory() {
@Override
public <T> InjectionInstance<T> create(Class<T> type) {
InstanceHandle<T> instance = container.instance(type);
if (instance.isAvailable()) {
return new InjectionInstance<T>() {
@Override
public T newInstance() {
return instance.get();
}
};
} else {
return new InjectionInstance<T>() {
@Override
public T newInstance() {
try {
return type.newInstance();
} catch (Exception e) {
throw new RuntimeException(e);
}
}
};
}
}
});
}
}

View File

@@ -1,4 +1,4 @@
package org.jboss.shamrock.weld.deployment;
package org.jboss.shamrock.deployment;
import org.jboss.jandex.IndexView;

View File

@@ -1,4 +1,4 @@
package org.jboss.shamrock.weld.deployment;
package org.jboss.shamrock.deployment;
import java.util.ArrayList;
import java.util.List;
@@ -7,10 +7,6 @@ import javax.inject.Inject;
import org.jboss.jandex.CompositeIndex;
import org.jboss.jandex.IndexView;
import org.jboss.shamrock.deployment.ApplicationArchive;
import org.jboss.shamrock.deployment.ArchiveContext;
import org.jboss.shamrock.deployment.ProcessorContext;
import org.jboss.shamrock.deployment.ResourceProcessor;
public class BeanArchiveProcessor implements ResourceProcessor {

View File

@@ -0,0 +1,19 @@
package org.jboss.shamrock.deployment;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
public class BeanDeployment {
private final List<Class<?>> additionalBeans = new ArrayList<>();
public void addAdditionalBean(Class<?> ... beanClass) {
additionalBeans.addAll(Arrays.asList(beanClass));
}
public List<Class<?>> getAdditionalBeans() {
return additionalBeans;
}
}

View File

@@ -1,25 +1,23 @@
package org.jboss.shamrock.weld.deployment;
package org.jboss.shamrock.deployment;
import java.util.Arrays;
import java.util.HashSet;
import java.util.Set;
import org.jboss.shamrock.deployment.InjectionProvider;
public class BeanDeploymentInjectionProvider implements InjectionProvider {
public class WeldInjectionProvider implements InjectionProvider {
private final BeanDeployment deployment = new BeanDeployment();
private final WeldDeployment deployment = new WeldDeployment();
private final BeanArchiveIndex beanArchiveIndex = new BeanArchiveIndex();
@Override
public Set<Class<?>> getProvidedTypes() {
return new HashSet<>(Arrays.asList(WeldDeployment.class, BeanArchiveIndex.class));
return new HashSet<>(Arrays.asList(BeanDeployment.class, BeanArchiveIndex.class));
}
@Override
public <T> T getInstance(Class<T> type) {
if (type == WeldDeployment.class) {
if(type == BeanDeployment.class) {
return (T) deployment;
}
if (type == BeanArchiveIndex.class) {

View File

@@ -192,6 +192,11 @@ public class BuildTimeGenerator {
output.writeClass(applicationClass, name, classData);
}
@Override
public void createResource(String name, byte[] data) throws IOException {
output.writeResource(name, data);
}
@Override
public void addByteCodeTransformer(Function<String, Function<ClassVisitor, ClassVisitor>> visitorFunction) {
bytecodeTransformers.add(visitorFunction);

View File

@@ -16,6 +16,9 @@ public interface ClassOutput {
*/
void writeClass(boolean applicationClass, String className, byte[] data) throws IOException;
void writeResource(String name, byte[] data) throws IOException;
//TODO: we should not need both these classes
static org.jboss.protean.gizmo.ClassOutput gizmoAdaptor(ClassOutput out, boolean applicationClass) {
return new org.jboss.protean.gizmo.ClassOutput() {

View File

@@ -4,5 +4,7 @@ public class CoreSetup implements ShamrockSetup {
@Override
public void setup(SetupContext context) {
context.addInjectionProvider(new ConfigInjectionProvider());
context.addInjectionProvider(new BeanDeploymentInjectionProvider());
context.addResourceProcessor(new BeanArchiveProcessor());
}
}

View File

@@ -50,6 +50,14 @@ public interface ProcessorContext {
*/
void addGeneratedClass(boolean applicationClass, String name, byte[] classData) throws IOException;
/**
* Creates a resources with the provided contents
* @param name
* @param data
* @throws IOException
*/
void createResource(String name, byte[] data) throws IOException;
/**
* Adds a bytecode transformer that can transform application classes.
* <p>

View File

@@ -12,6 +12,7 @@ public class RuntimePriority {
public static final int HEALTH_DEPLOYMENT = 260;
public static final int WELD_DEPLOYMENT = 300;
public static final int JAXRS_DEPLOYMENT = 350;
public static final int ARC_DEPLOYMENT = 300;
public static final int UNDERTOW_DEPLOY = 400;
public static final int UNDERTOW_START = 500;

View File

@@ -1,19 +1,19 @@
package org.jboss.shamrock.runner;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.lang.reflect.AccessibleObject;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.io.InputStream;
import java.net.URL;
import java.net.URLConnection;
import java.net.URLStreamHandler;
import java.nio.file.Files;
import java.nio.file.Path;
import java.security.AccessController;
import java.security.PrivilegedActionException;
import java.security.PrivilegedExceptionAction;
import java.security.ProtectionDomain;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
@@ -27,13 +27,13 @@ import org.objectweb.asm.ClassReader;
import org.objectweb.asm.ClassVisitor;
import org.objectweb.asm.ClassWriter;
import sun.misc.Unsafe;
public class RuntimeClassLoader extends ClassLoader implements ClassOutput, Consumer<List<Function<String, Function<ClassVisitor, ClassVisitor>>>> {
private final Map<String, byte[]> appClasses = new HashMap<>();
private final Set<String> frameworkClasses = new HashSet<>();
private final Map<String, byte[]> resources = new HashMap<>();
private volatile List<Function<String, Function<ClassVisitor, ClassVisitor>>> functions = null;
private final Path applicationClasses;
@@ -46,6 +46,31 @@ public class RuntimeClassLoader extends ClassLoader implements ClassOutput, Cons
this.applicationClasses = applicationClasses;
}
@Override
public Enumeration<URL> getResources(String name) throws IOException {
// TODO some superugly hack for bean provider
byte[] data = resources.get(name);
if (data != null) {
URL url = new URL(null, "shamrock:" + name + "/", new URLStreamHandler() {
@Override
protected URLConnection openConnection(final URL u) throws IOException {
return new URLConnection(u) {
@Override
public void connect() throws IOException {
}
@Override
public InputStream getInputStream() throws IOException {
return new ByteArrayInputStream(resources.get(name));
}
};
}
});
return Collections.enumeration(Collections.singleton(url));
}
return super.getResources(name);
}
@Override
protected Class<?> loadClass(String name, boolean resolve) throws ClassNotFoundException {
Class<?> ex = findLoadedClass(name);
@@ -137,8 +162,12 @@ public class RuntimeClassLoader extends ClassLoader implements ClassOutput, Cons
}
}
@Override
public void accept(List<Function<String, Function<ClassVisitor, ClassVisitor>>> functions) {
this.functions = functions;
}
public void writeResource(String name, byte[] data) throws IOException {
resources.put(name, data);
}
}

View File

@@ -115,5 +115,10 @@ public class BytecodeRecorderTestCase {
public void writeClass(boolean applicationClass, String className, byte[] data) throws IOException {
tcl.write(className, data);
}
@Override
public void writeResource(String name, byte[] data) throws IOException {
throw new UnsupportedOperationException();
}
}
}

View File

@@ -0,0 +1,9 @@
package org.jboss.shamrock.runtime;
import java.lang.annotation.Annotation;
public interface BeanContainer {
<T> T instance(Class<T> type, Annotation... qualifiers);
}

View File

@@ -17,11 +17,6 @@
<artifactId>shamrock-undertow-deployment</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.jboss.shamrock</groupId>
<artifactId>shamrock-weld-deployment</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.jboss.shamrock</groupId>
<artifactId>shamrock-jaxrs-deployment</artifactId>
@@ -131,6 +126,45 @@
</plugins>
</build>
</profile>
<profile>
<id>weld</id>
<activation>
<property>
<name>!arc</name>
</property>
</activation>
<dependencies>
<dependency>
<groupId>org.jboss.shamrock</groupId>
<artifactId>shamrock-weld-deployment</artifactId>
<scope>provided</scope>
</dependency>
</dependencies>
</profile>
<profile>
<id>arc</id>
<activation>
<property>
<name>arc</name>
<value>true</value>
</property>
</activation>
<properties>
<!-- https://github.com/mkouba/smallrye-health/tree/no-private-injection -->
<smallrye-health.version>1.0.2-SNAPSHOT</smallrye-health.version>
<!-- https://github.com/mkouba/smallrye-metrics/tree/no-private-injection -->
<smallrye-metrics.version>1.1-SNAPSHOT</smallrye-metrics.version>
</properties>
<dependencies>
<dependency>
<groupId>org.jboss.shamrock</groupId>
<artifactId>shamrock-arc-deployment</artifactId>
<scope>provided</scope>
</dependency>
</dependencies>
</profile>
</profiles>
</project>

View File

@@ -13,7 +13,7 @@ import javax.servlet.http.HttpServletResponse;
public class InjectionServlet extends HttpServlet {
@Inject
private MessageBean messageBean;
MessageBean messageBean;
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException {

View File

@@ -1,9 +1,8 @@
package org.jboss.shamrock.example;
import javax.enterprise.context.ApplicationScoped;
import java.util.Optional;
import javax.enterprise.context.ApplicationScoped;
import javax.inject.Inject;
import org.eclipse.microprofile.config.Config;
@@ -12,7 +11,7 @@ import org.eclipse.microprofile.config.Config;
public class MessageBean {
@Inject
private Config config;
Config config;
public String getMessage() {
Optional<String> message = config.getOptionalValue("message", String.class);

View File

@@ -3,13 +3,17 @@ package org.jboss.shamrock.example;
import java.util.Map;
import java.util.Optional;
import javax.enterprise.context.Dependent;
import org.eclipse.microprofile.health.Health;
import org.eclipse.microprofile.health.HealthCheck;
import org.eclipse.microprofile.health.HealthCheckResponse;
@Dependent
@Health
public class SimpleHealthCheck implements HealthCheck {
@Override
@Override
public HealthCheckResponse call() {
return new HealthCheckResponse() {
@Override

View File

@@ -10,19 +10,19 @@ import org.jboss.shamrock.example.MessageBean;
@Path("/test")
public class InjectionResource {
@Inject
private MessageBean messageBean;
@Inject
MessageBean messageBean;
@GET
@Counted(monotonic = true)
public String getTest() {
return "TEST";
}
@GET
@Counted(monotonic = true)
public String getTest() {
return "TEST";
}
@GET
@Path("/injection")
public String get() {
return messageBean.getMessage();
}
@GET
@Path("/injection")
public String get() {
return messageBean.getMessage();
}
}

View File

@@ -17,10 +17,6 @@
<groupId>org.jboss.shamrock</groupId>
<artifactId>shamrock-core-deployment</artifactId>
</dependency>
<dependency>
<groupId>org.jboss.shamrock</groupId>
<artifactId>shamrock-weld-deployment</artifactId>
</dependency>
<dependency>
<groupId>org.jboss.shamrock</groupId>
<artifactId>shamrock-undertow-deployment</artifactId>

View File

@@ -3,18 +3,20 @@ package org.jboss.shamrock.health;
import javax.inject.Inject;
import org.jboss.shamrock.deployment.ArchiveContext;
import org.jboss.shamrock.deployment.BeanDeployment;
import org.jboss.shamrock.deployment.ProcessorContext;
import org.jboss.shamrock.deployment.ResourceProcessor;
import org.jboss.shamrock.deployment.ShamrockConfig;
import org.jboss.shamrock.health.runtime.HealthServlet;
import org.jboss.shamrock.undertow.ServletData;
import org.jboss.shamrock.undertow.ServletDeployment;
import org.jboss.shamrock.weld.deployment.WeldDeployment;
import io.smallrye.health.SmallRyeHealthReporter;
class HealthProcessor implements ResourceProcessor {
@Inject
private WeldDeployment weldDeployment;
private BeanDeployment beanDeployment;
@Inject
private ShamrockConfig config;
@@ -27,7 +29,8 @@ 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(HealthServlet.class);
beanDeployment.addAdditionalBean(SmallRyeHealthReporter.class);
beanDeployment.addAdditionalBean(HealthServlet.class);
}
@Override

View File

@@ -18,7 +18,7 @@ import io.smallrye.health.SmallRyeHealthReporter;
public class HealthServlet extends HttpServlet {
@Inject
private SmallRyeHealthReporter reporter;
SmallRyeHealthReporter reporter;
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {

View File

@@ -1,7 +1,6 @@
package org.jboss.shamrock.jaxrs.runtime.graal;
import javax.enterprise.inject.se.SeContainer;
import org.jboss.shamrock.runtime.BeanContainer;
import org.jboss.shamrock.runtime.ContextObject;
/**
@@ -9,7 +8,7 @@ import org.jboss.shamrock.runtime.ContextObject;
*/
public class JaxrsTemplate {
public void setupIntegration(@ContextObject("weld.container")SeContainer container) {
public void setupIntegration(@ContextObject("bean.container") BeanContainer container) {
ShamrockInjectorFactory.CONTAINER = container;
}

View File

@@ -2,7 +2,6 @@ package org.jboss.shamrock.jaxrs.runtime.graal;
import java.lang.reflect.Constructor;
import javax.enterprise.inject.Instance;
import javax.ws.rs.WebApplicationException;
import org.jboss.resteasy.spi.ApplicationException;
@@ -33,8 +32,7 @@ public class ShamrockConstructorInjector implements ConstructorInjector {
if (ShamrockInjectorFactory.CONTAINER == null) {
return delegate.construct(request, response);
}
Instance object = ShamrockInjectorFactory.CONTAINER.select(this.ctor.getDeclaringClass());
return object.get();
return ShamrockInjectorFactory.CONTAINER.instance(this.ctor.getDeclaringClass());
}
@Override

View File

@@ -2,19 +2,18 @@ package org.jboss.shamrock.jaxrs.runtime.graal;
import java.lang.reflect.Constructor;
import javax.enterprise.inject.se.SeContainer;
import org.jboss.resteasy.core.InjectorFactoryImpl;
import org.jboss.resteasy.spi.ConstructorInjector;
import org.jboss.resteasy.spi.ResteasyProviderFactory;
import org.jboss.resteasy.spi.metadata.ResourceConstructor;
import org.jboss.shamrock.runtime.BeanContainer;
/**
* Created by bob on 7/31/18.
*/
public class ShamrockInjectorFactory extends InjectorFactoryImpl {
public static volatile SeContainer CONTAINER = null;
public static volatile BeanContainer CONTAINER = null;
@Override
public ConstructorInjector createConstructor(Constructor constructor, ResteasyProviderFactory providerFactory) {

View File

@@ -36,7 +36,6 @@ 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;
@@ -169,6 +168,16 @@ public class BuildMojo extends AbstractMojo {
out.write(data);
}
}
@Override
public void writeResource(String name, byte[] data) throws IOException {
File file = new File(wiringClassesDirectory, name);
file.getParentFile().mkdirs();
try (FileOutputStream out = new FileOutputStream(file)) {
out.write(data);
}
}
}, runnerClassLoader, useStaticInit);
ClassLoader old = Thread.currentThread().getContextClassLoader();
try {

View File

@@ -17,10 +17,6 @@
<groupId>org.jboss.shamrock</groupId>
<artifactId>shamrock-core-deployment</artifactId>
</dependency>
<dependency>
<groupId>org.jboss.shamrock</groupId>
<artifactId>shamrock-weld-deployment</artifactId>
</dependency>
<dependency>
<groupId>org.jboss.shamrock</groupId>
<artifactId>shamrock-undertow-deployment</artifactId>

View File

@@ -3,15 +3,19 @@ package org.jboss.shamrock.metrics;
import java.util.Collection;
import javax.inject.Inject;
import javax.interceptor.Interceptor;
import org.eclipse.microprofile.metrics.annotation.Counted;
import org.jboss.jandex.AnnotationInstance;
import org.jboss.jandex.AnnotationTarget;
import org.jboss.jandex.AnnotationTarget.Kind;
import org.jboss.jandex.ClassInfo;
import org.jboss.jandex.DotName;
import org.jboss.jandex.IndexView;
import org.jboss.jandex.MethodInfo;
import org.jboss.shamrock.deployment.ArchiveContext;
import org.jboss.shamrock.deployment.BeanArchiveIndex;
import org.jboss.shamrock.deployment.BeanDeployment;
import org.jboss.shamrock.deployment.ProcessorContext;
import org.jboss.shamrock.deployment.ResourceProcessor;
import org.jboss.shamrock.deployment.RuntimePriority;
@@ -21,8 +25,6 @@ import org.jboss.shamrock.metrics.runtime.MetricsDeploymentTemplate;
import org.jboss.shamrock.metrics.runtime.MetricsServlet;
import org.jboss.shamrock.undertow.ServletData;
import org.jboss.shamrock.undertow.ServletDeployment;
import org.jboss.shamrock.weld.deployment.BeanArchiveIndex;
import org.jboss.shamrock.weld.deployment.WeldDeployment;
import io.smallrye.metrics.MetricProducer;
import io.smallrye.metrics.MetricRegistries;
@@ -40,7 +42,7 @@ public class MetricsProcessor implements ResourceProcessor {
@Inject
private WeldDeployment weldDeployment;
private BeanDeployment beanDeployment;
@Inject
private ShamrockConfig config;
@@ -57,16 +59,16 @@ public class MetricsProcessor implements ResourceProcessor {
servletData.getMapings().add(config.getConfig("metrics.path", "/metrics"));
servletDeployment.addServlet(servletData);
weldDeployment.addAdditionalBean(MetricProducer.class,
beanDeployment.addAdditionalBean(MetricProducer.class,
MetricNameFactory.class,
MetricRegistries.class);
weldDeployment.addAdditionalBean(MetricsInterceptor.class,
beanDeployment.addAdditionalBean(MetricsInterceptor.class,
MeteredInterceptor.class,
CountedInterceptor.class,
TimedInterceptor.class);
weldDeployment.addAdditionalBean(MetricsRequestHandler.class, MetricsServlet.class);
beanDeployment.addAdditionalBean(MetricsRequestHandler.class, MetricsServlet.class);
//weldDeployment.addInterceptor(MetricsInterceptor.class);
//weldDeployment.addInterceptor(MeteredInterceptor.class);
//weldDeployment.addInterceptor(CountedInterceptor.class);
@@ -86,6 +88,12 @@ public class MetricsProcessor implements ResourceProcessor {
for (AnnotationInstance anno : annos) {
AnnotationTarget target = anno.target();
// TODO ugly hack to exclude metrics interceptors
if (Kind.CLASS.equals(target.kind())
&& target.asClass().classAnnotations().stream().anyMatch(a -> a.name().equals(DotName.createSimple(Interceptor.class.getName())))) {
continue;
}
MethodInfo methodInfo = target.asMethod();
ClassInfo classInfo = methodInfo.declaringClass();

View File

@@ -3,25 +3,18 @@ package org.jboss.shamrock.metrics.runtime;
import java.lang.management.GarbageCollectorMXBean;
import java.lang.management.ManagementFactory;
import java.lang.management.MemoryMXBean;
import java.lang.management.MemoryPoolMXBean;
import java.lang.management.ThreadMXBean;
import java.lang.reflect.AnnotatedElement;
import java.lang.reflect.Member;
import java.lang.reflect.Method;
import java.util.Arrays;
import java.util.List;
import javax.enterprise.inject.se.SeContainer;
import org.eclipse.microprofile.metrics.Metadata;
import org.eclipse.microprofile.metrics.MetricRegistry;
import org.eclipse.microprofile.metrics.MetricType;
import org.jboss.shamrock.runtime.BeanContainer;
import org.jboss.shamrock.runtime.ContextObject;
import io.smallrye.metrics.MetricRegistries;
import io.smallrye.metrics.app.CounterImpl;
import io.smallrye.metrics.interceptors.MetricResolver;
import org.eclipse.microprofile.metrics.Metadata;
import org.eclipse.microprofile.metrics.MetricRegistry;
import org.eclipse.microprofile.metrics.MetricType;
import org.eclipse.microprofile.metrics.annotation.Counted;
import org.eclipse.microprofile.metrics.annotation.Metric;
import org.jboss.shamrock.runtime.ContextObject;
/**
* Created by bob on 7/30/18.
@@ -108,7 +101,7 @@ public class MetricsDeploymentTemplate {
}
public void createRegistries(@ContextObject("weld.container") SeContainer container) {
public void createRegistries(@ContextObject("bean.container") BeanContainer container) {
System.err.println("creating registries");
MetricRegistries.get(MetricRegistry.Type.APPLICATION);
MetricRegistries.get(MetricRegistry.Type.BASE);
@@ -117,6 +110,6 @@ public class MetricsDeploymentTemplate {
//HACK: registration is does via statics, but cleanup is done via pre destroy
//however if the bean is not used it will not be created, so no cleanup will be done
//we force bean creation here to make sure the container can restart correctly
container.select(MetricRegistries.class).iterator().next().getApplicationRegistry();
container.instance(MetricRegistries.class).getApplicationRegistry();
}
}

View File

@@ -19,7 +19,7 @@ import io.smallrye.metrics.MetricsRequestHandler;
public class MetricsServlet extends HttpServlet {
@Inject
private MetricsRequestHandler metricsHandler;
MetricsRequestHandler metricsHandler;
@Override
protected void doOptions(HttpServletRequest req, HttpServletResponse resp) throws IOException {

24
pom.xml
View File

@@ -15,7 +15,7 @@
<packaging>pom</packaging>
<properties>
<version.org.jandex>2.0.5.Final</version.org.jandex>
<version.org.jandex>2.0.6.Final-SNAPSHOT</version.org.jandex>
<resteasy.version>3.5.1.Final</resteasy.version>
<weld-se-core.version>3.0.4.Final</weld-se-core.version>
<undertow.version>2.0.12.Final</undertow.version>
@@ -46,6 +46,7 @@
<jackson.version>2.9.5</jackson.version>
<commons-beanutils-core.version>1.8.3</commons-beanutils-core.version>
<commons-logging.version>1.2</commons-logging.version>
<arc.version>1.0.0-SNAPSHOT</arc.version>
</properties>
<modules>
@@ -61,6 +62,7 @@
<module>examples</module>
<module>jpa</module>
<module>gizmo</module>
<module>arc</module>
</modules>
<build>
<pluginManagement>
@@ -211,6 +213,16 @@
<artifactId>shamrock-jpa-runtime</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.jboss.shamrock</groupId>
<artifactId>shamrock-arc-deployment</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.jboss.shamrock</groupId>
<artifactId>shamrock-arc-runtime</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.jboss.protean.gizmo</groupId>
@@ -433,6 +445,16 @@
<artifactId>weld-se-core</artifactId>
<version>${weld-se-core.version}</version>
</dependency>
<dependency>
<groupId>org.jboss.protean.arc</groupId>
<artifactId>arc-processor</artifactId>
<version>${arc.version}</version>
</dependency>
<dependency>
<groupId>org.jboss.protean.arc</groupId>
<artifactId>arc-runtime</artifactId>
<version>${arc.version}</version>
</dependency>
<dependency>
<groupId>org.jboss.xnio</groupId>
<artifactId>xnio-api</artifactId>

View File

@@ -7,6 +7,8 @@ import javax.inject.Inject;
import org.jboss.jandex.ClassInfo;
import org.jboss.jandex.IndexView;
import org.jboss.shamrock.deployment.ArchiveContext;
import org.jboss.shamrock.deployment.BeanArchiveIndex;
import org.jboss.shamrock.deployment.BeanDeployment;
import org.jboss.shamrock.deployment.ProcessorContext;
import org.jboss.shamrock.deployment.ResourceProcessor;
import org.jboss.shamrock.deployment.RuntimePriority;
@@ -18,15 +20,16 @@ import io.smallrye.config.inject.ConfigProducer;
public class WeldAnnotationProcessor implements ResourceProcessor {
@Inject
private WeldDeployment weldDeployment;
private BeanDeployment beanDeployment;
@Inject
private BeanArchiveIndex beanArchiveIndex;
@Override
public void process(ArchiveContext archiveContext, ProcessorContext processorContext) throws Exception {
weldDeployment.addAdditionalBean(ConfigProducer.class);
IndexView index = beanArchiveIndex.getIndex();
//make config injectable
beanDeployment.addAdditionalBean(ConfigProducer.class);
try (BytecodeRecorder recorder = processorContext.addStaticInitTask(RuntimePriority.WELD_DEPLOYMENT)) {
WeldDeploymentTemplate template = recorder.getRecordingProxy(WeldDeploymentTemplate.class);
SeContainerInitializer init = template.createWeld();
@@ -35,13 +38,11 @@ public class WeldAnnotationProcessor implements ResourceProcessor {
template.addClass(init, recorder.classProxy(name));
processorContext.addReflectiveClass(true, true, name);
}
for (Class<?> clazz : weldDeployment.getAdditionalBeans()) {
for (Class<?> clazz : beanDeployment.getAdditionalBeans()) {
template.addClass(init, clazz);
}
for (Class<?> clazz : weldDeployment.getInterceptors()) {
template.addInterceptor(init, clazz);
}
SeContainer weld = template.doBoot(null, init);
template.initBeanContainer(weld);
template.setupInjection(null, weld);
}

View File

@@ -1,28 +0,0 @@
package org.jboss.shamrock.weld.deployment;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
public class WeldDeployment {
private final List<Class<?>> additionalBeans = new ArrayList<>();
private final List<Class<?>> interceptors = new ArrayList<>();
public void addAdditionalBean(Class<?> ... beanClass) {
additionalBeans.addAll(Arrays.asList(beanClass));
}
List<Class<?>> getAdditionalBeans() {
return additionalBeans;
}
public void addInterceptor(Class<?> interceptorClass) {
this.interceptors.add( interceptorClass);
}
List<Class<?>> getInterceptors() {
return this.interceptors;
}
}

View File

@@ -6,9 +6,7 @@ import org.jboss.shamrock.deployment.ShamrockSetup;
public class WeldSetup implements ShamrockSetup {
@Override
public void setup(SetupContext context) {
context.addInjectionProvider(new WeldInjectionProvider());
context.addResourceProcessor(new WeldAnnotationProcessor());
context.addResourceProcessor(new BeanArchiveProcessor());
context.addApplicationArchiveMarker("META-INF/beans.xml");
context.addApplicationArchiveMarker("META-INF/services/javax.enterprise.inject.spi.Extension");
}

View File

@@ -2,6 +2,7 @@ package org.jboss.shamrock.weld.runtime;
import java.io.Closeable;
import java.io.IOException;
import java.lang.annotation.Annotation;
import java.lang.reflect.Field;
import java.net.URL;
import java.net.URLConnection;
@@ -15,6 +16,7 @@ import javax.enterprise.inject.se.SeContainer;
import javax.enterprise.inject.se.SeContainerInitializer;
import javax.enterprise.inject.spi.Bean;
import org.jboss.shamrock.runtime.BeanContainer;
import org.jboss.shamrock.runtime.ContextObject;
import org.jboss.shamrock.runtime.InjectionFactory;
import org.jboss.shamrock.runtime.InjectionInstance;
@@ -122,4 +124,15 @@ public class WeldDeploymentTemplate {
});
}
@ContextObject("bean.container")
public BeanContainer initBeanContainer(SeContainer container) throws Exception {
return new BeanContainer() {
@Override
public <T> T instance(Class<T> type, Annotation... qualifiers) {
return container.select(type, qualifiers).get();
}
};
}
}