You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Command not registered if @Profile(..) is used and activatedΒ #1325
changed the title [-]Shell 4: Command not registered if @Profile(..) is used and activated[/-][+]Command not registered if @Profile(..) is used and activated[/+]on Mar 26, 2026
I've just tried to reproduce the issue to help fix the problem, but I'm not sure if my configuration is correct because I'm not able to replicate the issue with the following steps.
If I am not mistaken, the issue is about class level Profile configuration.
So considering the following configuration:
packageorg.springframework.shell.samples.helloworld.boot;
importorg.springframework.context.annotation.Profile;
importorg.springframework.shell.core.command.annotation.Command;
importorg.springframework.shell.core.command.annotation.Option;
importorg.springframework.stereotype.Component;
@Component@Profile("greetings")
publicclassGreetingCommands {
@Command(name = "hello", description = "Say hello to a given name", group = "Greetings",
help = "A command that greets the user with 'Hello ${name}!'. Usage: hello [-n | --name]=<name>")
publicvoidsayHello(@Option(shortName = 'n', longName = "name", description = "the name of the person to greet",
defaultValue = "World") Stringname) {
System.out.println("Hello " + name + "!");
}
}
I believe I validated this bug by mistake, and here is why: when I tested this back then, I used the non-boot version of the hello world sample (since the OP did not mention Boot). And here is the quick sample I used:
packageorg.springframework.shell.samples.helloworld;
importorg.springframework.context.ApplicationContext;
importorg.springframework.context.annotation.AnnotationConfigApplicationContext;
importorg.springframework.context.annotation.Profile;
importorg.springframework.shell.core.ShellRunner;
importorg.springframework.shell.core.command.annotation.Command;
importorg.springframework.shell.core.command.annotation.EnableCommand;
importorg.springframework.shell.core.command.annotation.Option;
importorg.springframework.stereotype.Component;
@EnableCommand(SpringShellApplication.class)
publicclassSpringShellApplication {
publicstaticvoidmain(String[] args) throwsException {
ApplicationContextcontext = newAnnotationConfigApplicationContext(SpringShellApplication.class);
ShellRunnerrunner = context.getBean(ShellRunner.class);
runner.run(args);
}
@Component@Profile("greeting")
staticclassGreetingCommands {
@Command(name = "hello", description = "Say hello to a given name", group = "Greetings",
help = "A command that greets the user with 'Hello ${name}!'. Usage: hello [-n | --name]=<name>")
publicvoidsayHello(@Option(shortName = 'n', longName = "name",
description = "the name of the person to greet", defaultValue = "World") Stringname) {
System.out.println("Hello " + name + "!");
}
@Command(name = "goodbye", description = "Say goodbye to a given name", group = "Greetings",
help = "A command that says goodbye to the user with 'Goodbye ${name}!'. Usage: goodbye [-n | --name]=<name>")
publicvoidsayGoodbye(@Option(shortName = 'n', longName = "name",
description = "the name of the person to say goodbye to", defaultValue = "World") Stringname) {
System.out.println("Goodbye " + name + "!");
}
}
}
Running this sample with the greeting profile active does not show the commands, so I thought the bug report is valid.. but my sample was actually incorrect, it should have been like:
--@EnableCommand(SpringShellApplication.class)++@EnableCommand(SpringShellApplication.GreetingCommands.class)
public class SpringShellApplication {
...
}
which works as expected with profiles. I just re-tested with nested and non-nested classes and profile honouring seems to work with boot and non-boot samples.
@tkrah Can you please provide a minimal complete sample that we can use to reproduce the issue? Are you sure your IndexCommand is not excluded from classpath scanning and correctly defined as a bean?
@Component
@Profile("solr")
public class IndexCommand {
Build it with:
./gradlew build -x check
and start the shell with:
./demo-shell.sh
This will print:
:: Spring Boot :: (v4.0.5)
2026-04-07T18:32:22.679+02:00 INFO 432919 --- [demo] [ main] com.example.demo.DemoApplication : Starting DemoApplication v0.0.1-SNAPSHOT using Java 25.0.2 with PID 432919 (/home/tkrah/Development/src/git/demo/demo/build/libs/demo-0.0.1-SNAPSHOT.jar started by tkrah in /home/tkrah/Development/src/git/demo/demo)
2026-04-07T18:32:22.683+02:00 INFO 432919 --- [demo] [ main] com.example.demo.DemoApplication : The following 3 profiles are active: "g_dev", "default", "solr"
2026-04-07T18:32:23.416+02:00 WARN 432919 --- [demo] [ main] o.s.security.core.userdetails.User : User.withDefaultPasswordEncoder() is considered unsafe for production and is only intended for sample applications.
2026-04-07T18:32:23.865+02:00 INFO 432919 --- [demo] [ main] com.example.demo.DemoApplication : Started DemoApplication in 1.645 seconds (process running for 2.198)
$>help
AVAILABLE COMMANDS
Built-In Commands
help: Display help about available commands
script: Execute commands from a script file
quit, exit: Exit the shell
clear: Clear the terminal screen
version: Show version info
$>hello
Command hello not found
AVAILABLE COMMANDS
Built-In Commands
help: Display help about available commands
script: Execute commands from a script file
quit, exit: Exit the shell
clear: Clear the terminal screen
version: Show version info
The command is not registered.
Now remove the @Profile("solr") from the IndexCommand class, rebuild the jar and restart the shell, you will see this:
:: Spring Boot :: (v4.0.5)
2026-04-07T18:32:56.034+02:00 INFO 433522 --- [demo] [ main] com.example.demo.DemoApplication : Starting DemoApplication v0.0.1-SNAPSHOT using Java 25.0.2 with PID 433522 (/home/tkrah/Development/src/git/demo/demo/build/libs/demo-0.0.1-SNAPSHOT.jar started by tkrah in /home/tkrah/Development/src/git/demo/demo)
2026-04-07T18:32:56.039+02:00 INFO 433522 --- [demo] [ main] com.example.demo.DemoApplication : The following 3 profiles are active: "g_dev", "default", "solr"
2026-04-07T18:32:56.752+02:00 WARN 433522 --- [demo] [ main] o.s.security.core.userdetails.User : User.withDefaultPasswordEncoder() is considered unsafe for production and is only intended for sample applications.
2026-04-07T18:32:57.222+02:00 INFO 433522 --- [demo] [ main] com.example.demo.DemoApplication : Started DemoApplication in 1.673 seconds (process running for 2.202)
$>help
AVAILABLE COMMANDS
Built-In Commands
help: Display help about available commands
script: Execute commands from a script file
quit, exit: Exit the shell
clear: Clear the terminal screen
version: Show version info
Greetings
hello: Say hello to a given name
Now the command is registered.
In both cases, the profiles active are:
The following 3 profiles are active: "g_dev", "default", "solr"
If I am doing something wrong here, I am open to suggestions ;) .
packageorg.springframework.shell.samples.helloworld.boot;
importorg.springframework.context.annotation.Profile;
importorg.springframework.shell.core.command.annotation.Command;
importorg.springframework.shell.core.command.annotation.Option;
importorg.springframework.stereotype.Component;
@Component@Profile("solr")
publicclassIndexCommand {
@Command(name = "hello", description = "Say hello to a given name", group = "Greetings",
help = "A command that greets the user with 'Hello ${name}!'. Usage: hello [-n | --name]=<name>")
publicvoidsayHello(@Option(shortName = 'n', longName = "name", description = "the name of the person to greet",
defaultValue = "World") Stringname) {
System.out.println("Hello " + name + "!");
}
}
Thank you for checking, @czpilar ! Indeed, I believe this is fixed by 236dbc9, which now get @Component classes from the application context (with profiles applied) compared to 4.0.1 which was looking for components by scanning the classpath (without respecting profiles).
@tkrah Thank you for the feedback and sample, and apologies for the noise about the validity of this issue.
Activity
fmbenhassine commentedon Mar 26, 2026
This is a valid issue. Thank you for reporting it! I will plan the fix for the upcoming release.
[-]Shell 4: Command not registered if @Profile(..) is used and activated[/-][+]Command not registered if @Profile(..) is used and activated[/+]czpilar commentedon Apr 1, 2026
Hello,
I've just tried to reproduce the issue to help fix the problem, but I'm not sure if my configuration is correct because I'm not able to replicate the issue with the following steps.
If I am not mistaken, the issue is about class level Profile configuration.
So considering the following configuration:
Running the application with an enabled profile and command is registered and works as expected:
or equivalently:
Running the application without an enabled profile and command is not registered:
fmbenhassine commentedon Apr 3, 2026
@czpilar Thank you for trying to help on this!
I believe I validated this bug by mistake, and here is why: when I tested this back then, I used the non-boot version of the hello world sample (since the OP did not mention Boot). And here is the quick sample I used:
Running this sample with the
greetingprofile active does not show the commands, so I thought the bug report is valid.. but my sample was actually incorrect, it should have been like:which works as expected with profiles. I just re-tested with nested and non-nested classes and profile honouring seems to work with boot and non-boot samples.
@tkrah Can you please provide a minimal complete sample that we can use to reproduce the issue? Are you sure your
IndexCommandis not excluded from classpath scanning and correctly defined as a bean?tkrah commentedon Apr 7, 2026
Got one, I reused my demo repo for my spring security issue, so please ignore the stuff which is not related.
Go to https://github.com/tkrah/spring-sec-14911:
You can see the command (https://github.com/tkrah/spring-sec-14911/blob/main/src/main/java/com/example/demo/shell/IndexCommand.java) is annotated with:
Build it with:
and start the shell with:
./demo-shell.shThis will print:
The command is not registered.
Now remove the
@Profile("solr")from the IndexCommand class, rebuild the jar and restart the shell, you will see this:Now the command is registered.
In both cases, the profiles active are:
The following 3 profiles are active: "g_dev", "default", "solr"If I am doing something wrong here, I am open to suggestions ;) .
czpilar commentedon Apr 7, 2026
I've just tried to reproduce the problem with the following configuration:
SpringShellApplication.java
IndexCommand.java
application.properties
I can confirm that this is an issue in Spring Shell 4.0.1, as you can see in the following screenshot.
However, with the current main branch, the issue is no longer reproducible.
I believe it has already been fixed, as suggested in a related issue (#1327) in the following comment:
#1327 (comment)
fmbenhassine commentedon Apr 8, 2026
Thank you for checking, @czpilar ! Indeed, I believe this is fixed by 236dbc9, which now get
@Componentclasses from the application context (with profiles applied) compared to 4.0.1 which was looking for components by scanning the classpath (without respecting profiles).@tkrah Thank you for the feedback and sample, and apologies for the noise about the validity of this issue.