spring-projects / spring-projects/spring-boot

Reduce XML classes in native image when using Logback

Open
#33,324 9 comments 1 reaction 0 assignees View on GitHub

Nobody has claimed this yet.

status: blocked theme: aot type: enhancement
Dominant language
Java
Stars
81.5k
Forks
42.7k
Avg merge
2d 4h
Merged PRs (30d)
65

Description

As discussed with @wilkinsona, in an empty Spring Boot application with just spring-boot-starter compiled to native, the only place where XML parsing is reachable is ch.qos.logback.core.joran.GenericXMLConfigurator#doConfigure. The impact on the footprint and compile time is quite significant (as usual with XML on native images).

On my Linux machine, the RSS memory after startup is 36.58M when XML is reachable and 34.15M without (difference of 2.43M or 6.64%). You can see the impressive diff of the 675 additional classes included in the native image in this gist.

To track how it is reachable, I compile the native image with a META-INF/native-image/native-image.properties with Args = -H:ReportAnalysisForbiddenType=ch.qos.logback.core.joran.event.SaxEventRecorder and it gives me the following stacktrace:

Fatal error: com.oracle.graal.pointsto.util.AnalysisError$ParsingError: Error encountered while parsing ch.qos.logback.core.joran.GenericXMLConfigurator.populateSaxEventRecorder(org.xml.sax.InputSource) 
Parsing context:
   at ch.qos.logback.core.joran.GenericXMLConfigurator.populateSaxEventRecorder(GenericXMLConfigurator.java:177)
   at ch.qos.logback.core.joran.GenericXMLConfigurator.doConfigure(GenericXMLConfigurator.java:159)
   at ch.qos.logback.core.joran.GenericXMLConfigurator.doConfigure(GenericXMLConfigurator.java:122)
   at ch.qos.logback.core.joran.GenericXMLConfigurator.doConfigure(GenericXMLConfigurator.java:65)
   at org.springframework.boot.logging.logback.LogbackLoggingSystem.configureByResourceUrl(LogbackLoggingSystem.java:260)
   at org.springframework.boot.logging.logback.LogbackLoggingSystem.loadConfiguration(LogbackLoggingSystem.java:237)
   at org.springframework.boot.logging.AbstractLoggingSystem.initializeWithConventions(AbstractLoggingSystem.java:80)
   at org.springframework.boot.logging.AbstractLoggingSystem.initialize(AbstractLoggingSystem.java:60)
   at org.springframework.boot.context.logging.LoggingApplicationListener.initializeSystem(LoggingApplicationListener.java:332)
   at org.springframework.boot.context.logging.LoggingApplicationListener.initialize(LoggingApplicationListener.java:298)
   at org.springframework.boot.context.logging.LoggingApplicationListener.onApplicationEnvironmentPreparedEvent(LoggingApplicationListener.java:246)
   at org.springframework.boot.context.logging.LoggingApplicationListener.onApplicationEvent(LoggingApplicationListener.java:223)

Sadly, GenericXMLConfigurator#doConfigure is final so we can't override it in a proper way, so to make the XML parsing not reachable for testing purpose, I used this substitution:

@TargetClass(className = "ch.qos.logback.core.joran.GenericXMLConfigurator")
final class Target_GenericXmlConfigurator {

	@Substitute
	public final void doConfigure(URL url) throws JoranException {
	}
}

I don't expect this to be fixable before Spring Boot 3.0 GA, but maybe we could do something about it in 3.0.x. We could potentially raise a related issue on Logback side to see if there is a possibility to make this method non final, or to ask a refactoring that would allow us to make the XML parsing not reachable on native image (either out of the box or via an override on Boot side).

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start with org.springframework.boot.logging.logback.LogbackLoggingSystem.configureByResourceUrl and the call chain to ch.qos.logback.core.joran.GenericXMLConfigurator#doConfigure. Review the native-image substitution example and the reported reachable type, then determine a viable Spring Boot or Logback change. Done means XML parsing is no longer reachable for the stated native application and the native image has fewer classes and lower footprint.

Written by the indexing model from the issue text.

Assessment

Tech stack
java, spring-boot
Domain
build-system, performance
Issue type
Refactor
Difficulty
5/5
Estimated time
Over a week
Activity status
Active
Clarity
Needs clarification
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.