Skip to content

Commit 5aa5604

Browse files
authored
Merge pull request #47837 from gsmet/3.22.3-backports-1
[3.22] 3.22.3 backports 1
2 parents 330195e + 8bfa0f2 commit 5aa5604

File tree

150 files changed

+3127
-934
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

150 files changed

+3127
-934
lines changed

adr/0004-using-the-tls-registry-for-clients.adoc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ The TLS registry is an extension processing the `quarkus.tls` configuration and
2626
Note that the configuration and the runtime API are different.
2727
The configuration is used to define the TLS settings, while the runtime API is used to access these pre-processed settings.
2828

29-
hen using the options directly under `quarkus.tls.`, one configures the default (_unamed_) configuration, while using options under `quarkus.tls.<name>.` configures a _named_ configuration.
29+
When using the options directly under `quarkus.tls.`, one configures the default (_unnamed_) configuration, while using options under `quarkus.tls.<name>.` configures a _named_ configuration.
3030
For each configuration, trust stores and key stores can be defined, as well as the default protocol, cipher suites, etc.
3131
More details can be found in the https://quarkus.io/version/main/guides/tls-registry-reference[documentation] and in the https://github.com/quarkusio/quarkus/blob/main/extensions/tls-registry/runtime/src/main/java/io/quarkus/tls/runtime/config/TlsBucketConfig.java[code].
3232

bom/application/pom.xml

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@
2222
<cyclonedx.version>9.0.5</cyclonedx.version>
2323
<expressly.version>5.0.0</expressly.version>
2424
<findbugs.version>3.0.2</findbugs.version>
25-
<jandex.version>3.3.0</jandex.version>
25+
<jandex.version>3.3.1</jandex.version>
2626
<javax.annotation-api.version>1.3.2</javax.annotation-api.version>
2727
<javax.inject.version>1</javax.inject.version>
2828
<parsson.version>1.1.7</parsson.version>
@@ -32,7 +32,7 @@
3232
<opentelemetry-instrumentation.version>2.10.0-alpha</opentelemetry-instrumentation.version>
3333
<opentelemetry-semconv.version>1.29.0-alpha</opentelemetry-semconv.version>
3434
<quarkus-http.version>5.3.4</quarkus-http.version>
35-
<micrometer.version>1.14.6</micrometer.version><!-- keep in sync with hdrhistogram: https://central.sonatype.com/artifact/io.micrometer/micrometer-core -->
35+
<micrometer.version>1.14.7</micrometer.version><!-- keep in sync with hdrhistogram: https://central.sonatype.com/artifact/io.micrometer/micrometer-core -->
3636
<hdrhistogram.version>2.2.2</hdrhistogram.version><!-- keep in sync with micrometer -->
3737
<google-auth.version>0.22.0</google-auth.version>
3838
<graphql-java.version>22.2</graphql-java.version> <!-- keep in sync with smallrye-graphql -->
@@ -96,7 +96,7 @@
9696
<classmate.version>1.7.0</classmate.version>
9797
<!-- See root POM for hibernate-orm.version, hibernate-reactive.version, hibernate-validator.version,
9898
hibernate-search.version, antlr.version, bytebuddy.version, hibernate-commons-annotations.version -->
99-
<narayana.version>7.2.1.Final</narayana.version>
99+
<narayana.version>7.2.2.Final</narayana.version>
100100
<narayana-lra.version>1.0.0.Final</narayana-lra.version>
101101
<agroal.version>2.6</agroal.version>
102102
<jboss-transaction-spi.version>8.0.0.Final</jboss-transaction-spi.version>
@@ -108,7 +108,7 @@
108108
<slf4j-jboss-logmanager.version>2.0.0.Final</slf4j-jboss-logmanager.version>
109109
<wildfly-common.version>2.0.1</wildfly-common.version>
110110
<wildfly-client-config.version>1.0.1.Final</wildfly-client-config.version>
111-
<wildfly-elytron.version>2.6.3.Final</wildfly-elytron.version>
111+
<wildfly-elytron.version>2.6.4.Final</wildfly-elytron.version>
112112
<jboss-marshalling.version>2.2.3.Final</jboss-marshalling.version>
113113
<jboss-threads.version>3.8.0.Final</jboss-threads.version>
114114
<vertx.version>4.5.14</vertx.version>

build-parent/pom.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@
2929
<jboss-bridger-plugin.version>1.6.Final</jboss-bridger-plugin.version>
3030

3131
<!-- Jandex versions -->
32-
<jandex.version>3.3.0</jandex.version>
32+
<jandex.version>3.3.1</jandex.version>
3333
<jandex-gradle-plugin.version>1.0.0</jandex-gradle-plugin.version>
3434

3535
<asciidoctorj.version>2.5.13</asciidoctorj.version>

core/deployment/src/main/java/io/quarkus/deployment/dev/testing/CurrentTestApplication.java

Lines changed: 0 additions & 19 deletions
This file was deleted.

core/deployment/src/main/java/io/quarkus/deployment/dev/testing/JunitTestRunner.java

Lines changed: 50 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -158,7 +158,6 @@ public Runnable prepare() {
158158
LogCapturingOutputFilter logHandler = new LogCapturingOutputFilter(testApplication, true, true,
159159
TestSupport.instance()
160160
.get()::isDisplayTestOutput);
161-
// TODO do we want to do this setting of the TCCL? I think it just makes problems?
162161
Thread.currentThread().setContextClassLoader(tcl);
163162

164163
Set<UniqueId> allDiscoveredIds = new HashSet<>();
@@ -570,21 +569,23 @@ private DiscoveryResult discoverTestClasses() {
570569
//for now this is out of scope, we are just going to do annotation based discovery
571570
//we will need to fix this sooner rather than later though
572571

572+
if (moduleInfo.getTest().isEmpty()) {
573+
return DiscoveryResult.EMPTY;
574+
}
575+
573576
//we also only run tests from the current module, which we can also revisit later
574577
Indexer indexer = new Indexer();
575-
moduleInfo.getTest().ifPresent(test -> {
576-
try (Stream<Path> files = Files.walk(Paths.get(test.getClassesPath()))) {
577-
files.filter(s -> s.getFileName().toString().endsWith(".class")).forEach(s -> {
578-
try (InputStream in = Files.newInputStream(s)) {
579-
indexer.index(in);
580-
} catch (IOException e) {
581-
throw new RuntimeException(e);
582-
}
583-
});
584-
} catch (IOException e) {
585-
throw new RuntimeException(e);
586-
}
587-
});
578+
try (Stream<Path> files = Files.walk(Paths.get(moduleInfo.getTest().get().getClassesPath()))) {
579+
files.filter(s -> s.getFileName().toString().endsWith(".class")).forEach(s -> {
580+
try (InputStream in = Files.newInputStream(s)) {
581+
indexer.index(in);
582+
} catch (IOException e) {
583+
throw new RuntimeException(e);
584+
}
585+
});
586+
} catch (IOException e) {
587+
throw new RuntimeException(e);
588+
}
588589

589590
Index index = indexer.complete();
590591
//we now have all the classes by name
@@ -617,18 +618,16 @@ private DiscoveryResult discoverTestClasses() {
617618
// Most logic in the JUnitRunner counts main tests as quarkus tests, so do a (mildly irritating) special pass to get the ones which are strictly @QuarkusTest
618619

619620
Set<String> quarkusTestClassesForFacadeClassLoader = new HashSet<>();
620-
for (var a : Arrays.asList(QUARKUS_TEST)) {
621-
for (AnnotationInstance i : index.getAnnotations(a)) {
622-
DotName name = i.target()
623-
.asClass()
624-
.name();
625-
quarkusTestClassesForFacadeClassLoader.add(name.toString());
626-
for (ClassInfo clazz : index.getAllKnownSubclasses(name)) {
627-
if (!integrationTestClasses.contains(clazz.name()
628-
.toString())) {
629-
quarkusTestClassesForFacadeClassLoader.add(clazz.name()
630-
.toString());
631-
}
621+
for (AnnotationInstance i : index.getAnnotations(QUARKUS_TEST)) {
622+
DotName name = i.target()
623+
.asClass()
624+
.name();
625+
quarkusTestClassesForFacadeClassLoader.add(name.toString());
626+
for (ClassInfo clazz : index.getAllKnownSubclasses(name)) {
627+
if (!integrationTestClasses.contains(clazz.name()
628+
.toString())) {
629+
quarkusTestClassesForFacadeClassLoader.add(clazz.name()
630+
.toString());
632631
}
633632
}
634633
}
@@ -681,10 +680,16 @@ private DiscoveryResult discoverTestClasses() {
681680
}
682681
var enclosing = enclosingClasses.get(testClass);
683682
if (enclosing != null) {
684-
if (integrationTestClasses.contains(enclosing.toString())) {
683+
String enclosingString = enclosing.toString();
684+
if (quarkusTestClassesForFacadeClassLoader.contains(enclosingString)) {
685+
quarkusTestClassesForFacadeClassLoader.add(name);
686+
}
687+
688+
// No else here, this is an 'also do'
689+
if (integrationTestClasses.contains(enclosingString)) {
685690
integrationTestClasses.add(name);
686691
continue;
687-
} else if (quarkusTestClasses.contains(enclosing.toString())) {
692+
} else if (quarkusTestClasses.contains(enclosingString)) {
688693
quarkusTestClasses.add(name);
689694
continue;
690695
}
@@ -696,6 +701,20 @@ private DiscoveryResult discoverTestClasses() {
696701
unitTestClasses.add(name);
697702
}
698703

704+
// if we didn't find any test classes, let's return early
705+
// Make sure you also update the logic for the non-empty case above if you adjust this part
706+
if (testType == TestType.ALL) {
707+
if (unitTestClasses.isEmpty() && quarkusTestClasses.isEmpty()) {
708+
return DiscoveryResult.EMPTY;
709+
}
710+
} else if (testType == TestType.UNIT) {
711+
if (unitTestClasses.isEmpty()) {
712+
return DiscoveryResult.EMPTY;
713+
}
714+
} else if (quarkusTestClasses.isEmpty()) {
715+
return DiscoveryResult.EMPTY;
716+
}
717+
699718
List<Class<?>> itClasses = new ArrayList<>();
700719
List<Class<?>> utClasses = new ArrayList<>();
701720

@@ -745,8 +764,6 @@ private DiscoveryResult discoverTestClasses() {
745764
log.warnf(
746765
"Failed to load test class %s (possibly as it was added after the test run started), it will not be executed this run.",
747766
i);
748-
} finally {
749-
// TODO should we do this? Thread.currentThread().setContextClassLoader(old);
750767
}
751768
}
752769
itClasses.sort(Comparator.comparing(new Function<Class<?>, String>() {
@@ -808,6 +825,7 @@ public String apply(Class<?> aClass) {
808825
}
809826
}
810827

828+
// Make sure you also update the logic for the empty case above if you adjust this part
811829
if (testType == TestType.ALL) {
812830
//run unit style tests first
813831
//before the quarkus tests have started
@@ -1270,6 +1288,8 @@ public FilterResult apply(TestDescriptor testDescriptor) {
12701288

12711289
static class DiscoveryResult implements AutoCloseable {
12721290

1291+
private final static DiscoveryResult EMPTY = new DiscoveryResult(null, List.of());
1292+
12731293
final QuarkusClassLoader classLoader;
12741294
final List<Class<?>> testClasses;
12751295

Lines changed: 164 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,164 @@
1+
package io.quarkus.deployment.pkg;
2+
3+
import java.io.IOException;
4+
import java.io.InputStream;
5+
import java.nio.file.Files;
6+
import java.nio.file.Path;
7+
import java.util.Enumeration;
8+
import java.util.Map;
9+
import java.util.function.Predicate;
10+
import java.util.jar.Attributes;
11+
import java.util.jar.JarEntry;
12+
import java.util.jar.JarFile;
13+
import java.util.jar.JarOutputStream;
14+
import java.util.jar.Manifest;
15+
16+
import org.jboss.logging.Logger;
17+
18+
/**
19+
* JarUnsigner is used to remove the signature from a jar file.
20+
*/
21+
public final class JarUnsigner {
22+
23+
private static final Logger log = Logger.getLogger(JarUnsigner.class);
24+
25+
private JarUnsigner() {
26+
// utility class
27+
}
28+
29+
/**
30+
* Unsigns a jar file by removing the signature entries.
31+
* If the JAR is not signed, it will simply copy the original JAR to the target path.
32+
*
33+
* @param jarPath the path to the jar file to unsign
34+
* @param targetPath the path to the target jar file
35+
* @throws IOException if an I/O error occurs
36+
*/
37+
public static void unsignJar(Path jarPath, Path targetPath) throws IOException {
38+
try (JarFile in = new JarFile(jarPath.toFile(), false)) {
39+
Manifest manifest = in.getManifest();
40+
boolean signed;
41+
if (manifest != null) {
42+
Map<String, Attributes> entries = manifest.getEntries();
43+
signed = !entries.isEmpty();
44+
// Remove signature entries
45+
entries.clear();
46+
} else {
47+
signed = false;
48+
manifest = new Manifest();
49+
}
50+
if (!signed) {
51+
in.close();
52+
log.debugf("JAR %s is not signed, skipping unsigning", jarPath);
53+
Files.copy(jarPath, targetPath, java.nio.file.StandardCopyOption.REPLACE_EXISTING);
54+
} else {
55+
log.debugf("JAR %s is signed, removing signature", jarPath);
56+
// Reusing buffer for performance reasons
57+
byte[] buffer = new byte[10000];
58+
try (JarOutputStream out = new JarOutputStream(Files.newOutputStream(targetPath))) {
59+
JarEntry manifestEntry = new JarEntry(JarFile.MANIFEST_NAME);
60+
// Set manifest time to epoch to always make the same jar
61+
manifestEntry.setTime(0);
62+
out.putNextEntry(manifestEntry);
63+
manifest.write(out);
64+
out.closeEntry();
65+
Enumeration<JarEntry> entries = in.entries();
66+
while (entries.hasMoreElements()) {
67+
JarEntry entry = entries.nextElement();
68+
String entryName = entry.getName();
69+
if (!entryName.equals(JarFile.MANIFEST_NAME)
70+
&& !entryName.equals("META-INF/INDEX.LIST")
71+
&& !isSignatureFile(entryName)) {
72+
entry.setCompressedSize(-1);
73+
out.putNextEntry(entry);
74+
try (InputStream inStream = in.getInputStream(entry)) {
75+
int r;
76+
while ((r = inStream.read(buffer)) > 0) {
77+
out.write(buffer, 0, r);
78+
}
79+
} finally {
80+
out.closeEntry();
81+
}
82+
} else {
83+
log.debugf("Removed %s from %s", entryName, jarPath);
84+
}
85+
}
86+
}
87+
}
88+
// let's make sure we keep the original timestamp
89+
Files.setLastModifiedTime(targetPath, Files.getLastModifiedTime(jarPath));
90+
}
91+
}
92+
93+
/**
94+
* Unsigns a jar file by removing the signature entries.
95+
*
96+
* @param jarPath the path to the jar file to unsign
97+
* @param targetPath the path to the target jar file
98+
* @param includePredicate a predicate to determine which entries to include in the target jar
99+
* @throws IOException if an I/O error occurs
100+
*/
101+
public static void unsignJar(Path jarPath, Path targetPath, Predicate<String> includePredicate) throws IOException {
102+
// Reusing buffer for performance reasons
103+
byte[] buffer = new byte[10000];
104+
try (JarFile in = new JarFile(jarPath.toFile(), false)) {
105+
Manifest manifest = in.getManifest();
106+
boolean signed;
107+
if (manifest != null) {
108+
Map<String, Attributes> entries = manifest.getEntries();
109+
signed = !entries.isEmpty();
110+
// Remove signature entries
111+
entries.clear();
112+
} else {
113+
signed = false;
114+
manifest = new Manifest();
115+
}
116+
if (signed) {
117+
log.debugf("JAR %s is signed, removing signature", jarPath);
118+
}
119+
try (JarOutputStream out = new JarOutputStream(Files.newOutputStream(targetPath))) {
120+
JarEntry manifestEntry = new JarEntry(JarFile.MANIFEST_NAME);
121+
// Set manifest time to epoch to always make the same jar
122+
manifestEntry.setTime(0);
123+
out.putNextEntry(manifestEntry);
124+
manifest.write(out);
125+
out.closeEntry();
126+
Enumeration<JarEntry> entries = in.entries();
127+
while (entries.hasMoreElements()) {
128+
JarEntry entry = entries.nextElement();
129+
String entryName = entry.getName();
130+
if (includePredicate.test(entryName)
131+
&& !entryName.equals(JarFile.MANIFEST_NAME)
132+
&& !entryName.equals("META-INF/INDEX.LIST")
133+
&& !isSignatureFile(entryName)) {
134+
entry.setCompressedSize(-1);
135+
out.putNextEntry(entry);
136+
try (InputStream inStream = in.getInputStream(entry)) {
137+
int r;
138+
while ((r = inStream.read(buffer)) > 0) {
139+
out.write(buffer, 0, r);
140+
}
141+
} finally {
142+
out.closeEntry();
143+
}
144+
} else {
145+
log.debugf("Removed %s from %s", entryName, jarPath);
146+
}
147+
}
148+
}
149+
// let's make sure we keep the original timestamp
150+
Files.setLastModifiedTime(targetPath, Files.getLastModifiedTime(jarPath));
151+
}
152+
}
153+
154+
private static boolean isSignatureFile(String entry) {
155+
entry = entry.toUpperCase();
156+
if (entry.startsWith("META-INF/") && entry.indexOf('/', "META-INF/".length()) == -1) {
157+
return entry.endsWith(".SF")
158+
|| entry.endsWith(".DSA")
159+
|| entry.endsWith(".RSA")
160+
|| entry.endsWith(".EC");
161+
}
162+
return false;
163+
}
164+
}

0 commit comments

Comments
 (0)