Skip to content
Open
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
20 changes: 17 additions & 3 deletions app/src/main/scripts/unixStartScript.txt
Original file line number Diff line number Diff line change
Expand Up @@ -43,9 +43,6 @@ cd "\$SAVED" >/dev/null
APP_NAME="${applicationName}"
APP_BASE_NAME=`basename "\$0"`

# Add default JVM options here. You can also use JAVA_OPTS and ${optsEnvironmentVar} to pass JVM options to this script.
DEFAULT_JVM_OPTS=${defaultJvmOpts}

# Use the maximum available, or set MAX_FD != -1 to use that value.
MAX_FD="maximum"

Expand Down Expand Up @@ -105,6 +102,23 @@ Please set the JAVA_HOME variable in your environment to match the
location of your Java installation."
fi

# Detect Java version
JAVA_VERSION=\$("\$JAVACMD" -version 2>&1 | awk -F '"' '/version/ {print \$2}' | sed 's/^1\\.//' | cut -d'.' -f1)

# Validate it's a number
if ! [ "\$JAVA_VERSION" -eq "\$JAVA_VERSION" ] 2>/dev/null; then
die "Unable to determine Java version"
fi

# Add default JVM options here. You can also use JAVA_OPTS and ${optsEnvironmentVar} to pass JVM options to this script.
if [ "\$JAVA_VERSION" -ge 25 ]; then
DEFAULT_JVM_OPTS=@DEFAULT_JVM_OPTS_25@
Copy link

Copilot AI Oct 28, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The placeholder @DEFAULT_JVM_OPTS_25@ uses a different format than ${defaultJvmOpts}. This inconsistency in placeholder syntax could indicate a template processing issue or incomplete implementation. Verify that both placeholders are correctly replaced during the build process.

Suggested change
DEFAULT_JVM_OPTS=@DEFAULT_JVM_OPTS_25@
DEFAULT_JVM_OPTS=${defaultJvmOpts25}

Copilot uses AI. Check for mistakes.
elif [ "\$JAVA_VERSION" -ge 21 ]; then
DEFAULT_JVM_OPTS=${defaultJvmOpts}
else
die "Java version must be at least 21 (detected: \$JAVA_VERSION)"
fi

# Increase the maximum file descriptors if we can.
if [ "\$cygwin" = "false" -a "\$darwin" = "false" -a "\$nonstop" = "false" ] ; then
MAX_FD_LIMIT=`ulimit -H -n`
Expand Down
40 changes: 34 additions & 6 deletions app/src/main/scripts/windowsStartScript.txt
Original file line number Diff line number Diff line change
Expand Up @@ -33,15 +33,12 @@ set APP_HOME=%DIRNAME%${appHomeRelativePath}
@rem Resolve any "." and ".." in APP_HOME to make it shorter.
for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi

@rem Add default JVM options here. You can also use JAVA_OPTS and ${optsEnvironmentVar} to pass JVM options to this script.
set DEFAULT_JVM_OPTS=${defaultJvmOpts}

@rem Find java.exe
if defined JAVA_HOME goto findJavaFromJavaHome

set JAVA_EXE=java.exe
%JAVA_EXE% -version >NUL 2>&1
if "%ERRORLEVEL%" == "0" goto execute
if "%ERRORLEVEL%" == "0" goto detectJavaVersion

echo.
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
Expand All @@ -55,7 +52,7 @@ goto fail
set JAVA_HOME=%JAVA_HOME:"=%
set JAVA_EXE=%JAVA_HOME%/bin/java.exe

if exist "%JAVA_EXE%" goto execute
if exist "%JAVA_EXE%" goto detectJavaVersion

echo.
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
Expand All @@ -65,9 +62,40 @@ echo location of your Java installation.

goto fail

:detectJavaVersion
@rem Detect Java version
for /f "tokens=3" %%g in ('"%JAVA_EXE%" -version 2^>^&1 ^| findstr /i "version"') do (
set JAVA_VERSION_STRING=%%g
)
set JAVA_VERSION_STRING=%JAVA_VERSION_STRING:"=%

@rem Extract major version (handle both 1.8 and 11+ format)
for /f "delims=. tokens=1-2" %%v in ("%JAVA_VERSION_STRING%") do (
if "%%v"=="1" (
set JAVA_VERSION=%%w
) else (
set JAVA_VERSION=%%v
)
)

@rem Validate Java version
if not defined JAVA_VERSION (
echo Unable to determine Java version
goto fail
)

@rem Add default JVM options here. You can also use JAVA_OPTS and ${optsEnvironmentVar} to pass JVM options to this script.
if %JAVA_VERSION% GEQ 25 (
set DEFAULT_JVM_OPTS=@DEFAULT_JVM_OPTS_25@
) else if %JAVA_VERSION% GEQ 21 (
set DEFAULT_JVM_OPTS=${defaultJvmOpts}
Copy link

Copilot AI Oct 28, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The placeholder @DEFAULT_JVM_OPTS_25@ appears to be a template variable that should be replaced during the build process, but ${defaultJvmOpts} uses a different placeholder format. This inconsistency could lead to confusion. Ensure both placeholders follow the same convention or document why they differ.

Suggested change
set DEFAULT_JVM_OPTS=${defaultJvmOpts}
set DEFAULT_JVM_OPTS=@DEFAULT_JVM_OPTS_21@

Copilot uses AI. Check for mistakes.
) else (
echo Java version must be at least 21 (detected: %JAVA_VERSION%)
goto fail
)

:execute
@rem Setup the command line

set CLASSPATH=$classpath
<% if ( mainClassName.startsWith('--module ') ) { %>set MODULE_PATH=$modulePath<% } %>

Expand Down
60 changes: 44 additions & 16 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -702,7 +702,8 @@ application {
"--add-exports",
"java.base/jdk.internal.misc=ALL-UNNAMED",
"--add-opens",
"java.base/java.nio=ALL-UNNAMED"
"java.base/java.nio=ALL-UNNAMED",
"--enable-native-access=ALL-UNNAMED"
]
}

Expand All @@ -715,11 +716,46 @@ run {
}
}

def tweakStartScript(createScriptTask) {
def defaultJvmOpts21 = application.applicationDefaultJvmArgs + [
"-XX:G1ConcRefinementThreads=2",
"-XX:G1HeapWastePercent=15",
"-XX:MaxGCPauseMillis=100",
"-XX:StartFlightRecording,settings=default.jfc",
"-Xlog:jfr*=off"
]

def defaultJvmOpts25 = defaultJvmOpts21 + [
"-XX:+UseCompactObjectHeaders",
"-XX:MaxHeapFreeRatio=30",
"-XX:MinHeapFreeRatio=10",
"-XX:GCTimeRatio=50",
"-XX:-ShrinkHeapInSteps"
]

def untunedJvmOpts = application.applicationDefaultJvmArgs

def evmToolJvmOpts = [
"-Dsecp256k1.randomize=false"
]

def serializeDefaultJvmOpts(opts) {
return "'" + opts.collect{ '"' + it.replaceAll(/"/, '\\"').replaceAll(/\$/, '\\$') + '"' }.join(' ') + "'"
}

def tweakStartScript(createScriptTask, jvmOptsForJava25) {
def shortenWindowsClasspath = { line ->
line.replaceAll(/^set CLASSPATH=.*$/, "set CLASSPATH=%APP_HOME%/lib/*")
}

// Replace Java 25 opts placeholder - must be before BESU_HOME replacement
createScriptTask.unixScript.text = createScriptTask.unixScript.text
.replace('@DEFAULT_JVM_OPTS_25@', jvmOptsForJava25)

// For Windows, remove the outer single quotes
def windowsJvmOpts = jvmOptsForJava25.replaceAll(/^'|'$/, '')
createScriptTask.windowsScript.text = createScriptTask.windowsScript.text
.replace('@DEFAULT_JVM_OPTS_25@', windowsJvmOpts)

createScriptTask.unixScript.text = createScriptTask.unixScript.text.replace('BESU_HOME', '\$APP_HOME')
createScriptTask.windowsScript.text = createScriptTask.windowsScript.text.replace('BESU_HOME', '%~dp0..')

Expand All @@ -732,40 +768,32 @@ def tweakStartScript(createScriptTask) {
}

startScripts {
defaultJvmOpts = application.applicationDefaultJvmArgs + [
"-XX:G1ConcRefinementThreads=2",
"-XX:G1HeapWastePercent=15",
"-XX:MaxGCPauseMillis=100",
"-XX:StartFlightRecording,settings=default.jfc",
"-Xlog:jfr*=off"
]
defaultJvmOpts = defaultJvmOpts21
unixStartScriptGenerator.template = resources.text.fromFile("${projectDir}/app/src/main/scripts/unixStartScript.txt")
windowsStartScriptGenerator.template = resources.text.fromFile("${projectDir}/app/src/main/scripts/windowsStartScript.txt")
doLast { tweakStartScript(startScripts) }
doLast { tweakStartScript(startScripts, serializeDefaultJvmOpts(defaultJvmOpts25)) }
}

task untunedStartScripts(type: CreateStartScripts) {
mainClass = 'org.hyperledger.besu.Besu'
classpath = startScripts.classpath
outputDir = startScripts.outputDir
applicationName = 'besu-untuned'
defaultJvmOpts = application.applicationDefaultJvmArgs
defaultJvmOpts = untunedJvmOpts
unixStartScriptGenerator.template = resources.text.fromFile("${projectDir}/app/src/main/scripts/unixStartScript.txt")
windowsStartScriptGenerator.template = resources.text.fromFile("${projectDir}/app/src/main/scripts/windowsStartScript.txt")
doLast { tweakStartScript(untunedStartScripts) }
doLast { tweakStartScript(untunedStartScripts, serializeDefaultJvmOpts(untunedJvmOpts)) }
}

task evmToolStartScripts(type: CreateStartScripts) {
mainClass = 'org.hyperledger.besu.evmtool.EvmTool'
classpath = startScripts.classpath
outputDir = startScripts.outputDir
applicationName = 'evmtool'
defaultJvmOpts = [
"-Dsecp256k1.randomize=false"
]
defaultJvmOpts = evmToolJvmOpts
unixStartScriptGenerator.template = resources.text.fromFile("${projectDir}/app/src/main/scripts/unixStartScript.txt")
windowsStartScriptGenerator.template = resources.text.fromFile("${projectDir}/app/src/main/scripts/windowsStartScript.txt")
doLast { tweakStartScript(evmToolStartScripts) }
doLast { tweakStartScript(evmToolStartScripts, serializeDefaultJvmOpts(evmToolJvmOpts)) }
}

task autocomplete(type: JavaExec) {
Expand Down
26 changes: 17 additions & 9 deletions docker/Dockerfile
Original file line number Diff line number Diff line change
@@ -1,3 +1,9 @@
# syntax=docker/dockerfile:1

# Stage: Use Eclipse Temurin JRE
FROM eclipse-temurin:25-jre AS java-base

# Stage: Final Besu image
FROM ubuntu:24.04
ARG VERSION="dev"
ENV NO_PROXY_CACHE="-o Acquire::BrokenProxy=true -o Acquire::http::No-Cache=true -o Acquire::http::Pipeline-Depth=0"
Expand All @@ -6,23 +12,25 @@ ENV NO_PROXY_CACHE="-o Acquire::BrokenProxy=true -o Acquire::http::No-Cache=true
RUN apt-get update $NO_PROXY_CACHE && \
# $NO_PROXY_CACHE must not be used here or otherwise will trigger a hadolint error
apt-get -o Acquire::BrokenProxy=true -o Acquire::http::No-Cache=true -o Acquire::http::Pipeline-Depth=0 \
--no-install-recommends -q --assume-yes install openjdk-21-jre-headless=21* libjemalloc-dev=5.* adduser=3* && \
--no-install-recommends -q --assume-yes install libjemalloc-dev=5.* && \
# Clean apt cache
apt-get clean && \
rm -rf /var/cache/apt/archives/* /var/cache/apt/archives/partial/* && \
rm -rf /var/lib/apt/lists/* && \
# Starting from version 23.10, Ubuntu comes with an "ubuntu" user with uid 1000. We need 1000 for besu.
userdel ubuntu 2>/dev/null || true && rm -rf /home/ubuntu && \
# Ensure we use a stable UID for besu, as file permissions are tied to UIDs.
adduser --uid 1000 --disabled-password --gecos "" --home /opt/besu besu && \
useradd --uid 1000 --create-home --home-dir /opt/besu --shell /bin/bash besu && \
Copy link

Copilot AI Oct 28, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The change from adduser to useradd alters the user creation tool. While useradd is more portable across distributions, adduser is a higher-level Debian/Ubuntu tool that was previously used. Ensure this change doesn't introduce compatibility issues with any scripts or tooling that might depend on the user creation method or expect specific group memberships that adduser automatically configures.

Suggested change
useradd --uid 1000 --create-home --home-dir /opt/besu --shell /bin/bash besu && \
adduser --uid 1000 --home /opt/besu --shell /bin/bash --disabled-password --gecos "" besu && \

Copilot uses AI. Check for mistakes.
chown besu:besu /opt/besu && \
chmod 0755 /opt/besu

# Copy JRE from the java-base stage
COPY --from=java-base /opt/java/openjdk /opt/java/openjdk

ARG BESU_USER=besu
USER ${BESU_USER}
WORKDIR /opt/besu


COPY --chown=besu:besu besu /opt/besu/
# support for pyroscope
ADD --chown=besu:besu https://github.com/grafana/pyroscope-java/releases/download/v2.1.2/pyroscope.jar /opt/besu/pyroscope/pyroscope.jar
Expand All @@ -43,14 +51,14 @@ ENV PYROSCOPE_CONFIGURATION_FILE=/etc/besu/pyroscope.properties
EXPOSE 8545 8546 8547 8550 8551 30303

# defaults for host interfaces
ENV BESU_RPC_HTTP_HOST 0.0.0.0
ENV BESU_RPC_WS_HOST 0.0.0.0
ENV BESU_GRAPHQL_HTTP_HOST 0.0.0.0
ENV BESU_PID_PATH "/tmp/pid"
ENV BESU_RPC_HTTP_HOST="0.0.0.0"
ENV BESU_RPC_WS_HOST="0.0.0.0"
ENV BESU_GRAPHQL_HTTP_HOST="0.0.0.0"
Copy link

Copilot AI Oct 28, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[nitpick] Adding quotes around environment variable values is inconsistent with the previous unquoted style and unnecessary for simple values. While functionally equivalent, this creates inconsistency in the Dockerfile's style. Consider keeping the original unquoted format unless there's a specific reason for the change.

Suggested change
ENV BESU_GRAPHQL_HTTP_HOST="0.0.0.0"
ENV BESU_GRAPHQL_HTTP_HOST=0.0.0.0

Copilot uses AI. Check for mistakes.
ENV BESU_PID_PATH="/tmp/pid"
ENV OTEL_RESOURCE_ATTRIBUTES="service.name=besu,service.version=$VERSION"
ENV JAVA_HOME="/opt/java/openjdk"

ENV OLDPATH="${PATH}"
ENV PATH="/opt/besu/bin:${OLDPATH}"
ENV PATH="/opt/besu/bin:${JAVA_HOME}/bin:${PATH}"

# The entry script just sets permissions as needed based on besu config
# and is replaced by the besu process running as besu user.
Expand Down
27 changes: 20 additions & 7 deletions ethereum/evmtool/src/main/docker/Dockerfile
Original file line number Diff line number Diff line change
@@ -1,4 +1,9 @@
# syntax=docker/dockerfile:1

# Use Eclipse Temurin JRE
FROM eclipse-temurin:25-jre AS java-base

# Stage 2: Final Besu image
FROM ubuntu:24.04
ARG VERSION="dev"
ENV NO_PROXY_CACHE="-o Acquire::BrokenProxy=true -o Acquire::http::No-Cache=true -o Acquire::http::Pipeline-Depth=0"
Expand All @@ -7,21 +12,29 @@ ENV NO_PROXY_CACHE="-o Acquire::BrokenProxy=true -o Acquire::http::No-Cache=true
RUN apt-get update $NO_PROXY_CACHE && \
# $NO_PROXY_CACHE must not be used here or otherwise will trigger a hadolint error
apt-get -o Acquire::BrokenProxy=true -o Acquire::http::No-Cache=true -o Acquire::http::Pipeline-Depth=0 \
--no-install-recommends -q --assume-yes install openjdk-21-jre-headless=21* adduser=3* && \
# Clean apt cache \
--no-install-recommends -q --assume-yes install libjemalloc-dev=5.* && \
# Clean apt cache
apt-get clean && \
rm -rf /var/cache/apt/archives/* /var/cache/apt/archives/partial/* && \
rm -rf /var/lib/apt/lists/* && \
# Creating a user for besu
adduser --disabled-password --gecos "" --home /opt/besu besu && \
chown besu:besu /opt/besu
# Starting from version 23.10, Ubuntu comes with an "ubuntu" user with uid 1000. We need 1000 for besu.
userdel ubuntu 2>/dev/null || true && rm -rf /home/ubuntu && \
# Ensure we use a stable UID for besu, as file permissions are tied to UIDs.
useradd --uid 1000 --create-home --home-dir /opt/besu-evmtool --shell /bin/bash besu && \
chown besu:besu /opt/besu-evmtool && \
chmod 0755 /opt/besu-evmtool

# Copy JRE from the jre-base stage
COPY --from=java-base /opt/java/openjdk /opt/java/openjdk

USER besu
ARG BESU_USER=besu
USER ${BESU_USER}
WORKDIR /opt/besu-evmtool

COPY --chown=besu:besu besu-evmtool /opt/besu-evmtool/

ENV PATH="/opt/besu-evmtool/bin:${PATH}"
ENV JAVA_HOME="/opt/java/openjdk"
ENV PATH="$JAVA_HOME/bin:/opt/besu-evmtool/bin:${PATH}"
ENTRYPOINT ["evmtool"]

# Build-time metadata as defined at http://label-schema.org
Expand Down