Linux开机启动Java应用时Log4J在sudo等命令下失效问题求助
Hey Jakub, let's break down what's happening here and walk through fixes for your issue.
First: The Reflection Warning (Non-Critical)
That sun.reflect.Reflection.getCallerClass is not supported warning is a known compatibility quirk with Log4J 2.x running on Java 9+. It doesn't directly cause your app to crash, but if it's bothering you, upgrading to Log4J 2.17.0 or later will resolve this warning—those versions include fixes for Java 9+ reflection API changes.
The Fatal Issue: NullPointerException in Logger Initialization
Your core problem is the NPE at me.inao.discordbot.util.Logger.<init>(Logger.java:28), and this almost always ties to working directory or permission problems when using runuser/sudo/su to switch users. Here's why:
- When you switch users with these commands, the default working directory isn't your app's root folder. Log4J can't find its configuration file (like
log4j2.xmlorlog4j.properties) or can't access relative-path log directories. - The user you switch to may lack read permissions for Log4J config files or write permissions for the log output directory, causing initialization to fail silently and trigger an NPE.
Step-by-Step Fixes
Force the Correct Working Directory
Always switch to your app's directory before launching the jar. For example, if your app lives in/opt/bufferBot, use commands like:# Using sudo sudo -u your_app_user sh -c "cd /opt/bufferBot && java -jar bufferBot.jar" # Using runuser runuser -l your_app_user -c "cd /opt/bufferBot && java -jar bufferBot.jar"This ensures Log4J can locate relative-path config and log files.
Fix File/Directory Permissions
Make sure the target user has proper access to your app's files:# Replace bufferbot_user with your actual app user chown -R bufferbot_user:bufferbot_user /opt/bufferBot # Give read/write access to the logs directory chmod -R 750 /opt/bufferBot/logsUse Absolute Paths in Log4J Config
Update your Log4J configuration to use absolute paths for log outputs (e.g., changelogs/bot.logto/opt/bufferBot/logs/bot.log). This removes dependency on the working directory entirely.Explicitly Specify Log4J Config Path
Add a JVM argument to point directly to your Log4J config file to eliminate any ambiguity:java -Dlog4j.configurationFile=/opt/bufferBot/log4j2.xml -jar bufferBot.jar
Is This a Programming Habit or Bug?
This isn't a "bad programming habit"—it's a common deployment oversight! Local testing usually runs from the app's root directory, so relative paths work, but server environments with user switching break that assumption. That said, you could improve your Logger class by adding explicit checks for config file existence or directory access, which would throw a more descriptive error instead of an NPE, making debugging easier.
Have Others Seen This?
Absolutely! This is one of the most frequent issues reported for Java apps running as non-login users on Linux. Most threads trace back to working directory mismatches or permission gaps when using sudo/su/runuser.
内容的提问来源于stack exchange,提问作者inao

