Comments (6)
Hi Felipe,
there is no official way of disabling converters, but I think you can easily achieve this by making sure your own converter gets registered after the standard one and has the same name (dateConverter
). This should work.
from spring-shell.
Hi @ericbottard , thanks a lot for the super fast response!
How can I ensure my converter gets after the standard one?
Right now, my DateConverter
looks like this:
package cli.converters;
import org.springframework.shell.core.Completion;
import org.springframework.shell.core.Converter;
import org.springframework.shell.core.MethodTarget;
import org.springframework.stereotype.Component;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
@Component
public class DateConverter implements Converter<Date>
{
private static final String DATE_FORMAT = "yyyy-MM-dd HH:mm:ss";
private final DateFormat dateFormat = new SimpleDateFormat(DATE_FORMAT);
@Override
public boolean supports(Class<?> type, String optionContext)
{
return Date.class.isAssignableFrom(type);
}
@Override
public Date convertFromText(String value, Class<?> targetType, String optionContext)
{
try {
return dateFormat.parse(value);
}
catch (ParseException e) {
throw new IllegalArgumentException("Could not parse date: " + e.getMessage());
}
}
@Override
public boolean getAllPossibleValues(List<Completion> completions, Class<?> targetType, String existingData, String optionContext, MethodTarget target)
{
return false;
}
}
And when I try to start the CLI I get this error:
Exception in thread "main" org.springframework.beans.factory.BeanDefinitionStoreException: Unexpected exception parsing XML document from URL [file:/Users/felipe/workspace/rebuy-java-cli/target/classes/META-INF/spring/spring-shell-plugin.xml]; nested exception is org.springframework.context.annotation.ConflictingBeanDefinitionException: Annotation-specified bean name 'dateConverter' for bean class [com.rebuy.cli.converters.DateConverter] conflicts with existing, non-compatible bean definition of same name and class [org.springframework.shell.converters.DateConverter]
at org.springframework.beans.factory.xml.XmlBeanDefinitionReader.doLoadBeanDefinitions(XmlBeanDefinitionReader.java:414)
at org.springframework.beans.factory.xml.XmlBeanDefinitionReader.loadBeanDefinitions(XmlBeanDefinitionReader.java:336)
at org.springframework.beans.factory.xml.XmlBeanDefinitionReader.loadBeanDefinitions(XmlBeanDefinitionReader.java:304)
at org.springframework.beans.factory.support.AbstractBeanDefinitionReader.loadBeanDefinitions(AbstractBeanDefinitionReader.java:181)
Disconnected from the target VM, address: '127.0.0.1:51111', transport: 'socket'
at org.springframework.beans.factory.support.AbstractBeanDefinitionReader.loadBeanDefinitions(AbstractBeanDefinitionReader.java:217)
at org.springframework.beans.factory.support.AbstractBeanDefinitionReader.loadBeanDefinitions(AbstractBeanDefinitionReader.java:188)
at org.springframework.beans.factory.support.AbstractBeanDefinitionReader.loadBeanDefinitions(AbstractBeanDefinitionReader.java:252)
at org.springframework.shell.Bootstrap.<init>(Bootstrap.java:101)
at org.springframework.shell.Bootstrap.<init>(Bootstrap.java:76)
at org.springframework.shell.Bootstrap.main(Bootstrap.java:58)
at com.rebuy.cli.Main.main(Main.java:11)
Caused by: org.springframework.context.annotation.ConflictingBeanDefinitionException: Annotation-specified bean name 'dateConverter' for bean class [com.rebuy.cli.converters.DateConverter] conflicts with existing, non-compatible bean definition of same name and class [org.springframework.shell.converters.DateConverter]
at org.springframework.context.annotation.ClassPathBeanDefinitionScanner.checkCandidate(ClassPathBeanDefinitionScanner.java:320)
at org.springframework.context.annotation.ClassPathBeanDefinitionScanner.doScan(ClassPathBeanDefinitionScanner.java:259)
at org.springframework.context.annotation.ComponentScanBeanDefinitionParser.parse(ComponentScanBeanDefinitionParser.java:87)
at org.springframework.beans.factory.xml.NamespaceHandlerSupport.parse(NamespaceHandlerSupport.java:74)
at org.springframework.beans.factory.xml.BeanDefinitionParserDelegate.parseCustomElement(BeanDefinitionParserDelegate.java:1411)
at org.springframework.beans.factory.xml.BeanDefinitionParserDelegate.parseCustomElement(BeanDefinitionParserDelegate.java:1401)
at org.springframework.beans.factory.xml.DefaultBeanDefinitionDocumentReader.parseBeanDefinitions(DefaultBeanDefinitionDocumentReader.java:168)
at org.springframework.beans.factory.xml.DefaultBeanDefinitionDocumentReader.doRegisterBeanDefinitions(DefaultBeanDefinitionDocumentReader.java:138)
at org.springframework.beans.factory.xml.DefaultBeanDefinitionDocumentReader.registerBeanDefinitions(DefaultBeanDefinitionDocumentReader.java:94)
at org.springframework.beans.factory.xml.XmlBeanDefinitionReader.registerBeanDefinitions(XmlBeanDefinitionReader.java:508)
at org.springframework.beans.factory.xml.XmlBeanDefinitionReader.doLoadBeanDefinitions(XmlBeanDefinitionReader.java:392)
... 10 more
Should I do anything else?
from spring-shell.
Wow, sorry this seems to be a (new?) behavior in Spring core. Back in the day, when I was still a kid, you could override a bean definition just by having it appear afterwards in the scanning order :)
Anyway, in the meantime I would say your best bet is to have a look at Spring Shell's Bootstrap class and replicate it yourself, bypassing the unconditional registration of all standard converters.
I will still have a look at this, as this seems like something users would want to do.
from spring-shell.
As a matter of fact, it seems like this overriding mechanism I was talking about indeed works, if you declare your bean via xml notation.
So, I'd recommend doing something like this:
I assume you currently have a spring-shell-plugin.xml
file that looks like this:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">
<context:component-scan base-package="com.acme.whatever" />
/>
</beans>
Change it to this:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">
<context:component-scan base-package="com.acme.whatever" />
<bean id="dateConverter" class="cli.converter.DateConverter" />
</beans>
(Drop the @Component
on your DateConverter
and/or make sure it is not being component scanned)
from spring-shell.
Works like a charm! Thanks a bunch for the super fast responses!
from spring-shell.
My pleasure :)
from spring-shell.
Related Issues (20)
- Upgrade jline 3.26.0
- Add jni starter
- Upgrade spring-boot 3.1.11
- Upgrade spring-boot 3.2.5
- Upgrade spring-boot 3.3.0-RC1
- Change properties for interactive and script to false on default
- ShellApplicationRunner should have behaviour without arguments
- CommandAvailability is not documented HOT 1
- Fixes
- Fixes
- Fixes
- Use string array in ShellRunner HOT 1
- backport(1046): Upgrade jline 3.26.0
- backport(1046): Upgrade jline 3.26.0
- Unable to build a native image using Native Build tools HOT 2
- Document ShellRunner changes
- StyleSettings interface "highlight" method failing to apply style. HOT 3
- native e2e tests on macos fail with cpu architecture
- backport(1063): StyleSettings interface "highlight" method failing to apply style.
- Single + Default Command HOT 1
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from spring-shell.