Skip to content

Commit ebf4aad

Browse files
committed
First step
1 parent 28cd73b commit ebf4aad

File tree

7 files changed

+260
-4
lines changed

7 files changed

+260
-4
lines changed
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
#!/bin/bash
2+
set -e
3+
4+
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
5+
WORK_DIR="$(mktemp -d)"
6+
CUSTOM_VERSION="1.33.4-SNAPSHOT"
7+
ORIGINAL_VERSION="1.33.3"
8+
9+
echo "Building armeria-core with UNSAFE disabled..."
10+
11+
cd "${WORK_DIR}"
12+
13+
# Clone Armeria repository
14+
git clone --depth 1 --branch "armeria-${ORIGINAL_VERSION}" https://github.com/line/armeria.git
15+
16+
cd armeria
17+
18+
# Apply patch to remove unsafe access
19+
git apply "${SCRIPT_DIR}/unsafe.patch"
20+
21+
# Update version to snapshot version
22+
sed -i "s/version=${ORIGINAL_VERSION}/version=${CUSTOM_VERSION}/" gradle.properties
23+
24+
# Build the core module
25+
./gradlew :core:jar -x javadoc -x :docs-client:nodeSetup -x :docs-client:npmSetup -x :docs-client:npmInstall -x :docs-client:eslint -x :docs-client:lint -x :docs-client:buildWeb -x :docs-client:copyWeb
26+
27+
# Find the built JAR
28+
CORE_JAR="core/build/libs/armeria-${CUSTOM_VERSION}.jar"
29+
if [ ! -f "$CORE_JAR" ]; then
30+
echo "Error: Could not find armeria JAR at $CORE_JAR"
31+
exit 1
32+
fi
33+
34+
# Install core JAR to Maven local repository
35+
mvn install:install-file -q \
36+
-Dfile="$CORE_JAR" \
37+
-DgroupId=com.linecorp.armeria \
38+
-DartifactId=armeria \
39+
-Dversion="${CUSTOM_VERSION}" \
40+
-Dpackaging=jar
41+
42+
# Update dependencies
43+
DEPS="${SCRIPT_DIR}/../../dependencyManagement/build.gradle.kts"
44+
45+
# Update only the armeria core artifact version
46+
sed -i '/com\.linecorp\.armeria:armeria:/d' "${DEPS}"
47+
sed -i '/^val DEPENDENCIES = listOf(/a\ "com.linecorp.armeria:armeria:'"${CUSTOM_VERSION}"'",' "${DEPS}"
48+
49+
echo "armeria ${CUSTOM_VERSION} built and installed (UNSAFE disabled)."
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
#!/bin/bash
2+
set -e
3+
4+
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
5+
WORK_DIR="$(mktemp -d)"
6+
CUSTOM_VERSION="4.32.2-SNAPSHOT"
7+
ORIGINAL_VERSION="4.32.1"
8+
9+
echo "Building protobuf-java with UNSAFE disabled..."
10+
11+
cd "${WORK_DIR}"
12+
13+
# Download original artifact and extract
14+
curl -sL -o "protobuf-java-${ORIGINAL_VERSION}.jar" "https://repo1.maven.org/maven2/com/google/protobuf/protobuf-java/${ORIGINAL_VERSION}/protobuf-java-${ORIGINAL_VERSION}.jar"
15+
16+
# Extract JAR
17+
mkdir classes
18+
cd classes
19+
jar -xf "../protobuf-java-${ORIGINAL_VERSION}.jar"
20+
cd ..
21+
22+
# Clone protobuf repository
23+
git clone --depth 1 --branch "v32.1" https://github.com/protocolbuffers/protobuf.git
24+
25+
# Apply patch to remove unsafe access
26+
sed -i 's/private static final sun\.misc\.Unsafe UNSAFE = getUnsafe();/private static final sun.misc.Unsafe UNSAFE = null;/' protobuf/java/core/src/main/java/com/google/protobuf/UnsafeUtil.java
27+
28+
# Compile modified classes
29+
javac -cp protobuf-java-${ORIGINAL_VERSION}.jar -d classes protobuf/java/core/src/main/java/com/google/protobuf/UnsafeUtil.java
30+
31+
# Update version and create new JAR
32+
sed -i "s/Implementation-Version: ${ORIGINAL_VERSION}/Implementation-Version: ${CUSTOM_VERSION}/" classes/META-INF/MANIFEST.MF
33+
find classes/META-INF -name "pom.properties" -exec sed -i "s/version=${ORIGINAL_VERSION}/version=${CUSTOM_VERSION}/" {} \;
34+
jar -cf "protobuf-java-${CUSTOM_VERSION}.jar" -C classes .
35+
36+
# Install to Maven local repository
37+
mvn install:install-file -q \
38+
-Dfile="protobuf-java-${CUSTOM_VERSION}.jar" \
39+
-DgroupId=com.google.protobuf \
40+
-DartifactId=protobuf-java \
41+
-Dversion="${CUSTOM_VERSION}" \
42+
-Dpackaging=jar
43+
44+
# Update dependencies
45+
DEPS="${SCRIPT_DIR}/../../dependencyManagement/build.gradle.kts"
46+
sed -i '/com\.google\.protobuf:protobuf-bom:/d' "${DEPS}"
47+
sed -i '/com\.google\.protobuf:protobuf-java/d' "${DEPS}"
48+
sed -i '/^val DEPENDENCIES = listOf(/a\ "com.google.protobuf:protobuf-java:'"${CUSTOM_VERSION}"'",' "${DEPS}"
49+
sed -i '/^val DEPENDENCIES = listOf(/a\ "com.google.protobuf:protobuf-java-util:${ORIGINAL_VERSION}",' "${DEPS}"
50+
51+
echo "protobuf-java ${CUSTOM_VERSION} built and installed (UNSAFE disabled)."

.github/unsafe/unsafe.patch

Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
From f371066409daaf55739eb60e1ef0d9f42b21ac2a Mon Sep 17 00:00:00 2001
2+
From: Trask Stalnaker <trask.stalnaker@gmail.com>
3+
Date: Sat, 20 Sep 2025 15:36:51 -0700
4+
Subject: [PATCH] Remove Unsafe usage
5+
6+
---
7+
.../java/com/linecorp/armeria/common/ExceptionSampler.java | 5 ++---
8+
.../linecorp/armeria/common/stream/DefaultStreamMessage.java | 4 ++--
9+
core/src/main/java/com/linecorp/armeria/server/Server.java | 4 ++--
10+
3 files changed, 6 insertions(+), 7 deletions(-)
11+
12+
diff --git a/core/src/main/java/com/linecorp/armeria/common/ExceptionSampler.java b/core/src/main/java/com/linecorp/armeria/common/ExceptionSampler.java
13+
index 87afd2074..b5c1c2470 100644
14+
--- a/core/src/main/java/com/linecorp/armeria/common/ExceptionSampler.java
15+
+++ b/core/src/main/java/com/linecorp/armeria/common/ExceptionSampler.java
16+
@@ -18,10 +18,9 @@ package com.linecorp.armeria.common;
17+
import static java.util.Objects.requireNonNull;
18+
19+
import java.util.Map;
20+
+import java.util.concurrent.ConcurrentHashMap;
21+
import java.util.function.Function;
22+
23+
-import org.jctools.maps.NonBlockingHashMap;
24+
-
25+
import com.google.common.base.MoreObjects;
26+
27+
import com.linecorp.armeria.common.util.Sampler;
28+
@@ -29,7 +28,7 @@ import com.linecorp.armeria.common.util.Sampler;
29+
final class ExceptionSampler implements Sampler<Class<? extends Throwable>> {
30+
31+
private final Map<Class<? extends Throwable>, Sampler<Class<? extends Throwable>>> samplers =
32+
- new NonBlockingHashMap<>();
33+
+ new ConcurrentHashMap<>();
34+
private final Function<? super Class<? extends Throwable>,
35+
? extends Sampler<Class<? extends Throwable>>> samplerFactory;
36+
private final String spec;
37+
diff --git a/core/src/main/java/com/linecorp/armeria/common/stream/DefaultStreamMessage.java b/core/src/main/java/com/linecorp/armeria/common/stream/DefaultStreamMessage.java
38+
index e9328f03e..12173e999 100644
39+
--- a/core/src/main/java/com/linecorp/armeria/common/stream/DefaultStreamMessage.java
40+
+++ b/core/src/main/java/com/linecorp/armeria/common/stream/DefaultStreamMessage.java
41+
@@ -22,9 +22,9 @@ import static java.util.Objects.requireNonNull;
42+
43+
import java.util.Queue;
44+
import java.util.concurrent.CompletableFuture;
45+
+import java.util.concurrent.ConcurrentLinkedQueue;
46+
import java.util.concurrent.atomic.AtomicReferenceFieldUpdater;
47+
48+
-import org.jctools.queues.MpscChunkedArrayQueue;
49+
import org.reactivestreams.Subscriber;
50+
import org.slf4j.Logger;
51+
import org.slf4j.LoggerFactory;
52+
@@ -109,7 +109,7 @@ public class DefaultStreamMessage<T> extends AbstractStreamWriter<T> {
53+
*/
54+
@Deprecated
55+
public DefaultStreamMessage() {
56+
- queue = new MpscChunkedArrayQueue<>(INITIAL_CAPACITY, 1 << 30);
57+
+ queue = new ConcurrentLinkedQueue<>();
58+
}
59+
60+
@Override
61+
diff --git a/core/src/main/java/com/linecorp/armeria/server/Server.java b/core/src/main/java/com/linecorp/armeria/server/Server.java
62+
index 6b8b0b557..0c3eed942 100644
63+
--- a/core/src/main/java/com/linecorp/armeria/server/Server.java
64+
+++ b/core/src/main/java/com/linecorp/armeria/server/Server.java
65+
@@ -37,6 +37,7 @@ import java.util.Set;
66+
import java.util.concurrent.CompletableFuture;
67+
import java.util.concurrent.CompletionException;
68+
import java.util.concurrent.CompletionStage;
69+
+import java.util.concurrent.ConcurrentHashMap;
70+
import java.util.concurrent.ExecutionException;
71+
import java.util.concurrent.Executor;
72+
import java.util.concurrent.ExecutorService;
73+
@@ -51,7 +52,6 @@ import java.util.stream.Collectors;
74+
75+
import javax.net.ssl.SSLSession;
76+
77+
-import org.jctools.maps.NonBlockingHashSet;
78+
import org.slf4j.Logger;
79+
import org.slf4j.LoggerFactory;
80+
81+
@@ -119,7 +119,7 @@ public final class Server implements ListenableAsyncCloseable {
82+
83+
private final UpdatableServerConfig config;
84+
private final StartStopSupport<Void, Void, Void, ServerListener> startStop;
85+
- private final Set<ServerChannel> serverChannels = new NonBlockingHashSet<>();
86+
+ private final Set<ServerChannel> serverChannels = ConcurrentHashMap.newKeySet();
87+
private final ReentrantLock lock = new ReentrantShortLock();
88+
@GuardedBy("lock")
89+
private final Map<InetSocketAddress, ServerPort> activePorts = new LinkedHashMap<>();
90+
--
91+
2.51.0.windows.1
92+

.github/workflows/build.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,7 @@ jobs:
7070

7171
- name: Set up gradle
7272
uses: gradle/actions/setup-gradle@ed408507eac070d1f99cc633dbcf757c94c7933a # v4.4.3
73+
7374
- name: Build
7475
run: >
7576
./gradlew build

.github/workflows/unsafe.yml

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
name: Test without unsafe access
2+
3+
on:
4+
push:
5+
branches:
6+
- main
7+
- release/*
8+
pull_request:
9+
workflow_dispatch:
10+
11+
concurrency:
12+
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.sha }}
13+
cancel-in-progress: true
14+
15+
permissions:
16+
contents: read
17+
18+
jobs:
19+
test-without-unsafe:
20+
name: Test without unsafe access
21+
runs-on: ubuntu-latest
22+
steps:
23+
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
24+
25+
- id: setup-java-test
26+
name: Set up Java 24 for tests
27+
uses: actions/setup-java@dded0888837ed1f317902acf8a20df0ad188d165 # v5.0.0
28+
with:
29+
distribution: temurin
30+
java-version: 24
31+
32+
- id: setup-java
33+
name: Set up Java for build
34+
uses: actions/setup-java@dded0888837ed1f317902acf8a20df0ad188d165 # v5.0.0
35+
with:
36+
distribution: temurin
37+
java-version: 17
38+
39+
- name: Set up gradle
40+
uses: gradle/actions/setup-gradle@ed408507eac070d1f99cc633dbcf757c94c7933a # v4.4.3
41+
42+
- name: Build custom protobuf-java without unsafe
43+
run: ./.github/unsafe/build-custom-protobuf.sh
44+
45+
- name: Build custom armeria without unsafe
46+
run: ./.github/unsafe/build-custom-armeria.sh
47+
48+
- name: Build and test
49+
run: >
50+
./gradlew build
51+
-PtestJavaVersion=24
52+
-PdenyUnsafeAccess=true
53+
"-Porg.gradle.java.installations.paths=${{ steps.setup-java-test.outputs.path }}"
54+
"-Porg.gradle.java.installations.auto-download=false"

buildSrc/src/main/kotlin/otel.java-conventions.gradle.kts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,7 @@ dependencyCheck {
7070
}
7171

7272
val testJavaVersion = gradle.startParameter.projectProperties.get("testJavaVersion")?.let(JavaVersion::toVersion)
73+
val denyUnsafeAccess = gradle.startParameter.projectProperties.get("denyUnsafeAccess")?.toBoolean() ?: false
7374

7475
tasks {
7576
withType<JavaCompile>().configureEach {
@@ -114,6 +115,11 @@ tasks {
114115
)
115116
}
116117

118+
// Add JVM arguments when denyUnsafeAccess property is set
119+
if (denyUnsafeAccess) {
120+
jvmArgs("--sun-misc-unsafe-memory-access=deny")
121+
}
122+
117123
val defaultMaxRetries = if (System.getenv().containsKey("CI")) 2 else 0
118124
val maxTestRetries = gradle.startParameter.projectProperties["maxTestRetries"]?.toInt() ?: defaultMaxRetries
119125

sdk/trace-shaded-deps/src/test/java/io/opentelemetry/sdk/trace/internal/JcToolsTest.java

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ void drain_ArrayBlockingQueue() {
4343
void drain_MessagePassingQueue() {
4444
// Arrange
4545
batch.add("Test3");
46-
Queue<String> queue = new MpscArrayQueue<>(10);
46+
Queue<String> queue = JcTools.newFixedSizeQueue(10);
4747
queue.add("Test1");
4848
queue.add("Test2");
4949

@@ -58,7 +58,7 @@ void drain_MessagePassingQueue() {
5858
@Test
5959
void drain_MaxBatch() {
6060
// Arrange
61-
Queue<String> queue = new MpscArrayQueue<>(10);
61+
Queue<String> queue = JcTools.newFixedSizeQueue(10);
6262
queue.add("Test1");
6363
queue.add("Test2");
6464

@@ -79,7 +79,10 @@ void newFixedSize_MpscQueue() {
7979
Queue<Object> objects = JcTools.newFixedSizeQueue(capacity);
8080

8181
// Assert
82-
assertThat(objects).isInstanceOf(MpscArrayQueue.class);
82+
assertThat(objects)
83+
.satisfiesAnyOf(
84+
queue -> assertThat(queue).isInstanceOf(MpscArrayQueue.class),
85+
queue -> assertThat(queue).isInstanceOf(ArrayBlockingQueue.class));
8386
}
8487

8588
@Test
@@ -92,7 +95,7 @@ void capacity_MpscQueue() {
9295
long queueSize = JcTools.capacity(queue);
9396

9497
// Assert
95-
assertThat(queueSize).isGreaterThan(capacity);
98+
assertThat(queueSize).isGreaterThanOrEqualTo(capacity);
9699
}
97100

98101
@Test

0 commit comments

Comments
 (0)