Context

I tried to build native Spring boot artifact and spent hours to struggle with build failed obscure error. I was not able to spot the build failed root cause because of the too generic error message 'className' must be a valid identifier

This error message prevents me to fix the problem

I did not found any related issue to this specific point.

Observation

GeneratedFiles.getClassNamePath(String className) error message is too generic

Exception in thread "main" java.lang.IllegalArgumentException: 'className' must be a valid identifier
    at org.springframework.util.Assert.isTrue(Assert.java:122)
    at org.springframework.aot.generate.GeneratedFiles.getClassNamePath(GeneratedFiles.java:164)

Proposal

Put className value in the error message

Exception in thread "main" java.lang.IllegalArgumentException: 'className' com/example/HelloWorld.java must be a valid identifier
    at org.springframework.util.Assert.isTrue(Assert.java:122)
    at org.springframework.aot.generate.GeneratedFiles.getClassNamePath(GeneratedFiles.java:164)

Comment From: pivotal-cla

@PiotrFLEURY Please sign the Contributor License Agreement!

Click here to manually synchronize the status of this Pull Request.

See the FAQ for frequently asked questions.

Comment From: pivotal-cla

@PiotrFLEURY Thank you for signing the Contributor License Agreement!

Comment From: snicoll

@PiotrFLEURY thanks for the PR. Can you share how you ended up in that situation?

Comment From: snicoll

Thank you for making your first contribution to Spring Framework, @PiotrFLEURY. Interested to understand more what caused this as there might be something else that needs fixing to prevent that from happening.

Comment From: PiotrFLEURY

Thank you for making your first contribution to Spring Framework, @PiotrFLEURY. Interested to understand more what caused this as there might be something else that needs fixing to prevent that from happening.

Thanks to you @snicoll for accepting my contribution.

The pull request was closed but I see that you merged polished modification on main branch. Thanks for the polishing. Never saw this kind of flow before. Just for my curiosity, can you explain how did you that ?

I will give more details as soon as I fully understand what was the root cause of the build problem.

Comment From: PiotrFLEURY

@PiotrFLEURY thanks for the PR. Can you share how you ended up in that situation?

I finally spotted the root cause thanks to this new detailed message 🚀

It can easily reproduced.

Steps to reproduce

start.spring.io

Generates a new Spring boot project using Maven + Kotlin + Graalvm native support.

Required versions

spring-boot-starter-parent:3.1.5 java:17 kotlin:1.8.22

Code

Create a data class named MyConfig and ommit package directive


import org.springframework.boot.context.properties.ConfigurationProperties
import org.springframework.context.annotation.Configuration

@Configuration
@ConfigurationProperties(prefix = "config")
data class MyConfig(
    var apps: Map<String, String>
)

Now add @EnableConfigurationProperties annotation to the SpringBoot application class and import a config class

package com.example.demokotlinnative

import MyConfig
import org.springframework.boot.autoconfigure.SpringBootApplication
import org.springframework.boot.context.properties.EnableConfigurationProperties
import org.springframework.boot.runApplication

@SpringBootApplication
@EnableConfigurationProperties(MyConfig::class)
class DemoKotlinNativeApplication

fun main(args: Array<String>) {
    runApplication<DemoKotlinNativeApplication>(*args)
}

Try build native image

Run mvn -Pnative -DskipTests native:compile

Issue

Spring aot processor fails with the following message

Exception in thread "main" java.lang.IllegalArgumentException: 'className' must be a valid identifier, got '.MyConfig__BeanDefinitions'
    at org.springframework.util.Assert.isTrue(Assert.java:122)
    at org.springframework.aot.generate.GeneratedFiles.getClassNamePath(GeneratedFiles.java:164)

Expected behavior

As a missing package directive is a warning should the build pass with warning ?

Or should it fail with a dedicated message asking to fix the missing package directive ?

Everything works fine with the package directive inside the MyConfig class

Hope this will help @snicoll

Feel free to ask for any further info

Comment From: snicoll

Thanks @PiotrFLEURY. This is largely a Kotlin-specific problem as Java does not allow to import classes from the default package. I've reproduced based on your snippet above, please watch https://github.com/spring-projects/spring-framework/issues/31628 for updates.