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

SmallRye Context Propagation 1.0.16 #11410

Merged
merged 5 commits into from Oct 28, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
4 changes: 2 additions & 2 deletions bom/application/pom.xml
Expand Up @@ -41,9 +41,9 @@
<smallrye-open-api.version>2.0.13</smallrye-open-api.version>
<smallrye-graphql.version>1.0.14</smallrye-graphql.version>
<smallrye-opentracing.version>1.3.4</smallrye-opentracing.version>
<smallrye-fault-tolerance.version>4.3.1</smallrye-fault-tolerance.version>
<smallrye-fault-tolerance.version>4.3.2</smallrye-fault-tolerance.version>
<smallrye-jwt.version>2.3.1</smallrye-jwt.version>
<smallrye-context-propagation.version>1.0.13</smallrye-context-propagation.version>
<smallrye-context-propagation.version>1.0.19</smallrye-context-propagation.version>
<smallrye-reactive-streams-operators.version>1.0.13</smallrye-reactive-streams-operators.version>
<smallrye-converter-api.version>1.2.2</smallrye-converter-api.version>
<smallrye-reactive-messaging.version>2.4.0</smallrye-reactive-messaging.version>
Expand Down
1 change: 1 addition & 0 deletions core/runtime/pom.xml
Expand Up @@ -119,6 +119,7 @@
<configuration>
<parentFirstArtifacts>
<parentFirstArtifact>io.quarkus:quarkus-bootstrap-runner</parentFirstArtifact>
<parentFirstArtifact>io.smallrye.common:smallrye-common-io</parentFirstArtifact>
<parentFirstArtifact>org.wildfly.common:wildfly-common</parentFirstArtifact>
<parentFirstArtifact>org.graalvm.sdk:graal-sdk</parentFirstArtifact>
<parentFirstArtifact>org.graalvm.nativeimage:svm</parentFirstArtifact>
Expand Down
@@ -0,0 +1,85 @@
package io.quarkus.arc.test.unproxyable;

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertTrue;

import java.util.function.Consumer;

import javax.enterprise.context.ApplicationScoped;
import javax.enterprise.inject.Vetoed;

import org.jboss.shrinkwrap.api.ShrinkWrap;
import org.jboss.shrinkwrap.api.spec.JavaArchive;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.RegisterExtension;

import io.quarkus.arc.Arc;
import io.quarkus.arc.InstanceHandle;
import io.quarkus.arc.deployment.BeanRegistrarBuildItem;
import io.quarkus.arc.processor.BeanRegistrar;
import io.quarkus.builder.BuildChainBuilder;
import io.quarkus.builder.BuildContext;
import io.quarkus.builder.BuildStep;
import io.quarkus.gizmo.MethodDescriptor;
import io.quarkus.gizmo.ResultHandle;
import io.quarkus.test.QuarkusUnitTest;

public class SynthProxiableBeanWithoutNoArgConstructorTest {

@RegisterExtension
static final QuarkusUnitTest config = new QuarkusUnitTest()
.setArchiveProducer(() -> ShrinkWrap.create(JavaArchive.class)
.addClasses(SynthBean.class))
.addBuildChainCustomizer(buildCustomizer());

static Consumer<BuildChainBuilder> buildCustomizer() {
return new Consumer<BuildChainBuilder>() {

@Override
public void accept(BuildChainBuilder builder) {
builder.addBuildStep(new BuildStep() {

@Override
public void execute(BuildContext context) {
context.produce(new BeanRegistrarBuildItem(new BeanRegistrar() {
@Override
public void register(RegistrationContext context) {
context.configure(SynthBean.class)
.scope(ApplicationScoped.class)
.types(SynthBean.class)
.unremovable()
.creator(mc -> {
ResultHandle ret = mc.newInstance(
MethodDescriptor.ofConstructor(SynthBean.class, String.class),
mc.load("foo"));
mc.returnValue(ret);
})
.done();
}
}));
}
}).produces(BeanRegistrarBuildItem.class).build();
}
};
}

@Test
public void testSyntheticBean() {
InstanceHandle<SynthBean> instance = Arc.container().instance(SynthBean.class);
assertTrue(instance.isAvailable());
assertEquals("foo", instance.get().getString());
}

@Vetoed
static class SynthBean {
private String s;

public SynthBean(String s) {
this.s = s;
}

public String getString() {
return s;
}
}
}
Expand Up @@ -23,6 +23,7 @@
import io.quarkus.deployment.util.ServiceUtil;
import io.quarkus.smallrye.context.runtime.SmallRyeContextPropagationProvider;
import io.quarkus.smallrye.context.runtime.SmallRyeContextPropagationRecorder;
import io.smallrye.context.SmallRyeManagedExecutor;

/**
* The deployment processor for MP-CP applications
Expand Down Expand Up @@ -76,8 +77,9 @@ void build(SmallRyeContextPropagationRecorder recorder,

// Synthetic bean for ManagedExecutor
syntheticBeans.produce(
SyntheticBeanBuildItem.configure(ManagedExecutor.class)
SyntheticBeanBuildItem.configure(SmallRyeManagedExecutor.class)
.scope(ApplicationScoped.class)
.addType(ManagedExecutor.class)
.defaultBean()
.unremovable()
.supplier(recorder.initializeManagedExecutor(executorBuildItem.getExecutorProxy()))
Expand Down
Expand Up @@ -7,15 +7,17 @@
import org.eclipse.microprofile.context.ThreadContext;

import io.quarkus.arc.DefaultBean;
import io.smallrye.context.SmallRyeThreadContext;

@Dependent
public class SmallRyeContextPropagationProvider {

@Produces
@Singleton
@DefaultBean
public ThreadContext getAllThreadContext() {
return ThreadContext.builder().propagated(ThreadContext.ALL_REMAINING).cleared().unchanged().build();
public SmallRyeThreadContext getAllThreadContext() {
return (SmallRyeThreadContext) ThreadContext.builder().propagated(ThreadContext.ALL_REMAINING).cleared().unchanged()
.build();
}

}
Expand Up @@ -789,6 +789,37 @@ static void validateBean(BeanInfo bean, List<Throwable> errors, List<BeanDeploym
}
}
}
} else if (bean.isSynthetic()) {
// this is for synthetic beans that need to be proxied but their classes don't have no-args constructor
ClassInfo beanClass = getClassByName(bean.getDeployment().getBeanArchiveIndex(), bean.getBeanClass());
MethodInfo noArgsConstructor = beanClass.method(Methods.INIT);
if (bean.getScope().isNormal() && !Modifier.isInterface(beanClass.flags()) && noArgsConstructor == null) {
if (bean.getDeployment().transformUnproxyableClasses) {
DotName superName = beanClass.superName();
if (!DotNames.OBJECT.equals(superName)) {
ClassInfo superClass = bean.getDeployment().getBeanArchiveIndex().getClassByName(beanClass.superName());
if (superClass == null || !superClass.hasNoArgsConstructor()) {
// Bean class extends a class without no-args constructor
// It is not possible to generate a no-args constructor reliably
superName = null;
}
}
if (superName != null) {
String superClassName = superName.toString().replace('.', '/');
bytecodeTransformerConsumer.accept(new BytecodeTransformer(beanClass.name().toString(),
new NoArgConstructorTransformFunction(superClassName)));
} else {
errors.add(new DeploymentException(
"It's not possible to add a synthetic constructor with no parameters to the unproxyable bean class: "
+
beanClass));
}
} else {
errors.add(new DeploymentException(String
.format("Normal scoped beans must declare a non-private constructor with no parameters: %s",
bean)));
}
}
}
}

Expand Down
Expand Up @@ -8,6 +8,7 @@
import java.io.InputStream;
import java.io.InterruptedIOException;
import java.io.UncheckedIOException;
import java.lang.reflect.Method;
import java.net.MalformedURLException;
import java.net.URI;
import java.net.URISyntaxException;
Expand All @@ -18,6 +19,7 @@
import java.security.cert.Certificate;
import java.util.Enumeration;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.function.Function;
import java.util.jar.JarEntry;
Expand All @@ -30,7 +32,23 @@
*/
public class JarClassPathElement implements ClassPathElement {

private static final int JAVA_VERSION;

static {
int version = 8;
try {
Method versionMethod = Runtime.class.getMethod("version");
Object v = versionMethod.invoke(null);
List<Integer> list = (List<Integer>) v.getClass().getMethod("version").invoke(v);
version = list.get(0);
} catch (Exception e) {
//version 8
}
JAVA_VERSION = version;
}

private static final Logger log = Logger.getLogger(JarClassPathElement.class);
public static final String META_INF_VERSIONS = "META-INF/versions/";
private final File file;
private final URL jarPath;
private final Path root;
Expand Down Expand Up @@ -147,6 +165,26 @@ public Set<String> apply(JarFile jarFile) {
paths.add(entry.getName());
}
}
//multi release jars can add additional entries
if (JarFiles.isMultiRelease(jarFile)) {
Set<String> copy = new HashSet<>(paths);
for (String i : copy) {
if (i.startsWith(META_INF_VERSIONS)) {
String part = i.substring(META_INF_VERSIONS.length());
int slash = part.indexOf("/");
if (slash != -1) {
try {
int ver = Integer.parseInt(part.substring(0, slash));
if (ver <= JAVA_VERSION) {
paths.add(part.substring(slash + 1));
}
} catch (NumberFormatException e) {
log.debug("Failed to parse META-INF/versions entry", e);
}
}
}
}
}
return paths;
}
}));
Expand Down
4 changes: 4 additions & 0 deletions independent-projects/bootstrap/runner/pom.xml
Expand Up @@ -19,6 +19,10 @@
</description>

<dependencies>
<dependency>
<groupId>io.smallrye.common</groupId>
<artifactId>smallrye-common-io</artifactId>
</dependency>
<dependency>
<groupId>org.graalvm.sdk</groupId>
<artifactId>graal-sdk</artifactId>
Expand Down
@@ -1,5 +1,7 @@
package io.quarkus.bootstrap.runner;

import io.smallrye.common.io.jar.JarEntries;
import io.smallrye.common.io.jar.JarFiles;
import java.io.IOException;
import java.io.InputStream;
import java.net.MalformedURLException;
Expand All @@ -10,6 +12,8 @@
import java.security.CodeSource;
import java.security.ProtectionDomain;
import java.security.cert.Certificate;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;

Expand All @@ -20,7 +24,7 @@ public class JarResource implements ClassLoadingResource {

private final ManifestInfo manifestInfo;
private final Path jarPath;
private volatile ZipFile zipFile;
private volatile JarFile zipFile;

public JarResource(ManifestInfo manifestInfo, Path jarPath) {
this.manifestInfo = manifestInfo;
Expand Down Expand Up @@ -54,12 +58,17 @@ public byte[] getResourceData(String resource) {

@Override
public URL getResourceURL(String resource) {
ZipFile zipFile = file();
ZipEntry entry = zipFile.getEntry(resource);
JarFile zipFile = file();
JarEntry entry = zipFile.getJarEntry(resource);
if (entry == null) {
return null;
}
try {
String realName = JarEntries.getRealName(entry);
// Avoid ending the URL with / to avoid breaking compatibility
if (realName.endsWith("/")) {
realName = realName.substring(0, realName.length() - 1);
}
URI jarUri = jarPath.toUri();
return new URL("jar", null, jarUri.getScheme() + ":" + jarUri.getPath() + "!/" + resource);
} catch (MalformedURLException e) {
Expand Down Expand Up @@ -89,12 +98,12 @@ public ProtectionDomain getProtectionDomain(ClassLoader classLoader) {
return new ProtectionDomain(codesource, null, classLoader, null);
}

private ZipFile file() {
private JarFile file() {
if (zipFile == null) {
synchronized (this) {
if (zipFile == null) {
try {
return zipFile = new ZipFile(jarPath.toFile());
return zipFile = JarFiles.create(jarPath.toFile());
} catch (IOException e) {
throw new RuntimeException("Failed to open " + jarPath, e);
}
Expand Down
Expand Up @@ -29,6 +29,8 @@
*/
public class SerializedApplication {

public static final String META_INF_VERSIONS = "META-INF/versions/";

private static final int MAGIC = 0XF0315432;
private static final int VERSION = 1;

Expand Down Expand Up @@ -160,6 +162,20 @@ private static void writeJar(DataOutputStream out, Path jar) throws IOException
//looking at you h2
final int index = entry.getName().lastIndexOf('/');
dirs.add(entry.getName().substring(0, index));

if (entry.getName().startsWith(META_INF_VERSIONS)) {
//multi release jar
//we add all packages here
//they may no be relevant for some versions, but that is fine
String part = entry.getName().substring(META_INF_VERSIONS.length());
int slash = part.indexOf("/");
if (slash != -1) {
final int subIndex = part.lastIndexOf('/');
if (subIndex != slash) {
dirs.add(part.substring(slash + 1, subIndex));
}
}
}
}
}
if (hasDefaultPackge) {
Expand Down