Skip to content

A way to disable the optimization for filling the stack traces #3638

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Conversation

neboskreb
Copy link
Contributor

@neboskreb neboskreb commented Apr 25, 2025

This PR addresses issue #3639

This PR allows to disable the optimization for filling the stack traces on platforms where it is not available (e.g. on Android).

The developer of the port to such platform shall call PrivateSecurityManagerStackTraceUtil.disable() before any loggins is printed, e.g. during the configuration phase.

For this reason, the visibility of PrivateSecurityManagerStackTraceUtil was increased to public.

The capability of instantiated PrivateSecurityManager is checked, and a faulty candidate (e.g. on Android) is rejected, thus rendering the optimization not enabled.

Copy link

github-actions bot commented Apr 25, 2025

Job Requested goals Build Tool Version Build Outcome Build Scan®
build-macos-latest clean install 3.9.8 Build Scan PUBLISHED
build-ubuntu-latest clean install 3.9.8 Build Scan PUBLISHED
build-windows-latest clean install 3.9.8 Build Scan PUBLISHED
Generated by gradle/develocity-actions

Copy link
Contributor

@ppkarwasz ppkarwasz left a comment

Choose a reason for hiding this comment

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

@neboskreb,

Thank you for your contribution!

I think that PrivateSecurityManagerStackTraceUtil should always be disabled on Android. Similarly to #3071 I would simply disable the class if the java.vendor system property contains Android.

@ppkarwasz ppkarwasz moved this from To triage to Waiting for user in Log4j bug tracker Apr 25, 2025
@ppkarwasz ppkarwasz self-assigned this Apr 25, 2025
@neboskreb
Copy link
Contributor Author

@ppkarwasz , as you mentioned in the other ticket, this PR seems to be on a critical path.

But I'm not quite sure I understand what is the blocker here, sorry. What can I do to unblock the progress?

@ppkarwasz
Copy link
Contributor

But I'm not quite sure I understand what is the blocker here, sorry. What can I do to unblock the progress?

Currently you are proposing a new PrivateSecurityManagerStackTraceUtil#disable() method that can be used by other libraries to disable the security manager.

My point is that PrivateSecurityManagerStackTraceUtil will never work on Android, so we might as well always disable the class on that platform. More concretely the static initialization code:

static {
PrivateSecurityManager psm;
try {
final SecurityManager sm = System.getSecurityManager();
if (sm != null) {
sm.checkPermission(new RuntimePermission("createSecurityManager"));
}
psm = new PrivateSecurityManager();
} catch (final SecurityException ignored) {
psm = null;
}
SECURITY_MANAGER = psm;
}

should:

  • check if the Java property java.vendor contains the word Android.
  • if we are running on Android set SECURITY_MANAGER to null.
  • otherwise proceed as before.

@neboskreb
Copy link
Contributor Author

Ah, I see your point. Let me quickly draft the solution.

@neboskreb
Copy link
Contributor Author

Okay, so checking the runtime platform appears ugly, because it requires copying the code from SystemUtils (which is available in core but not here in api) or referring to core as dependency - neither being a great idea...

Therefore I decided, instead, to go with checking the capability of the instantiated PrivateSecurityManager. This looks more robust, because it's not the platform (we wouldn't be excited to add check isOsXxxx for every possible beast in the zoo) but the capability we're interested in.

I have completely rewritten the solution, and replaced the PR description.
@ppkarwasz please check and say what you think?

@neboskreb neboskreb force-pushed the fix/2.x/disable-stack-trace-optimization-on-android branch from 8c823ce to 425a37a Compare April 30, 2025 12:30
@ppkarwasz
Copy link
Contributor

Okay, so checking the runtime platform appears ugly, because it requires copying the code from SystemUtils (which is available in core but not here in api) or referring to core as dependency - neither being a great idea...

I think that this should be enough:

boolean isAndroid = System.getProperty("java.vendor", "").contains("Android");

If we already know the System.getSecurityManager() is null, we don't even have to use a try...catch, since the getProperty() method can not throw.

@neboskreb
Copy link
Contributor Author

Apparently, we have different approaches. Feel free to close this PR if you don't plan to merge it. After all, it proposes one of many possible ways to fix #3639; you can always draft a better solution yourself, especially that you already have the bigger part of it.

@neboskreb neboskreb force-pushed the fix/2.x/disable-stack-trace-optimization-on-android branch from 425a37a to 40d66ed Compare April 30, 2025 18:55
@neboskreb
Copy link
Contributor Author

Re-formatted the code to make Spotless happy. Hopefully, this turns the build green.

This is the most I can do, I'm sorry.

Copy link
Contributor

@ppkarwasz ppkarwasz left a comment

Choose a reason for hiding this comment

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

LGTM, thanks!

@ppkarwasz
Copy link
Contributor

@neboskreb,

Thanks! In order to merge the PR:

  • All the commits must be signed with a GPG recognized by Github. If you didn't do it before, could you add a GPG key to your Github account and then rebase this PR, so all commits get signed?
  • Could you add a changelog file to src/changelog/.2.x.x? You can use one of the files already there as template.

@neboskreb
Copy link
Contributor Author

  • Could you add a changelog file to src/changelog/.2.x.x? You can use one of the files already there as template.

Done

  • All the commits must be signed with a GPG recognized by Github. If you didn't do it before, could you add a GPG key to your Github account and then rebase this PR, so all commits get signed?

Hmmm, git log --show-signature 40d66ed7 shows that the commit is signed but I don't see the checkmark next to it here on Github... Is this normal? If not, what can I do to rectify?

@ppkarwasz
Copy link
Contributor

I don't see the signatures, I even checked the raw data.
Try

git rebase -f -i -S 2.x
git push -f

…fully) supporting SecurityManager do not poison the stack trace.
@neboskreb neboskreb force-pushed the fix/2.x/disable-stack-trace-optimization-on-android branch from cf4a361 to 87a81da Compare April 30, 2025 20:24
@neboskreb
Copy link
Contributor Author

This helped!
Thanks a lot!

@ppkarwasz ppkarwasz merged commit db0360d into apache:2.x May 1, 2025
11 checks passed
@github-project-automation github-project-automation bot moved this from Waiting for user to Done in Log4j bug tracker May 1, 2025
@ppkarwasz
Copy link
Contributor

ppkarwasz commented May 1, 2025

@neboskreb,

Thanks a lot! Now the Android support is almost as good as the JVM support! 💯

IIRC there is still one location-related feature that breaks on Android: LogManager.getLogger() will fail, since the Java 8 version of StackLocator relies on the absent sun.reflect.Reflection class and Android does not support Multi-Release JARs, so it doesn't use the Java 11 version of StackLocator.

If you know of a smart way to fix that, let me know.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
Status: Done
Development

Successfully merging this pull request may close these issues.

2 participants