Skip to content

NPE in BeanDefinitionLoader when loading non-Class sources and XML support is disabled #22696

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

dreis2211
Copy link
Contributor

Hi,

I was playing with spring.xml.ignore and found an NPE when loading CharSequence sources.

The following application snippet should reproduce the error

@SpringBootApplication
public class Application {

	public static void main(String[] args) {
		SpringApplication app = new SpringApplication(Application.class);
		app.setSources(Set.of("test", "source"));
		app.run(args);
	}

}

When running java -Dspring.xml.ignore=true -jar app.jar the following NPE occurs:

java.lang.NullPointerException: null
        at org.springframework.boot.BeanDefinitionLoader.load(BeanDefinitionLoader.java:192)
        at org.springframework.boot.BeanDefinitionLoader.load(BeanDefinitionLoader.java:155)
        at org.springframework.boot.BeanDefinitionLoader.load(BeanDefinitionLoader.java:136)
        at org.springframework.boot.SpringApplication.load(SpringApplication.java:691)
        at org.springframework.boot.SpringApplication.prepareContext(SpringApplication.java:392)
        at org.springframework.boot.SpringApplication.run(SpringApplication.java:314)

This is due to the fact that xmlReader is null when XML support is disabled. As the reader is only used to get the Environment, I think we can workaround this by just using the scanner field. They should have the same Environment here.

Unfortunately, it's a bit cumbersome to write a test for this. I would need to set the final xmlReader field to null via reflection, which is what I try to avoid usually. Nonetheless, let me know If I should add a test like described that mimics XML support being disabled.

Cheers,
Christoph

P.S.: I tried setting spring.xml.ignore in my application.properties first, which didn't work. I think we would need to use Binder facilities to make this work. Maybe that's worth evaluating.

@spring-projects-issues spring-projects-issues added the status: waiting-for-triage An issue we've not yet triaged label Aug 1, 2020
@snicoll snicoll added type: bug A general bug and removed status: waiting-for-triage An issue we've not yet triaged labels Aug 1, 2020
@snicoll snicoll added this to the 2.2.x milestone Aug 1, 2020
@wilkinsona wilkinsona modified the milestones: 2.2.x, 2.4.0-M2 Aug 3, 2020
@wilkinsona wilkinsona added type: regression A regression from a previous release and removed type: bug A general bug labels Aug 3, 2020
@wilkinsona
Copy link
Member

wilkinsona commented Aug 3, 2020

Unfortunately, it's a bit cumbersome to write a test for this.

We talked a bit about this last week. We're increasingly uncomfortable with these Graal-specific changes that are hard to test. Our assumption had been that any problems would be detected by the Spring Graal Native project but it appears to have been missed there too.

@sdeleuze I think we need to revisit our approach here. We either need to figure how how to test these changes in Boot (without relying on Graal) or we need a commitment on your side to test things.

@wilkinsona wilkinsona changed the title Fix NPE in BeanDefinitionLoader when XML support is disabled NPE in BeanDefinitionLoader when loading non-Class sources and XML support is disabled Aug 3, 2020
@wilkinsona
Copy link
Member

wilkinsona commented Aug 3, 2020

With a change to make ModifiedClasspathExtension public, I think we can test this with the following:

package org.springframework.boot;

import org.junit.jupiter.api.AfterAll;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;

import org.springframework.beans.factory.BeanDefinitionStoreException;
import org.springframework.boot.testsupport.classpath.ModifiedClassPathExtension;
import org.springframework.context.support.StaticApplicationContext;

import static org.assertj.core.api.Assertions.assertThatExceptionOfType;

@ExtendWith(ModifiedClassPathExtension.class)
class IgnoringXmlBeanDefinitionLoaderTests {

    @BeforeAll
    static void ignoreXml() {
        System.setProperty("spring.xml.ignore", "true");
    }

    @AfterAll
    static void enableXml() {
        System.clearProperty("spring.xml.ignore");
    }

    @Test
    void whenXmlSupportIsDisabledXmlSourcesAreRejected() {
        assertThatExceptionOfType(BeanDefinitionStoreException.class)
                .isThrownBy(() -> new BeanDefinitionLoader(new StaticApplicationContext(),
                        "classpath:org/springframework/boot/sample-beans.xml").load())
                .withMessage("Cannot load XML bean definitions when XML support is disabled");
    }

}

@wilkinsona wilkinsona added the for: merge-with-amendments Needs some changes when we merge label Aug 3, 2020
@wilkinsona wilkinsona self-assigned this Aug 3, 2020
@wilkinsona
Copy link
Member

Thanks very much, @dreis2211.

@dreis2211
Copy link
Contributor Author

That's a neat trick to use ModifiedClassPathExtension, @wilkinsona . Given that I wrote this thing, I could have come up with that as well, I guess. ;-)

@dreis2211
Copy link
Contributor Author

I wonder if we should rather introduce a new annotation ForkedClassPath instead of making ModifiedClassPathExtension public btw.

@wilkinsona
Copy link
Member

I wonder if we should rather introduce a new annotation ForkedClassPath instead of making ModifiedClassPathExtension public btw.

I was in two minds about that, and I still am really. I don't have any objection to introducing a custom annotation. I guess we'd want to prevent @ForkedClassPath being used alongside @ClassPathExclusions or @ClassPathOverrides to make it clear that it is intended for the situation where you just need a "copy" of the class path rather than a modified variant of it.

@dreis2211
Copy link
Contributor Author

Mind if I experiment with that if I find the time?

@wilkinsona
Copy link
Member

Not at all. That'd be great!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
for: merge-with-amendments Needs some changes when we merge type: regression A regression from a previous release
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants