Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Initial Arc support #9

Closed
wants to merge 3 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 30 additions & 0 deletions arc/deployment/pom.xml
Original file line number Diff line number Diff line change
@@ -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>
Original file line number Diff line number Diff line change
@@ -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);
}
}
}
}

}
Original file line number Diff line number Diff line change
@@ -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());
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
org.jboss.shamrock.arc.deployment.ArcSetup
19 changes: 19 additions & 0 deletions arc/pom.xml
Original file line number Diff line number Diff line change
@@ -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 changes: 34 additions & 0 deletions arc/runtime/pom.xml
Original file line number Diff line number Diff line change
@@ -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>
Original file line number Diff line number Diff line change
@@ -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);
}
}
};
}
}
});
}

}
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package org.jboss.shamrock.weld.deployment;
package org.jboss.shamrock.deployment;

import org.jboss.jandex.IndexView;

Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package org.jboss.shamrock.weld.deployment;
package org.jboss.shamrock.deployment;

import java.util.ArrayList;
import java.util.List;
Expand All @@ -7,10 +7,6 @@

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 {

Expand Down
Original file line number Diff line number Diff line change
@@ -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;
}

}
Original file line number Diff line number Diff line change
@@ -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) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -201,6 +201,11 @@ public void addGeneratedClass(boolean applicationClass, String name, byte[] clas
output.writeClass(applicationClass, name, classData);
}

@Override
public void addResource(String name, byte[] data) throws IOException {
output.writeResource(name, data);
}

@Override
public void addByteCodeTransformer(Function<String, Function<ClassVisitor, ClassVisitor>> visitorFunction) {
bytecodeTransformers.add(visitorFunction);
Expand Down
Loading