Skip to content
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

@ImportTestcontainers doesn't work with AOT #42891

Open
wants to merge 1 commit into
base: 3.3.x
Choose a base branch
from

Conversation

nosan
Copy link
Contributor

@nosan nosan commented Oct 25, 2024

#42875

Since Bean's InstanceSupplier cannot be used during the AOT process, I added BeanRegistrationAotProcessor to replace it.

If a container's field is inaccessible, the generated code will be:

@Generated
public class GraalmavenApplicationTests__TestContext001_BeanDefinitions {

	/**
	 * Get the bean instance for 'importTestContainer.task.graalmaven.GraalmavenApplicationTests.mongoDbContainer'.
	 */
	private static MongoDBContainer getMongoDbContainerInstance() {
		try {
			Class<?> clazz = ClassUtils.forName("task.graalmaven.GraalmavenApplicationTests",
					GraalmavenApplicationTests__TestContext001_BeanDefinitions.class.getClassLoader());
			Field field = ReflectionUtils.findField(clazz, "mongoDbContainer");
			Assert.notNull(field, "Field 'mongoDbContainer' is not found");
			ReflectionUtils.makeAccessible(field);
			Object container = ReflectionUtils.getField(field, null);
			Assert.notNull(container, "Container field 'mongoDbContainer' must not have a null value");
			return (MongoDBContainer) container;
		} catch (ClassNotFoundException ex) {
			throw new RuntimeException(ex);
		}
	}

	/**
	 * Get the bean definition for 'mongoDbContainer'.
	 */
	public static BeanDefinition getMongoDbContainerBeanDefinition() {
		RootBeanDefinition beanDefinition = new RootBeanDefinition(MongoDBContainer.class);
		beanDefinition.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
		beanDefinition.setInstanceSupplier(
				GraalmavenApplicationTests__TestContext001_BeanDefinitions::getMongoDbContainerInstance);
		return beanDefinition;
	}

}

If a container's field is accessible, the generated code will be:

@Generated
public class GraalmavenApplicationTests__TestContext001_BeanDefinitions {
  /**
   * Get the bean definition for 'mongoDbContainer'.
   */
  public static BeanDefinition getMongoDbContainerBeanDefinition() {
    RootBeanDefinition beanDefinition = new RootBeanDefinition(MyContainer.class);
    beanDefinition.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
    beanDefinition.setInstanceSupplier(() -> GraalmavenApplicationTests.mongoDbContainer);
    return beanDefinition;
  }
}

An alternative way is FactoryBean instead of InstanceSupplier.

The target branch is 3.2.x

@spring-projects-issues spring-projects-issues added the status: waiting-for-triage An issue we've not yet triaged label Oct 25, 2024
@nosan nosan force-pushed the 42875 branch 4 times, most recently from 2b1535f to e9795bb Compare October 27, 2024 10:00
@nosan nosan marked this pull request as draft October 27, 2024 12:41
@nosan nosan marked this pull request as ready for review October 27, 2024 20:09
@nosan nosan force-pushed the 42875 branch 3 times, most recently from 91e3273 to cd63de3 Compare October 27, 2024 21:54
@nosan
Copy link
Contributor Author

nosan commented Oct 27, 2024

Unfortunately, handling the bean instance supplier for container fields only addresses
half of the issue. The more problematic part involves handling @DynamicPropertySource
methods. These @DynamicPropertySource methods need to be generated and invoked within
the AOT environment. To achieve this, I introduced
DynamicPropertySourceBeanFactoryInitializationAotProcessor

@nosan nosan force-pushed the 42875 branch 3 times, most recently from 008de18 to 65e3548 Compare October 28, 2024 11:09
@nosan nosan marked this pull request as draft October 28, 2024 14:06
@nosan nosan marked this pull request as ready for review October 28, 2024 16:46
@nosan
Copy link
Contributor Author

nosan commented Oct 28, 2024

@philwebb
Could I kindly ask you to do a quick review of this PR, and let me know if I'm in the right direction?

@nosan nosan force-pushed the 42875 branch 4 times, most recently from 7c38b50 to e6b1c3e Compare October 29, 2024 12:37
@nosan nosan changed the base branch from 3.2.x to 3.3.x December 2, 2024 21:54
@philwebb
Copy link
Member

philwebb commented Dec 3, 2024

Sorry for the delay @nosan, I haven't had the chance to look in detail at this one yet.

@nosan
Copy link
Contributor Author

nosan commented Dec 3, 2024

@philwebb
No worries! I completely understand that you’ve been focusing on higher-priority tasks.

Add TestcontainersBeanRegistrationAotProcessor that
replaces InstanceSupplier of Container by either direct field usage or
a reflection equivalent.

Add DynamicPropertySourceBeanFactoryInitializationAotProcessor that
generates methods for each annotated @DynamicPropertySource method

See spring-projectsgh-42891

Signed-off-by: Dmytro Nosan <dimanosan@gmail.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
status: waiting-for-triage An issue we've not yet triaged
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants