Skip to content
This repository was archived by the owner on Feb 23, 2023. It is now read-only.

ResolvableType - java.lang.IllegalArgumentException: Mismatched number of generics specified #1401

Closed
a-locatelli opened this issue Dec 23, 2021 · 9 comments
Assignees
Labels
type: bug A general bug
Milestone

Comments

@a-locatelli
Copy link

a-locatelli commented Dec 23, 2021

I'm trying to build an application using cloud gcp data datastore.
This app expose a rest api endpoint for receiving data and make a call to gcp datastore for saving data.

RestController:

@RestController
public class DevicesApiController implements DevicesApi {
	
	@Autowired
	private DeviceManager deviceManager;
	
	@Autowired
	private DeviceRepository deviceRepository;
	
	@Override
	public ResponseEntity<Void> postDevice(@Valid DevicePost devicePost) {
		Device device = deviceManager.createDevice(devicePost);
		deviceRepository.save(device);
		
		HttpHeaders responseHeaders = new HttpHeaders();
		responseHeaders.set(HttpHeaders.LOCATION, null);
		
		return ResponseEntity.status(HttpStatus.CREATED).headers(responseHeaders).build();
	}

}

The DeviceRepository is an interface which extend the DatastoreRepository:

public interface DeviceRepository extends DatastoreRepository<Device, Long> {
	
}

While running the application normally doesn't make problem, when i build the native image i get this error from spring-aot-maven-plugin:

[INFO] --- spring-aot-maven-plugin:0.11.0:generate (generate) @ smartstore-backend ---
2021-12-23 15:01:31.723  INFO 54492 --- [           main] o.s.a.build.ContextBootstrapContributor  : Detected application class: org.foo.SmartstoreBackendApplication
2021-12-23 15:01:31.726  INFO 54492 --- [           main] o.s.a.build.ContextBootstrapContributor  : Processing application context
2021-12-23 15:01:32.304  INFO 54492 --- [           main] .s.d.r.c.RepositoryConfigurationDelegate : Bootstrapping Spring Data Datastore repositories in DEFAULT mode.
2021-12-23 15:01:32.332  INFO 54492 --- [           main] .s.d.r.c.RepositoryConfigurationDelegate : Finished Spring Data repository scanning in 25 ms. Found 1 Datastore repository interfaces.
java.lang.IllegalArgumentException: Mismatched number of generics specified
        at org.springframework.util.Assert.isTrue(Assert.java:121)
        at org.springframework.core.ResolvableType.forClassWithGenerics(ResolvableType.java:1088)
        at org.springframework.data.RepositoryFactoryBeanPostProcessor.resolveRepositoryFactoryBeanTypeIfNecessary(RepositoryFactoryBeanPostProcessor.java:66)
        at org.springframework.data.RepositoryFactoryBeanPostProcessor.postProcessBeanDefinition(RepositoryFactoryBeanPostProcessor.java:52)
        at org.springframework.context.annotation.BuildTimeBeanDefinitionsRegistrar.lambda$postProcessBeanDefinitions$2(BuildTimeBeanDefinitionsRegistrar.java:83)
        at java.base/java.util.ArrayList.forEach(ArrayList.java:1541)
        at org.springframework.context.annotation.BuildTimeBeanDefinitionsRegistrar.postProcessBeanDefinitions(BuildTimeBeanDefinitionsRegistrar.java:83)
        at org.springframework.context.annotation.BuildTimeBeanDefinitionsRegistrar.processBeanDefinitions(BuildTimeBeanDefinitionsRegistrar.java:67)
        at org.springframework.aot.context.bootstrap.generator.ApplicationContextAotProcessor.process(ApplicationContextAotProcessor.java:94)
        at org.springframework.aot.build.ContextBootstrapContributor.contribute(ContextBootstrapContributor.java:80)
        at org.springframework.aot.build.BootstrapCodeGenerator.generate(BootstrapCodeGenerator.java:91)
        at org.springframework.aot.build.BootstrapCodeGenerator.generate(BootstrapCodeGenerator.java:71)
        at org.springframework.aot.build.GenerateBootstrapCommand.call(GenerateBootstrapCommand.java:107)
        at org.springframework.aot.build.GenerateBootstrapCommand.call(GenerateBootstrapCommand.java:42)
        at picocli.CommandLine.executeUserObject(CommandLine.java:1953)
        at picocli.CommandLine.access$1300(CommandLine.java:145)
        at picocli.CommandLine$RunLast.executeUserObjectOfLastSubcommandWithSameParent(CommandLine.java:2352)
        at picocli.CommandLine$RunLast.handle(CommandLine.java:2346)
        at picocli.CommandLine$RunLast.handle(CommandLine.java:2311)
        at picocli.CommandLine$AbstractParseResultHandler.execute(CommandLine.java:2179)
        at picocli.CommandLine.execute(CommandLine.java:2078)
        at org.springframework.aot.build.GenerateBootstrapCommand.main(GenerateBootstrapCommand.java:112)

The method snippet (from org.springframework.core.ResolvableType )

public static ResolvableType forClassWithGenerics(Class<?> clazz, ResolvableType... generics) {
	Assert.notNull(clazz, "Class must not be null");
	Assert.notNull(generics, "Generics array must not be null");
	TypeVariable<?>[] variables = clazz.getTypeParameters();
	Assert.isTrue(variables.length == generics.length, "Mismatched number of generics specified");
	Type[] arguments = new Type[generics.length];
	for (int i = 0; i < generics.length; i++) {
		ResolvableType generic = generics[i];
		Type argument = (generic != null ? generic.getType() : null);
		arguments[i] = (argument != null && !(argument instanceof TypeVariable) ? argument : variables[i]);
	}
	ParameterizedType syntheticType = new SyntheticParameterizedType(clazz, arguments);
	return forType(syntheticType, new TypeVariablesVariableResolver(variables, generics));
}

From debugging the error: java.lang.IllegalArgumentException: Mismatched number of generics specified is raised when processing class org.springframework.cloud.gcp.data.datastore.repository.support.DatastoreRepositoryFactoryBean.

Method variables involved:
clazz = org.springframework.cloud.gcp.data.datastore.repository.support.DatastoreRepositoryFactoryBean

variables = 
- [0]	TypeVariableImpl<D>  (id=372) -> DatastoreRepository entity class
- [1]	TypeVariableImpl<D>  (id=373)-> DatastoreRepository entity id
generics = 
- [0]	ResolvableType  (id=395) -> DeviceRepository (which extends DatastoreRespository)
- [1]	ResolvableType  (id=396) -> DatastoreRepository entity class
- [2]	ResolvableType  (id=397) -> DatastoreRepository entity id

The problem seems to be the generics[0] because it is the interface itself.

pom.xml <build>:

<build>
	<sourceDirectory>src/main/java</sourceDirectory>
		<plugins>
			<plugin>
				<groupId>org.springframework.boot</groupId>
				<artifactId>spring-boot-maven-plugin</artifactId>
				<configuration>
					<classifier>${repackage.classifier}</classifier>
					<image>
						<builder>paketobuildpacks/builder:tiny</builder>
						<env>
							<BP_NATIVE_IMAGE>true</BP_NATIVE_IMAGE>
							<BP_NATIVE_IMAGE_BUILD_ARGUMENTS>
								--initialize-at-build-time=com.google.api.client.json.GenericJson
							</BP_NATIVE_IMAGE_BUILD_ARGUMENTS>
						</env>
					</image>
				</configuration>
			</plugin>
			<plugin>
				<groupId>org.springframework.experimental</groupId>
				<artifactId>spring-aot-maven-plugin</artifactId>
				<version>${spring-aot.version}</version>
				<executions>
					<execution>
						<id>generate</id>
						<goals>
							<goal>generate</goal>
						</goals>
					</execution>
				</executions>
				<configuration>
					<removeYamlSupport>true</removeYamlSupport>
					<removeSpelSupport>true</removeSpelSupport>
				</configuration>
				<dependencies>
					<dependency>
						<groupId>org.springframework.experimental</groupId>
						<artifactId>spring-aot</artifactId>
						<version>${spring-native.version}</version>
					</dependency>
				</dependencies>
			</plugin>
		</plugins>
	</build>

VERSIONS:

  • java: 11
  • spring-boot: 2.6.2
  • spring-native: 0.11.1
  • spring-cloud: 2021.0.0
  • spring-cloud-gcp: 1.2.8.RELEASE
  • spring-aot: 0.11.0
@spring-projects-issues spring-projects-issues added the status: waiting-for-triage An issue we've not yet triaged or decided on label Dec 23, 2021
@snicoll snicoll added type: bug A general bug and removed status: waiting-for-triage An issue we've not yet triaged or decided on labels Dec 26, 2021
@snicoll snicoll added this to the 0.11.2 milestone Dec 26, 2021
@snicoll
Copy link
Contributor

snicoll commented Dec 26, 2021

Thanks for the report. Can you share a small sample that we can run ourselves?

@snicoll snicoll added the status: waiting-for-feedback We need additional information before we can continue label Dec 26, 2021
@ch4mpy
Copy link

ch4mpy commented Dec 27, 2021

PR #1408 reproduces similar issue with a minimal change set from data-jpa sample

@sdeleuze sdeleuze mentioned this issue Jan 3, 2022
@spring-projects-issues spring-projects-issues added status: feedback-provided Feedback has been provided and removed status: waiting-for-feedback We need additional information before we can continue labels Jan 4, 2022
@christophstrobl christophstrobl self-assigned this Jan 12, 2022
@christophstrobl christophstrobl linked a pull request Jan 12, 2022 that will close this issue
@snicoll
Copy link
Contributor

snicoll commented Jan 12, 2022

I think the problem is that the FactoryBean that handles the repository type might not be the one we thought it would be. DatastoreRepositoryFactoryBean has two generics, not three.

@snicoll
Copy link
Contributor

snicoll commented Jan 12, 2022

I've reproduced the problem in a unit test.

@snicoll snicoll assigned snicoll and unassigned christophstrobl Jan 13, 2022
@snicoll
Copy link
Contributor

snicoll commented Jan 13, 2022

This turned out to be quite tricky to fix. I have a first draft that I'd like to review once more.

@ch4mpy
Copy link

ch4mpy commented Jan 14, 2022

@snicoll I have a new exception (but stil related to generics) with latest snapshot on api/order-api module from this repo:

2022-01-13 18:03:33.451  INFO 9144 --- [           main] .s.d.r.c.RepositoryConfigurationDelegate : Finished Spring Data repository scanning in 152 ms. Found 1 JPA repository interfa
ces.
java.lang.IllegalArgumentException: Type N not found on org.springframework.data.jpa.repository.support.JpaRepositoryFactoryBean<T, S, ID>
    at org.springframework.data.ParameterizedTypeMapper.findMatchingTypeVariable(ParameterizedTypeMapper.java:129)
    at org.springframework.data.ParameterizedTypeMapper.mapGeneric(ParameterizedTypeMapper.java:114)
    at org.springframework.data.ParameterizedTypeMapper.getTargetGenericIndexFor(ParameterizedTypeMapper.java:108)
    at org.springframework.data.ParameterizedTypeMapper.mapGenericTypes(ParameterizedTypeMapper.java:94)
    at org.springframework.data.RepositoryFactoryBeanPostProcessor.resolveRepositoryFactoryBeanType(RepositoryFactoryBeanPostProcessor.java:81)
    at org.springframework.data.RepositoryFactoryBeanPostProcessor.resolveRepositoryFactoryBeanTypeIfNecessary(RepositoryFactoryBeanPostProcessor.java:60)
    at org.springframework.data.RepositoryFactoryBeanPostProcessor.postProcessBeanDefinition(RepositoryFactoryBeanPostProcessor.java:52)
    at org.springframework.context.annotation.BuildTimeBeanDefinitionsRegistrar.lambda$postProcessBeanDefinitions$2(BuildTimeBeanDefinitionsRegistrar.java:83)
    at java.base/java.util.ArrayList.forEach(ArrayList.java:1511)
    at org.springframework.context.annotation.BuildTimeBeanDefinitionsRegistrar.postProcessBeanDefinitions(BuildTimeBeanDefinitionsRegistrar.java:83)
    at org.springframework.context.annotation.BuildTimeBeanDefinitionsRegistrar.processBeanDefinitions(BuildTimeBeanDefinitionsRegistrar.java:67)
    at org.springframework.aot.context.bootstrap.generator.ApplicationContextAotProcessor.process(ApplicationContextAotProcessor.java:95)
    at org.springframework.aot.build.ContextBootstrapContributor.contribute(ContextBootstrapContributor.java:80)
    at org.springframework.aot.build.BootstrapCodeGenerator.generate(BootstrapCodeGenerator.java:91)
    at org.springframework.aot.build.BootstrapCodeGenerator.generate(BootstrapCodeGenerator.java:71)
    at org.springframework.aot.build.GenerateBootstrapCommand.call(GenerateBootstrapCommand.java:107)
    at org.springframework.aot.build.GenerateBootstrapCommand.call(GenerateBootstrapCommand.java:42)
    at picocli.CommandLine.executeUserObject(CommandLine.java:1953)
    at picocli.CommandLine.access$1300(CommandLine.java:145)
    at picocli.CommandLine$RunLast.executeUserObjectOfLastSubcommandWithSameParent(CommandLine.java:2352)
    at picocli.CommandLine$RunLast.handle(CommandLine.java:2346)
    at picocli.CommandLine$RunLast.handle(CommandLine.java:2311)
    at picocli.CommandLine$AbstractParseResultHandler.execute(CommandLine.java:2179)
    at picocli.CommandLine.execute(CommandLine.java:2078)
    at org.springframework.aot.build.GenerateBootstrapCommand.main(GenerateBootstrapCommand.java:112)
[ERROR]
org.apache.maven.plugin.MojoExecutionException: Could not exec java
    at org.springframework.aot.maven.AbstractBootstrapMojo.forkJvm (AbstractBootstrapMojo.java:187)
    at org.springframework.aot.maven.GenerateMojo.execute (GenerateMojo.java:132)
    at org.apache.maven.plugin.DefaultBuildPluginManager.executeMojo (DefaultBuildPluginManager.java:137)
    at org.apache.maven.lifecycle.internal.MojoExecutor.execute (MojoExecutor.java:210)
    at org.apache.maven.lifecycle.internal.MojoExecutor.execute (MojoExecutor.java:156)
    at org.apache.maven.lifecycle.internal.MojoExecutor.execute (MojoExecutor.java:148)
    at org.apache.maven.lifecycle.internal.LifecycleModuleBuilder.buildProject (LifecycleModuleBuilder.java:117)
    at org.apache.maven.lifecycle.internal.LifecycleModuleBuilder.buildProject (LifecycleModuleBuilder.java:81)
    at org.apache.maven.lifecycle.internal.builder.singlethreaded.SingleThreadedBuilder.build (SingleThreadedBuilder.java:56)
    at org.apache.maven.lifecycle.internal.LifecycleStarter.execute (LifecycleStarter.java:128)
    at org.apache.maven.DefaultMaven.doExecute (DefaultMaven.java:305)
    at org.apache.maven.DefaultMaven.doExecute (DefaultMaven.java:192)
    at org.apache.maven.DefaultMaven.execute (DefaultMaven.java:105)
    at org.apache.maven.cli.MavenCli.execute (MavenCli.java:957)
    at org.apache.maven.cli.MavenCli.doMain (MavenCli.java:289)
    at org.apache.maven.cli.MavenCli.main (MavenCli.java:193)
    at jdk.internal.reflect.NativeMethodAccessorImpl.invoke0 (Native Method)
    at jdk.internal.reflect.NativeMethodAccessorImpl.invoke (NativeMethodAccessorImpl.java:77)
    at jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke (DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke (Method.java:568)
    at org.codehaus.plexus.classworlds.launcher.Launcher.launchEnhanced (Launcher.java:282)
    at org.codehaus.plexus.classworlds.launcher.Launcher.launch (Launcher.java:225)
    at org.codehaus.plexus.classworlds.launcher.Launcher.mainWithExitCode (Launcher.java:406)
    at org.codehaus.plexus.classworlds.launcher.Launcher.main (Launcher.java:347)
Caused by: org.apache.maven.plugin.MojoExecutionException: Bootstrap code generator finished with exit code: 1
    at org.springframework.aot.maven.AbstractBootstrapMojo.forkJvm (AbstractBootstrapMojo.java:184)
    at org.springframework.aot.maven.GenerateMojo.execute (GenerateMojo.java:132)
    at org.apache.maven.plugin.DefaultBuildPluginManager.executeMojo (DefaultBuildPluginManager.java:137)
    at org.apache.maven.lifecycle.internal.MojoExecutor.execute (MojoExecutor.java:210)
    at org.apache.maven.lifecycle.internal.MojoExecutor.execute (MojoExecutor.java:156)
    at org.apache.maven.lifecycle.internal.MojoExecutor.execute (MojoExecutor.java:148)
    at org.apache.maven.lifecycle.internal.LifecycleModuleBuilder.buildProject (LifecycleModuleBuilder.java:117)
    at org.apache.maven.lifecycle.internal.LifecycleModuleBuilder.buildProject (LifecycleModuleBuilder.java:81)
    at org.apache.maven.lifecycle.internal.builder.singlethreaded.SingleThreadedBuilder.build (SingleThreadedBuilder.java:56)
    at org.apache.maven.lifecycle.internal.LifecycleStarter.execute (LifecycleStarter.java:128)
    at org.apache.maven.DefaultMaven.doExecute (DefaultMaven.java:305)
    at org.apache.maven.DefaultMaven.doExecute (DefaultMaven.java:192)
    at org.apache.maven.DefaultMaven.execute (DefaultMaven.java:105)
    at org.apache.maven.cli.MavenCli.execute (MavenCli.java:957)
    at org.apache.maven.cli.MavenCli.doMain (MavenCli.java:289)
    at org.apache.maven.cli.MavenCli.main (MavenCli.java:193)
    at jdk.internal.reflect.NativeMethodAccessorImpl.invoke0 (Native Method)
    at jdk.internal.reflect.NativeMethodAccessorImpl.invoke (NativeMethodAccessorImpl.java:77)
    at jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke (DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke (Method.java:568)
    at org.codehaus.plexus.classworlds.launcher.Launcher.launchEnhanced (Launcher.java:282)
    at org.codehaus.plexus.classworlds.launcher.Launcher.launch (Launcher.java:225)
    at org.codehaus.plexus.classworlds.launcher.Launcher.mainWithExitCode (Launcher.java:406)
    at org.codehaus.plexus.classworlds.launcher.Launcher.main (Launcher.java:347)
[ERROR] [org.springframework.aot.maven.AbstractBootstrapMojo.forkJvm(AbstractBootstrapMojo.java:187), org.springframework.aot.maven.GenerateMojo.execute(GenerateMojo.java:1
32), org.apache.maven.plugin.DefaultBuildPluginManager.executeMojo(DefaultBuildPluginManager.java:137), org.apache.maven.lifecycle.internal.MojoExecutor.execute(MojoExecutor.java:210
), org.apache.maven.lifecycle.internal.MojoExecutor.execute(MojoExecutor.java:156), org.apache.maven.lifecycle.internal.MojoExecutor.execute(MojoExecutor.java:148), org.apache.maven.
lifecycle.internal.LifecycleModuleBuilder.buildProject(LifecycleModuleBuilder.java:117), org.apache.maven.lifecycle.internal.LifecycleModuleBuilder.buildProject(LifecycleModuleBuilde
r.java:81), org.apache.maven.lifecycle.internal.builder.singlethreaded.SingleThreadedBuilder.build(SingleThreadedBuilder.java:56), org.apache.maven.lifecycle.internal.LifecycleStarte
r.execute(LifecycleStarter.java:128), org.apache.maven.DefaultMaven.doExecute(DefaultMaven.java:305), org.apache.maven.DefaultMaven.doExecute(DefaultMaven.java:192), org.apache.maven
.DefaultMaven.execute(DefaultMaven.java:105), org.apache.maven.cli.MavenCli.execute(MavenCli.java:957), org.apache.maven.cli.MavenCli.doMain(MavenCli.java:289), org.apache.maven.cli.
MavenCli.main(MavenCli.java:193), java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method), java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(Nativ
eMethodAccessorImpl.java:77), java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43), java.base/java.lang.reflect.Method.invoke(Meth
od.java:568), org.codehaus.plexus.classworlds.launcher.Launcher.launchEnhanced(Launcher.java:282), org.codehaus.plexus.classworlds.launcher.Launcher.launch(Launcher.java:225), org.co
dehaus.plexus.classworlds.launcher.Launcher.mainWithExitCode(Launcher.java:406), org.codehaus.plexus.classworlds.launcher.Launcher.main(Launcher.java:347)]

@snicoll snicoll reopened this Jan 14, 2022
@snicoll
Copy link
Contributor

snicoll commented Jan 14, 2022

@ch4mpy thanks for testing the snapshot!

@sdeleuze sdeleuze removed the status: feedback-provided Feedback has been provided label Jan 25, 2022
@VadimT7
Copy link

VadimT7 commented Jul 6, 2022

Any updates on @ch4mpy's latest error?
I have the same one even after removing Mockito (as was recommended in a different issue)

@snicoll
Copy link
Contributor

snicoll commented Jul 6, 2022

As far as I am aware, I did fix that (see the reopen). If you're experiencing an issue still please open a new issue with a small sample that we can run ourselves.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
type: bug A general bug
Development

Successfully merging a pull request may close this issue.

7 participants