Can not registry a dynamic bean - spring-boot

I am migrating a Project which using JBOSS fuse to Spring Boot and I use this code for registry a dynamic DataSource:
PropertyPlaceholderDelegateRegistry reg = (PropertyPlaceholderDelegateRegistry) exchange.getContext().getRegistry();
CompositeRegistry cReg = (CompositeRegistry) reg.getRegistry();
SimpleRegistry simpleReg = new SimpleRegistry();
simpleReg.put(
Messaging.Names.SAM_DATABASE_CONNECTION_KEY.toString() + configuration.getCustomerNumber(),
dataSource);
cReg.addRegistry(simpleReg);
But when i migrated it to Spring boot, it does not work and has this Error:
There's uncaught exception has occured. Exception message:
org.apache.camel.spring.spi.ApplicationContextRegistry cannot be cast to org.apache.camel.impl.CompositeRegistry
Please help!!!

Related

NoSuchFieldError: pathPatternParser in WebMvcEndpointManagementContextConfiguration after upgrade from spring-boot 2.5.5 to 2.6.1

When upgrading to Spring-Boot from 2.5.5 to 2.6.1, I encounter the following error:
Caused by: org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.springframework.boot.actuate.endpoint.web.servlet.WebMvcEndpointHandlerMapping]: Factory method 'webEndpointServletHandlerMapping' threw exception; nested exception is java.lang.NoSuchFieldError: pathPatternParser
I use Spring Boot Actuator, which uses class WebMvcEndpointManagementContextConfiguration in the autoconfigure dependency (spring-boot-actuator-autoconfigure). On line 68 (decompiled class), the WebMvcAutoConfiguration.pathPatternParser field is used, which to my understanding causes the exception.
return new WebMvcEndpointHandlerMapping(endpointMapping, webEndpoints, endpointMediaTypes, corsProperties.toCorsConfiguration(), new EndpointLinksResolver(allEndpoints, basePath), shouldRegisterLinksMapping, WebMvcAutoConfiguration.pathPatternParser);
If I check the WebMvcAutoConfiguration class, I can only see the following usage of the PathPatternParser class, but no field declaration.
public void configurePathMatch(PathMatchConfigurer configurer) {
if (this.mvcProperties.getPathmatch().getMatchingStrategy() == MatchingStrategy.PATH_PATTERN_PARSER) {
configurer.setPatternParser(new PathPatternParser());
}
Is this a bug?
I will try to use Spring-Boot 2.6.0, 2.5.7 and 2.5.6 and see what the behavior on those versions is. I will update this issue with the information

How to disable SpringBoot autoconfiguration for TomcatServletWebServerFactory in order for a custom spring-starter to provide it?

so I was writing my own SpringBootStarter which was supposed to enable the JNDI lookup in the embedded tomcat of a SpringBoot application.
My sample SpringBoot application has a dependency of my custom SpringBootStarter, which in turn has a dependency on the spring-boot-starter-web. If I create a Configuration class like the following inside the sample SpringBoot application everything works perfectly:
#Configuration
public class SampleSpringBootAppConfig {
#Bean
public TomcatServletWebServerFactory tomcatFactory() {
return new TomcatServletWebServerFactory() {
#Override
protected TomcatWebServer getTomcatWebServer(org.apache.catalina.startup.Tomcat tomcat) {
System.out.println("CONFIGURING CUSTOM TOMCAT WEB SERVER FACTORY ");
tomcat.enableNaming();
return super.getTomcatWebServer(tomcat);
}
#Override
protected void postProcessContext(Context context) {
ContextResource resource = new ContextResource();
resource.setName("myDataSource");
resource.setType(DataSource.class.getName());
resource.setProperty("driverClassName", "org.postgresql.Driver");
resource.setProperty("url", "jdbc:postgresql://localhost:5432/postgres");
resource.setProperty("username", "postgres");
resource.setProperty("password", "postgres");
context.getNamingResources()
.addResource(resource);
}
};
}
Because SpringBoot finds a custom Bean, there won't be an autoconfigured default one / it is overridden and the JNDI is successfully enabled.
However, as soon as I extract this Bean configuration into my auto-configure module of my custom SpringBoot Starter, the following exception is thrown while trying to start the sample SpringBoot application:
org.springframework.context.ApplicationContextException: Unable to start web server; nested exception is org.springframework.context.ApplicationContextException: Unable to start ServletWebServerApplicationContext due to multiple ServletWebServerFactory beans : tomcatServletWebServerFactory,tomcatFactory
I reckon this is due to SpringBoot not finding a customized Bean and therefore creating an autoconfigured default one which also won't be overridden. So now there will be two ServletWebServerFactory beans, the default one and the one from my auto- configure module.
What i tried so far (to no avail) :
annotating my custom Bean with #Primary
setting spring.main.allow-bean-definition-overriding to true
Is there any way to make SpringBoot not initialize a autoconfigured default bean, or any other possible solution to this?
try this
#AutoConfigureBefore(ServletWebServerFactoryAutoConfiguration.class)
I was able to solve this myself by excluding the responsible AutoConfiguration class:
#SpringBootApplication ( exclude = ServletWebServerFactoryAutoConfiguration.class)

Unable to call Mapper.xml file by using junit testing for the application developed using Mybatis+Springboot

I'm very new to junit testing. How to write junit test real database call from mybatis.xml file.
Please find the below code.
#RunWith(SpringRunner.class)
//#MybatisTest
#SpringBootTest
public class HotelMapperTest {
#Autowired
private HotelMapper hotelMapper;
#Test
public void selectByCityIdTest() {
Hotel hotel = hotelMapper.selectByCityId(1);
assertThat(hotel.getName()).isEqualTo("Conrad Treasury Place");
assertThat(hotel.getAddress()).isEqualTo("William & George Streets");
assertThat(hotel.getZip()).isEqualTo("4001");
}
when i run the junit testing i'm getting below exception:
org.apache.ibatis.binding.BindingException: Invalid bound statement (not found):
Herer my question is how we'll test the real database, When enable the #MybatisTest it's looking for datasource, already we specified all properties in applicaiton.properties. In this time i'm getting below exception:
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'dataSource':
You can config mybatis mapper location in spring configuration file (such as application.yml).
mybatis configuration:
mybatis:
mapper-locations:
- classpath*:mapper/*.xml

Spring Boot & RabbitMQ: message conversion content type

We are using Spring Boot 2.1.3.RELEASE and RabbitMQ. MessagePack is used for serialization.
We are using convertAndSend:
rabbitTemplate.convertAndSend("exchange", "routingKey", object);
And getting the following exception:
java.lang.UnsupportedOperationException: null
at org.msgpack.jackson.dataformat.MessagePackFactory.createGenerator(MessagePackFactory.java:102)
at com.fasterxml.jackson.databind.ObjectMapper.writeValueAsString(ObjectMapper.java:3219)
at org.springframework.amqp.support.converter.AbstractJackson2MessageConverter.createMessage(AbstractJackson2MessageConverter.java:259)
at org.springframework.amqp.support.converter.AbstractMessageConverter.toMessage(AbstractMessageConverter.java:70)
at org.springframework.amqp.support.converter.AbstractMessageConverter.toMessage(AbstractMessageConverter.java:58)
at org.springframework.amqp.rabbit.core.RabbitTemplate.convertMessageIfNecessary(RabbitTemplate.java:1726)
at org.springframework.amqp.rabbit.core.RabbitTemplate.convertAndSend(RabbitTemplate.java:1048)
at org.springframework.amqp.rabbit.core.RabbitTemplate.convertAndSend(RabbitTemplate.java:1041)
This is the line where the exception is thrown:
return getRequiredMessageConverter().toMessage(object, new MessageProperties());
Is there a way to set the content type in MessageProperties to application/json? The default is application/octet-stream.

Webshpere datasource error:Unable to lookup JNDI name

I am developing an application with Hibernate and Websphere Application Server 8.0.
I have create a datasource in Websphere and it can connect with database successfully.
But from application I am getting following error:
SystemErr R Error creating Session: org.hibernate.service.jndi.JndiException: Unable to lookup JNDI name [java:comp/env/jdbc/OracleDS]
Following is the setup I have done:
Websphere datasource setup:
hibernate.cfg.xml
web.xml
When I try to get sessiofactory, it gives me error:
HibernateUtil.java:
try
{
Configuration configuration = new Configuration().configure();
serviceRegistry = new ServiceRegistryBuilder().applySettings(configuration.getProperties()).buildServiceRegistry();
sessionFactory = configuration.buildSessionFactory(serviceRegistry);
}
catch (HibernateException he)
{
System.err.println("Error creating Session: " + he);
throw new ExceptionInInitializerError(he);
}
Error:
java.lang.NullPointerException
at com.ibm.ws.webcontainer.metadata.WebComponentMetaDataImpl.getJavaNameSpace(WebComponentMetaDataImpl.java:143)
at com.ibm.ws.threadContext.JavaNameSpaceAccessorImpl.getJavaNameSpace(JavaNameSpaceAccessorImpl.java:79)
at com.ibm.ws.naming.java.javaURLContextFactory.createURLContextRoot(javaURLContextFactory.java:137)
at com.ibm.ws.naming.urlbase.UrlContextFactory.getObjectInstance(UrlContextFactory.java:101)
at org.apache.aries.jndi.URLContextProvider.getContext(URLContextProvider.java:43)
at org.apache.aries.jndi.DelegateContext.getURLContext(DelegateContext.java:252)
at org.apache.aries.jndi.DelegateContext.findContext(DelegateContext.java:214)
at org.apache.aries.jndi.DelegateContext.findContext(DelegateContext.java:207)
at org.apache.aries.jndi.DelegateContext.lookup(DelegateContext.java:157)
at javax.naming.InitialContext.lookup(InitialContext.java:432)
at org.hibernate.service.jndi.internal.JndiServiceImpl.locate(JndiServiceImpl.java:65)
at org.hibernate.service.jdbc.connections.internal.DatasourceConnectionProviderImpl.configure(DatasourceConnectionProviderImpl.java:116)
at org.hibernate.service.internal.StandardServiceRegistryImpl.configureService(StandardServiceRegistryImpl.java:75)
at org.hibernate.service.internal.AbstractServiceRegistryImpl.initializeService(AbstractServiceRegistryImpl.java:159)
at org.hibernate.service.internal.AbstractServiceRegistryImpl.getService(AbstractServiceRegistryImpl.java:131)
at org.hibernate.engine.jdbc.internal.JdbcServicesImpl.buildJdbcConnectionAccess(JdbcServicesImpl.java:223)
at org.hibernate.engine.jdbc.internal.JdbcServicesImpl.configure(JdbcServicesImpl.java:89)
at org.hibernate.service.internal.StandardServiceRegistryImpl.configureService(StandardServiceRegistryImpl.java:75)
at org.hibernate.service.internal.AbstractServiceRegistryImpl.initializeService(AbstractServiceRegistryImpl.java:159)
at org.hibernate.service.internal.AbstractServiceRegistryImpl.getService(AbstractServiceRegistryImpl.java:131)
at org.hibernate.cfg.Configuration.buildTypeRegistrations(Configuration.java:1818)
at org.hibernate.cfg.Configuration.buildSessionFactory(Configuration.java:1776)
at com.test.util.HibernateUtil.(HibernateUtil.java:25)
Error creating Session: org.hibernate.service.jndi.JndiException: Unable to lookup JNDI name [java:comp/env/jdbc/OracleDS]
Please let me know what I am missing.
I have applied more tries, now I am getting following error:
FFDC Exception:javax.naming.NamingException SourceId:com.ibm.ws.naming.java.javaURLContextFactory.createURLContextRoot ProbeId:142 Reporter:java.lang.Class#dfac0b43
javax.naming.NamingException: NMSV0308W: javaURLContextFactory cannot create a javaURLContext object because there is no java URL name space currently accessible from the executing thread.
at com.ibm.ws.naming.java.javaURLContextFactory.createURLContextRoot(javaURLContextFactory.java:170)
at com.ibm.ws.naming.urlbase.UrlContextFactory.getObjectInstance(UrlContextFactory.java:101)
at org.apache.aries.jndi.URLContextProvider.getContext(URLContextProvider.java:43)
at org.apache.aries.jndi.DelegateContext.getURLContext(DelegateContext.java:252)
at org.apache.aries.jndi.DelegateContext.findContext(DelegateContext.java:214)
at org.apache.aries.jndi.DelegateContext.findContext(DelegateContext.java:207)
at org.apache.aries.jndi.DelegateContext.lookup(DelegateContext.java:157)
at javax.naming.InitialContext.lookup(InitialContext.java:432)
at org.hibernate.service.jndi.internal.JndiServiceImpl.locate(JndiServiceImpl.java:65)
at org.hibernate.service.jdbc.connections.internal.DatasourceConnectionProviderImpl.configure(DatasourceConnectionProviderImpl.java:116)
at org.hibernate.service.internal.StandardServiceRegistryImpl.configureService(StandardServiceRegistryImpl.java:75)
at org.hibernate.service.internal.AbstractServiceRegistryImpl.initializeService(AbstractServiceRegistryImpl.java:159)
at org.hibernate.service.internal.AbstractServiceRegistryImpl.getService(AbstractServiceRegistryImpl.java:131)
at org.hibernate.engine.jdbc.internal.JdbcServicesImpl.buildJdbcConnectionAccess(JdbcServicesImpl.java:223)
at org.hibernate.engine.jdbc.internal.JdbcServicesImpl.configure(JdbcServicesImpl.java:89)
at org.hibernate.service.internal.StandardServiceRegistryImpl.configureService(StandardServiceRegistryImpl.java:75)
at org.hibernate.service.internal.AbstractServiceRegistryImpl.initializeService(AbstractServiceRegistryImpl.java:159)
at org.hibernate.service.internal.AbstractServiceRegistryImpl.getService(AbstractServiceRegistryImpl.java:131)
at org.hibernate.cfg.Configuration.buildTypeRegistrations(Configuration.java:1818)
at org.hibernate.cfg.Configuration.buildSessionFactory(Configuration.java:1776)
at com.test.util.HibernateUtil.(HibernateUtil.java:25)
Did you create binding between you reference and JNDI name?
You can do it
either using admin console - Enterprise Application > ApplicationName > Resource references. then select reference and map it to the datasource JNDI name
or using binding file - you need to create ibm-web-bnd.xml file with the following contents:
<resource-ref name="jdbc/OracleDS" binding-name="jdbc/OracleDS" />
In WebSphere you don't need java:comp/env at the hibernate datasource.
So your hibernate.cfg.xml would look like this:
.
.
.
<!-- JNDI Datasource -->
<property name="hibernate.connection.datasource">jdbc/OracleDS</property>
.
.
.

Resources