Skip to content

Commit 4aeed29

Browse files
Merge branch 'main' into docs/oidc-remove-renarde
2 parents 23f1d3e + 20ff061 commit 4aeed29

File tree

18 files changed

+268
-64
lines changed

18 files changed

+268
-64
lines changed

.github/workflows/preview.yml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -110,8 +110,11 @@ jobs:
110110
run: |
111111
find assets/images/posts/ -mindepth 1 -maxdepth 1 -type d -mtime +100 -exec rm -rf _site/{} \;
112112
find newsletter/ -mindepth 1 -maxdepth 1 -type d -mtime +100 -exec rm -rf _site/{} \;
113+
rm -rf _site/assets/stickers
113114
rm -rf _site/assets/images/worldtour/2023
115+
rm -rf _site/assets/images/worldtour/2024
114116
rm -rf _site/assets/images/desktopwallpapers
117+
rm -rf _site/assets/images/stickers
115118
116119
- name: Publishing to surge for preview
117120
id: deploy

bom/dev-ui/pom.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
<description>Dependency management for dev-ui. Importable by third party extension developers.</description>
1414

1515
<properties>
16-
<vaadin.version>24.8.5</vaadin.version>
16+
<vaadin.version>24.8.7</vaadin.version>
1717
<lit.version>3.3.1</lit.version>
1818
<lit-element.version>4.2.1</lit-element.version>
1919
<lit-html.version>3.3.1</lit-html.version>

core/deployment/src/main/java/io/quarkus/deployment/steps/CheckJVMparamsProcessor.java renamed to core/deployment/src/main/java/io/quarkus/deployment/steps/JVMUnsafeWarningsProcessor.java

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,12 @@
66
import io.quarkus.deployment.pkg.steps.NativeBuild;
77
import io.quarkus.runtime.JVMChecksRecorder;
88

9-
public class CheckJVMparamsProcessor {
9+
public class JVMUnsafeWarningsProcessor {
1010

1111
@BuildStep(onlyIfNot = NativeBuild.class)
12-
@Record(ExecutionTime.RUNTIME_INIT)
13-
public void recordJvmChecks(JVMChecksRecorder recorder) {
14-
recorder.check();
12+
@Record(ExecutionTime.STATIC_INIT) //We need this to trigger before Netty or other Unsafe users get to run: static init seems effective enough
13+
public void disableUnsafeRelatedWarnings(JVMChecksRecorder recorder) {
14+
recorder.disableUnsafeRelatedWarnings();
1515
}
16+
1617
}
Lines changed: 17 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,36 +1,29 @@
11
package io.quarkus.runtime;
22

3-
import java.lang.management.ManagementFactory;
4-
import java.lang.management.RuntimeMXBean;
5-
import java.util.List;
6-
7-
import org.jboss.logging.Logger;
3+
import java.lang.reflect.InvocationTargetException;
4+
import java.lang.reflect.Method;
85

96
import io.quarkus.runtime.annotations.Recorder;
107

118
@Recorder
129
public class JVMChecksRecorder {
1310

14-
public void check() {
15-
if (!isUnsafeMemoryAccessAllowed()) {
16-
Logger.getLogger("JVM").warn(
17-
"Unsafe memory access is not going to be allowed in future versions of the JVM. Since Java 24, the JVM will print a warning on boot (most likely shown above), but several Quarkus extensions still require it. "
18-
+
19-
"There is currently no need to worry: please add the `--sun-misc-unsafe-memory-access=allow` JVM argument to avoid these warnings. "
20-
+
21-
"We are working with the maintainers of those libraries to get this resolved in future versions; when this is done, we will remove the need for this argument.");
22-
}
23-
}
24-
25-
public static boolean isUnsafeMemoryAccessAllowed() {
11+
/**
12+
* This is a horrible hack to disable the Unsafe-related warnings that are printed on startup:
13+
* we know about the problem, we're working on it, and there's no need to print a warning scaring our
14+
* users with it.
15+
*/
16+
public void disableUnsafeRelatedWarnings() {
2617
if (Runtime.version().feature() < 24) {
27-
//Versions before Java 24 would not complain about the use of Unsafe.
28-
//Also, setting `--sun-misc-unsafe-memory-access=allow` isn't possible (not a valid argument) before Java 24.
29-
return true;
18+
return;
19+
}
20+
try {
21+
Class<?> unsafeClass = Class.forName("sun.misc.Unsafe");
22+
Method trySetMemoryAccessWarnedMethod = unsafeClass.getDeclaredMethod("trySetMemoryAccessWarned");
23+
trySetMemoryAccessWarnedMethod.setAccessible(true);
24+
trySetMemoryAccessWarnedMethod.invoke(null);
25+
} catch (ClassNotFoundException | NoSuchMethodException | IllegalAccessException | InvocationTargetException e) {
26+
//let's ignore it - if we failed with our horrible hack, worst that could happen is that the ugly warning is printed
3027
}
31-
RuntimeMXBean runtimeMxBean = ManagementFactory.getRuntimeMXBean();
32-
List<String> arguments = runtimeMxBean.getInputArguments();
33-
return arguments.contains("--sun-misc-unsafe-memory-access=allow");
3428
}
35-
3629
}

docs/src/main/asciidoc/observability.adoc

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -42,8 +42,8 @@ The following table provides an overview of the observability extensions availab
4242
|Extension |Logging |Metrics |Tracing |Profiling |Health Check|Events
4343

4444
|xref:opentelemetry.adoc[quarkus-opentelemetry]
45-
|O
46-
|O
45+
|O, R
46+
|O, R
4747
|R
4848
|
4949
|

docs/src/main/asciidoc/security-oidc-auth0-tutorial.adoc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ and pull requests should be submitted there:
44
https://github.com/quarkusio/quarkus/tree/main/docs/src/main/asciidoc
55
////
66
[id="security-oidc-auth0-tutorial"]
7-
= Protect Quarkus web application by using an Auth0 OpenID Connect provider
7+
= Protect a Quarkus web application by using an Auth0 OpenID Connect provider
88
include::_attributes.adoc[]
99
:diataxis-type: tutorial
1010
:categories: security,web

docs/src/main/asciidoc/upx.adoc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ If you want to force compression to take place in a container, you can set `quar
3838
If you are not in one of these cases, the compression fails.
3939

4040
Setting `quarkus.native.compression.container-image` results in the compression to run in a container.
41-
If you want to set the variable, but not run the compression in a container, set `quakrus.native.compression.container-build` explicitly to `false`.
41+
If you want to set the variable, but not run the compression in a container, set `quarkus.native.compression.container-build` explicitly to `false`.
4242

4343
[IMPORTANT]
4444
.`WORKDIR` for the image used for compression

extensions/arc/deployment/src/main/java/io/quarkus/arc/deployment/BeanArchiveProcessor.java

Lines changed: 32 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,10 @@
1313
import java.util.Set;
1414
import java.util.stream.Collectors;
1515

16+
import jakarta.enterprise.inject.spi.DefinitionException;
17+
1618
import org.jboss.jandex.AnnotationInstance;
19+
import org.jboss.jandex.AnnotationTarget;
1720
import org.jboss.jandex.AnnotationTarget.Kind;
1821
import org.jboss.jandex.ClassInfo;
1922
import org.jboss.jandex.CompositeIndex;
@@ -178,15 +181,41 @@ private IndexView buildApplicationIndex(ArcConfig config, ApplicationArchivesBui
178181
if (isExplicitBeanArchive(archive)
179182
|| isImplicitBeanArchive(index, beanDefiningAnnotations)
180183
|| isAdditionalBeanArchive(archive, beanArchivePredicates)) {
184+
// check for occurrences of incompatible annotations - currently only @Specializes
185+
validateArchiveCompatibility(archive, index, knownCompatibleBeanArchives);
181186
indexes.add(index);
182187
}
183188
}
184189
if (rootIsAlwaysBeanArchive) {
185-
indexes.add(applicationArchivesBuildItem.getRootArchive().getIndex());
190+
ApplicationArchive rootArchive = applicationArchivesBuildItem.getRootArchive();
191+
validateArchiveCompatibility(rootArchive, rootArchive.getIndex(), knownCompatibleBeanArchives);
192+
indexes.add(rootArchive.getIndex());
186193
}
187194
return CompositeIndex.create(indexes);
188195
}
189196

197+
private void validateArchiveCompatibility(ApplicationArchive archive, IndexView index,
198+
KnownCompatibleBeanArchives knownCompatibleBeanArchives) {
199+
// check for occurrences of incompatible annotations - currently only @Specializes
200+
Collection<AnnotationInstance> annotations = index.getAnnotations(DotNames.SPECIALIZES);
201+
if (!annotations.isEmpty() && !knownCompatibleBeanArchives.isKnownCompatible(archive,
202+
KnownCompatibleBeanArchiveBuildItem.Reason.SPECIALIZES_ANNOTATION)) {
203+
Set<String> definitionErrors = new HashSet<>();
204+
for (AnnotationInstance annInstance : annotations) {
205+
DotName targetClassName = annInstance.target().kind().equals(AnnotationTarget.Kind.CLASS)
206+
? annInstance.target().asClass().name()
207+
: annInstance.target().asMethod().declaringClass().name();
208+
definitionErrors.add(targetClassName.toString());
209+
throw new DefinitionException(
210+
"Quarkus does not support CDI Full @Specializes annotation; try using an @Alternative instead. "
211+
+
212+
"If you want to mark one or more archives as Quarkus compatible, take a " +
213+
"look at io.quarkus.arc.deployment.KnownCompatibleBeanArchiveBuildItem.\n" +
214+
"Annotation was found in the following classes: " + definitionErrors);
215+
}
216+
}
217+
}
218+
190219
private boolean isExplicitBeanArchive(ApplicationArchive archive) {
191220
return archive.apply(tree -> tree.contains("META-INF/beans.xml") || tree.contains("WEB-INF/beans.xml"));
192221
}
@@ -229,7 +258,8 @@ private boolean possiblyBeanArchive(ApplicationArchive archive,
229258
if (text.contains("bean-discovery-mode='all'")
230259
|| text.contains("bean-discovery-mode=\"all\"")) {
231260

232-
if (!knownCompatibleBeanArchives.isKnownCompatible(archive)) {
261+
if (!knownCompatibleBeanArchives.isKnownCompatible(archive,
262+
KnownCompatibleBeanArchiveBuildItem.Reason.BEANS_XML_ALL)) {
233263
LOGGER.warnf("Detected bean archive with bean discovery mode of 'all', "
234264
+ "this is not portable in CDI Lite and is treated as 'annotated' in Quarkus! "
235265
+ "Path to beans.xml: %s",
Lines changed: 79 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,28 +1,100 @@
11
package io.quarkus.arc.deployment;
22

3+
import java.util.HashSet;
34
import java.util.Objects;
5+
import java.util.Set;
46

57
import io.quarkus.builder.item.MultiBuildItem;
68

79
/**
810
* Marks a bean archive with given coordinates (groupId, artifactId and optionally classifier)
9-
* as known compatible with Quarkus. This is only useful for bean archives whose {@code beans.xml}
10-
* defines a bean discovery mode of {@code all}; bean archives with discovery mode of {@code none}
11-
* or {@code annotated} are always compatible. If a bean archive is known to be compatible with
12-
* Quarkus, no warning about {@code all} discovery is logged during application build.
11+
* as known compatible with Quarkus. If a bean archive is known to be compatible with
12+
* Quarkus, any error logging or exception throwing related to that compatibility is skipped.
13+
* <p>
14+
* This is useful in the following cases:
15+
* <li>Bean archives whose {@code beans.xml} defines a bean discovery mode of {@code all}; bean archives with discovery mode of
16+
* {@code none} or {@code annotated} are always compatible.</li>
17+
* <li>Bean archives that contain the unsupported {@link jakarta.enterprise.inject.Specializes} annotation.</li>
1318
*/
1419
public final class KnownCompatibleBeanArchiveBuildItem extends MultiBuildItem {
20+
final Set<Reason> reasons;
1521
final String groupId;
1622
final String artifactId;
1723
final String classifier;
1824

25+
/**
26+
* Deprecated, use {@link KnownCompatibleBeanArchiveBuildItem#builder(String, String)} method instead.
27+
* For compatibility reasons, this method automatically registers the artifact with {@link Reason#BEANS_XML_ALL}.
28+
*/
29+
@Deprecated
1930
public KnownCompatibleBeanArchiveBuildItem(String groupId, String artifactId) {
2031
this(groupId, artifactId, "");
2132
}
2233

34+
/**
35+
* Deprecated, use {@link KnownCompatibleBeanArchiveBuildItem#builder(String, String)} method instead.
36+
* For compatibility reasons, this method automatically registers the artifact with {@link Reason#BEANS_XML_ALL}.
37+
*/
38+
@Deprecated
2339
public KnownCompatibleBeanArchiveBuildItem(String groupId, String artifactId, String classifier) {
24-
this.groupId = Objects.requireNonNull(groupId, "groupId must be set");
25-
this.artifactId = Objects.requireNonNull(artifactId, "artifactId must be set");
26-
this.classifier = Objects.requireNonNull(classifier, "classifier must be set");
40+
this(groupId, artifactId, classifier, Set.of(Reason.BEANS_XML_ALL));
41+
}
42+
43+
private KnownCompatibleBeanArchiveBuildItem(String groupId, String artifactId, String classifier, Set<Reason> reasons) {
44+
Objects.requireNonNull(groupId, "groupId must be set");
45+
Objects.requireNonNull(artifactId, "artifactId must be set");
46+
Objects.requireNonNull(classifier, "classifier must be set");
47+
if (reasons.isEmpty()) {
48+
throw new IllegalStateException(
49+
"KnownCompatibleBeanArchiveBuildItem.Builder needs to declare at least one compatibility reason. Artifact with following coordinates had no reason associated: "
50+
+ groupId + ":" + artifactId);
51+
}
52+
this.groupId = groupId;
53+
this.artifactId = artifactId;
54+
this.classifier = classifier;
55+
this.reasons = reasons;
56+
}
57+
58+
public static Builder builder(String groupId, String artifactId) {
59+
return new Builder(groupId, artifactId);
60+
}
61+
62+
/**
63+
* An enum listing known reasons for which an archive might be marked as compatible despite using some unsupported
64+
* feature such as {@code beans.xml} discovery mode {@code all} or using {@link jakarta.enterprise.inject.Specializes}
65+
* annotation on its classes.
66+
*/
67+
public enum Reason {
68+
BEANS_XML_ALL,
69+
SPECIALIZES_ANNOTATION;
70+
}
71+
72+
public static class Builder {
73+
74+
private final String groupId;
75+
private final String artifactId;
76+
private final Set<Reason> reasons;
77+
private String classifier;
78+
79+
private Builder(String groupId, String artifactId) {
80+
this.groupId = groupId;
81+
this.artifactId = artifactId;
82+
this.classifier = "";
83+
this.reasons = new HashSet<>();
84+
}
85+
86+
public Builder setClassifier(String classifier) {
87+
this.classifier = classifier;
88+
return this;
89+
}
90+
91+
public Builder addReason(Reason reason) {
92+
this.reasons.add(reason);
93+
return this;
94+
}
95+
96+
public KnownCompatibleBeanArchiveBuildItem build() {
97+
return new KnownCompatibleBeanArchiveBuildItem(groupId, artifactId, classifier, reasons);
98+
}
2799
}
28100
}

extensions/arc/deployment/src/main/java/io/quarkus/arc/deployment/KnownCompatibleBeanArchives.java

Lines changed: 15 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,17 @@
11
package io.quarkus.arc.deployment;
22

3+
import java.util.HashMap;
34
import java.util.HashSet;
45
import java.util.List;
6+
import java.util.Map;
57
import java.util.Objects;
68
import java.util.Set;
79

810
import io.quarkus.deployment.ApplicationArchive;
911
import io.quarkus.maven.dependency.ArtifactKey;
1012

1113
final class KnownCompatibleBeanArchives {
12-
private static class Key {
14+
static class Key {
1315
final String groupId;
1416
final String artifactId;
1517
final String classifier;
@@ -40,22 +42,28 @@ public int hashCode() {
4042
}
4143
}
4244

43-
private final Set<Key> keys;
45+
private final Map<KnownCompatibleBeanArchiveBuildItem.Reason, Set<Key>> compatArchivesByReason;
4446

4547
KnownCompatibleBeanArchives(List<KnownCompatibleBeanArchiveBuildItem> list) {
46-
Set<Key> keys = new HashSet<>();
48+
Map<KnownCompatibleBeanArchiveBuildItem.Reason, Set<Key>> allCompatArchivesMap = new HashMap<>();
4749
for (KnownCompatibleBeanArchiveBuildItem item : list) {
48-
keys.add(new Key(item.groupId, item.artifactId, item.classifier));
50+
for (KnownCompatibleBeanArchiveBuildItem.Reason reason : item.reasons) {
51+
allCompatArchivesMap.computeIfAbsent(reason, unused -> new HashSet<>())
52+
.add(new Key(item.groupId, item.artifactId, item.classifier));
53+
}
4954
}
50-
this.keys = keys;
55+
this.compatArchivesByReason = allCompatArchivesMap;
5156
}
5257

53-
boolean isKnownCompatible(ApplicationArchive archive) {
58+
boolean isKnownCompatible(ApplicationArchive archive, KnownCompatibleBeanArchiveBuildItem.Reason reason) {
5459
ArtifactKey artifact = archive.getKey();
5560
if (artifact == null) {
5661
return false;
5762
}
5863

59-
return keys.contains(new Key(artifact.getGroupId(), artifact.getArtifactId(), artifact.getClassifier()));
64+
Set<Key> archives = compatArchivesByReason.get(reason);
65+
return archives == null ? false
66+
: archives
67+
.contains(new Key(artifact.getGroupId(), artifact.getArtifactId(), artifact.getClassifier()));
6068
}
6169
}

0 commit comments

Comments
 (0)