Skip to content

Simplify always-override resource registration in AOT #35855

Closed as not planned
Closed as not planned

Description

@odrotbohm

Assuming a BeanFactoryInitializationAotProcessor would like to register a resource that's not dependent on the ConfigurableListableBeanFactory handed into the method but globally applicable. It would return a BeanFactoryInitializationAotContribution that'd do something like this with the GenerationContext provided:

context.getGeneratedFiles().addResourceFile("someLocation", "someContent");

This fails for a subsequent run of the AOT process if the build hasn't cleaned out someLocation beforehand, as the resource creation rejects overwriting files by default. To reliably always create or replace the file to be created, one has to resort to this:

context.getGeneratedFiles().handleFile(Kind.RESOURCE, "someLocation", it -> {

	var resource = new ByteArrayResource("someContent".getBytes(StandardCharsets.UTF_8));

	if (it.exists()) {
		it.override(resource);
	} else {
		it.create(resource);
	}
});

This is pretty involved compared to the simple call to ….addResourceFile(…). I wonder if it makes sense to add method overloads that allow triggering the always-override behavior. Or, alternatively, flip the default to allow the override and rely on users with more advanced needs to simply use the already existing API that gives them more control over the file creation.

Related tickets

Activity

  1. added
    in: coreIssues in core modules (aop, beans, core, context, expression)
    theme: aotAn issue related to Ahead-of-time processing
    on Nov 19, 2025
  2. snicoll commented on Nov 20, 2025

    @snicoll
    Member

    This fails for a subsequent run of the AOT process if the build hasn't cleaned out someLocation beforehand

    You are misunderstanding the problem. The problem occurs if several application contexts are handled within a single invocation of the AOT process. The OP in the linked issue hinted at that with "As soon as I set the Spring Actuator port to a different port". This will effectively trigger a separate context for the Actuator and you end up in the problem that the contribution is called again for the second context.

    You also have, as we've discussed, this situation almost all the time for processing tests as they rarely operate on a single ApplicationContext arrangement.

    flip the default to allow the override and rely on users with more advanced needs to simply use the already existing API that gives them more control over the file creation.

    The problem with that suggestion is that it hides the problem to those generating a file that does change based on the state of the application context. It would also be inconsistent with what happens with source code (If you try to add a class that already exists, it should fail). I don't know if it's more obvious that classes can't be overridden but resources can.

    Wondering what @philwebb thinks since he's been working on the initial implementation.

  3. added and removed on Nov 20, 2025
  4. odrotbohm commented on Nov 20, 2025

    @odrotbohm
    MemberAuthor

    I completely understand that extra care has to be taken in case there is a relationship between the config file and the ApplicationContext the AOT process is running for. I'd just argue that if that's the case, the implementor knows about that and wouldn't use the simple addResourceFile(…) methods anyway.

    To quote myself:

    … a resource that's not dependent on the ConfigurableListableBeanFactory handed into the method but globally applicable.

    What I tried to express with the statement is that such a relationship does not exist in my case and that it would be nice if the simpler case (no relationship) would not require the more complex arrangement.

    If you think that the more complex case is the common one, what would be the use case for the simple registration methods? In other words: in which case would one ever call addResourceFile(…) at all? Because even for unique (per-AC) file names, a second run of the AOT plugin would fail, wouldn't it?

  5. snicoll commented on Nov 20, 2025

    @snicoll
    Member

    I completely understand that extra care has to be taken in case there is a relationship between the config file and the ApplicationContext the AOT process is running for.

    At this time, this is the default. We may or may not agree that's a good default and that's why I asked feedback from Phil.

    I'd just argue that if that's the case, the implementor knows about that

    That's not how this works. You should not care when you create a class and that's what's done by default. The main problem here is that we don't do that for resources and we should. I've opened #35862.

    As for the rest of the comment, let's stick with what the default is currently. If we decide to change it, it'll auto-fix the problem you are reporting but I don't think it is as easy as it sounds. Certainly not without #35862 implemented. That being said, I agree things are broken at the moment.

    Something else that's interesting is the concept of an "Application" contribution that would be more explicit than just adding a file.

  6. philwebb commented on Dec 1, 2025

    @philwebb
    Member

    Sorry, I only just got to this one in my overflowing inbox. It's been quite a while since I looked at this code, but I think keeping the default behavior consistent for addResourceFile and addSourceFile would be my preference (especially as they all end up calling addFile.

    I guess a new method with override support could be added, but perhaps #35862 will negate the need for that.

  7. snicoll commented on Dec 8, 2025

    @snicoll
    Member

    Thanks @philwebb. I am going to close this one in favour of #35862 that should provide a more explicit api for the use case @odrotbohm mentioned.

  8. added
    status: supersededAn issue that has been superseded by another
    and removed on Dec 8, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    in: coreIssues in core modules (aop, beans, core, context, expression)status: supersededAn issue that has been superseded by anothertheme: aotAn issue related to Ahead-of-time processing

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions