How to get Spring/Gradle to recognize JdbcTemplate initialization - spring-boot

I have created a small SpringBoot/Gradle REST controller application, but I am
having problems initializing a connection to a Postgresql database. My application
includes the following class that's used to access the database:
#Component
public class UserSettingDAO {
#Autowired
private JdbcTemplate jdbcTemplate;
#Autowired
private DataSource dataSource;
...
}
In the first version of the program, I included the following in /src/main/resources/application.properties:
spring.datasource.driver-class-name=org.postgresql.Driver
spring.datasource.url=jdbc:postgresql://...
spring.datasource.username=...
spring.datasource.password=...
In this version, my REST service successfully connected with the database. However,
for consistency with other projects in my group, I changed the initialization of
dataSource and jdbcTemplate as follows:
First, I removed those property
definitions above from application.properties. Next, I created an XML initialization file resources/resources_deployment1/spring-resource1.xml that included the
following:
<bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="locations" value="classpath:pdao_connection.properties"/>
</bean>
<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="${driverClassName}" />
<property name="url" value="${url}" />
<property name="username" value="${db.username}" />
<property name="password" value="${db.password}"/>
</bean>
<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
<constructor-arg ref="dataSource"/>
</bean>
where the referenced file resources/resources_deployment1/pdao_connection.properties
contains the following:
driverClassName=org.postgresql.Driver
db.username=...
db.password=...
url=jdbc:postgresql://...
After this, when I then deployed my application (to Websphere Liberty) and hit my REST
service from Chrome, it failed with the following message:
Failed to auto-configure a DataSource: 'spring.datasource.url' is not specified and no embedded datasource could be auto-configured.
It seems like there is a break in the long chain of references so that Spring does
not have access to the required connection parameters. How can I fix this, while
keeping the deployment-specific parameters in a subfolder of resources? In
particular, how do I convince the build and runtime operations to look in the
resources/resources_deployment1 folder?

it required artifacts spring-jdbc and postgresql java connector inside your web.xml or pom.xml

I stumbled upon an answer: Adding the following piece of code in the same package where I'm using jdbcTemplate
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.ImportResource;
#Configuration
#ImportResource("classpath:spring-resource1.xml")
public class DAOConfiguration {
}
appears to let Spring know that it should look in the referenced XML file that is, in fact, under the project's resources/ directory.

Related

Custom LineMapper could not be registered from xml configuration when using spring batch and spring boot 2.2.5

Version using:
Spring boot 2.2.5
Spring batch core 4.x
There is only one following bean in the spring-batch.xml file:
<bean id="lineMapper" primary="true" class="com.batch.ContextSavingLineMapper" scope="step">
<property name="lineTokenizer">
<bean class="org.springframework.batch.item.file.transform.DelimitedLineTokenizer">
<!-- This is to accept lines with incorrect number of tokens -->
<property name="strict" value="false"/>
<!-- Expected CSV column names -->
<property name="names" value="#{jobParameters['columnNames']}" />
</bean>
</property>
<property name="fieldSetMapper">
<bean class="com.batch.DetectorRegistrationFieldSetMapper" />
</property>
</bean>
Class ContextSavingLineMapper is extended as below:
public class ContextSavingLineMapper<T> extends DefaultLineMapper<T> implements StepExecutionListener {
Message error:
Description:
The bean 'lineMapper', defined in BeanDefinition defined in class path resource [spring-batch.xml], could not be registered. A bean with that name has already been defined in class path resource [spring-batch.xml] and overriding is disabled.
Action:
Consider renaming one of the beans or enabling overriding by setting spring.main.allow-bean-definition-overriding=true
Note: I don't want to use spring.main.allow-bean-definition-overriding=true.
You are hitting this open issue: https://github.com/spring-projects/spring-batch/issues/1050.
I don't want to use spring.main.allow-bean-definition-overriding=true
Unfortunately this is the only workaround until the aforementioned issue is resolved.

Issue while deploying multiple peristence.xml in tomee with JBPM, spring, JPA (Hibernate)

I am facing an issue while configuring the multiple entity managers with multiple persistence.xml via xml configuration, can someone please help me out with the configuration.
Issue:
SEVERE [main] org.apache.openejb.config.ReportValidationResults.logResults FAIL ... core-web-1.0_A0: #PersistenceContext unitName required, multiple units available: ref "em", available units [applicationPersistenceUnit, applicationPersistenceUnit, applicationPersistenceUnit, applicationPersistenceUnit]
Below is configuration:
<bean id="appEntityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean" p:jpadialect-ref="jpaDialect" p:jpavendoradapter-ref="jpaVendorAdapter">
<property name="jpaProperties"/>
<property name="packagesToScan">
<list>
<value>${application.model.packagesToScan}</value>
<value>org.kie.*</value>
<value>org.jbpm.*</value>
</list>
</property>
<property name="dataSource" ref="appDataSource"/>
<property name="persistenceUnitManager" ref="persistenceUnitManager"/>
</bean>
<bean id="persistenceUnitManager" class="org.springframework.data.jpa.support.MergingPersistenceUnitManager">
<property name="persistenceXmlLocations">
<list>
<value>classpath*:META-INF/persistence.xml</value>
<value>classpath*:META-INF/workflow-persistence.xml</value>
</list>
</property>
<property name="defaultDataSource" ref="appDataSource"/>
</bean>
Reason being having multiple persistence.xmls is JBPM expects separate set of classes.
it seems that you have multiple persistence units, but jpa doesnt know how to handle the entity manager. in which persistence unit should it belong?
try sth like this (change to your local needs accordingly)
#PersistenceContext(unitName = "UNIT1", type = PersistenceContextType.TRANSACTION)
private EntityManager unit1EntityManager;
#PersistenceContext(unitName = "UNIT2", type = PersistenceContextType.TRANSACTION)
private EntityManager unit2EntityManager;
#PersistenceContext(unitName = "UNIT3", type = PersistenceContextType.TRANSACTION)
private EntityManager unit3EntityManager;
If you have some jars which are not EE (100% spring, standalone or other) you can exclude them from the scanning creating a WEB-INF/exclusions.list and adding inside:
default-list
myjarprefix
if the jar is named myjarprefix-1.2.3.jar for instance.
It will prevent the not EE #PersistenceContext/#PersistenceUnit without a name from being scanned and therefore will let the container start.
If the classes are mixed with EE code you can add a WEB-INF/scan.xml with:
<scan>
<packages>
<package>com.company.application.myeepackage</package>
</packages>
</scan>
Taking care to not list a package with the classes you want to exclude

Can't Import properties after integrating spring-batch-admin into existed spring boot

I have worked on a project using spring-batch and spring-boot.
I followed the exact rules how to integrate it by:
1. removing all #EnableBatchProcessing
2. adding ServletConfiguration and WebappConfiguration (and also import them using
#Import({ ServletConfiguration.class, WebappConfiguration.class })
add props:
batch-mysql.properties
business-schema-mysql
and modified application.properties with:
server.servletPath=/*
spring.freemarker.checkTemplateLocation=false
ENVIRONMENT=mysql
Now here is the side effect. My app is using an applicationContext .xml in addition to it's java config.
that applicationContext has some place holders:
<context:property-placeholder
location="file:///etc/location/services/myapp.properties"/>
<bean name="configuration" class="com.mycompany.commons.configuration.factory.BeanAwareConfigurationFactory">
<property name="serviceId" value="${serviceId}"/>
...
</bean>
As soon as I integrated spring-batch-admin I got this error:
Caused by: java.lang.IllegalArgumentException: Could not resolve placeholder 'serviceId' in string value "${serviceId}"
at
...
I tried #PropertySource to import it, but it didn't work:
#PropertySource("file:///etc/location/services/myapp.properties")
public class Application extends SpringBootServletInitializer {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
System.out.printf("Started processor service app");
}
As soon as I removed spring-batch-admin from my spring-boot project I manage to attach those props.
Any idea how to overcome this?
You can override spring-batch-admindefault context loading configuration. In src/main/resources/META-INF/spring/batch/override/manager/ you can place env-context.xml file with configuration of resources which need to be loaded.
Here is spring batch admin one which can be used as starting point so you can do something like:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<!-- Use this to set additional properties on beans at run time -->
<bean id="placeholderProperties" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="locations">
<list>
<value>classpath:/org/springframework/batch/admin/bootstrap/batch.properties</value>
<value>classpath:batch-default.properties</value>
<value>classpath:batch-${ENVIRONMENT:hsql}.properties</value>
<!-- this line you can add-->
<value>file:///etc/location/services/myapp.properties</value>
</list>
</property>
<property name="systemPropertiesModeName" value="SYSTEM_PROPERTIES_MODE_OVERRIDE" />
<property name="ignoreResourceNotFound" value="true" />
<property name="ignoreUnresolvablePlaceholders" value="false" />
<property name="order" value="1" />
</bean>
</beans>
I forked the github project and I added the fix to prevent the placeholder error. You can get the new code here: https://github.com/vesperaba/spring-batch-admin-spring-boot.
The issue was SpringBatch has it's own PropertyPlaceholder and you have to overwrite it but to do that you have to manually import some files in order to avoid the one define it.
Here you can find the new conf: https://github.com/vesperaba/spring-batch-admin-spring-boot/blob/master/src/main/java/de/codecentric/batch/config/MainV2Configuration.java

Spring JNDI datasource not recognized after upgrade to ActiveMQ 5.6.0

I tested a ActiveMQ 5.5.0 (fuse version) app in AMQ 5.6.0 and noticed that our Spring JNDI configured Oracle datasources aren't being found.
The only thing I changed in my applications was the pom.xml versions of AMQ/Spring (to match the 5.6 versions). Otherwise, I'm using the identical application code and configuration (activemq.xml, jndi.xml, etc), but my Spring JDBC DAOs (v3.0.5) are failing to find them.
No errors in the logs otherwise, just this Spring Application Context initialization error...
javax.naming.NameNotFoundException; remaining name 'jdbc/myDataSource'
here is the relevant Spring jndi config (conf/jndi.xml, included in conf/activemq.xml)...
<bean id="jndi" class="org.apache.xbean.spring.jndi.SpringInitialContextFactory"
factory-method="makeInitialContext" scope="singleton">
<property name="entries" ref="jndiEntries" />
</bean>
<util:map id="jndiEntries">
<entry key="jdbc/myDataSource">
<bean id="myDBCPDataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
<property name="driverClassName" value="oracle.jdbc.OracleDriver" />
...
then my application references it like this...
<bean id="myDataSource" class="org.springframework.jndi.JndiObjectFactoryBean">
<property name="jndiName">
<value>jdbc/myDataSource</value>
</property>
</bean>
<bean id="messageDAO" class="com.mycompany.MessageDAOImpl">
<property name="dataSource" ref="myDataSource" />
</bean>
That said, I tested without using JNDI (instead just hardcoded the datasource in my app) and everything works as expected. So that should rule out everything except the Spring JNDI registration/lookup of the datasource, etc.
So, what am I missing?
ActiveMQ has a dependency into xbean-spring, which you are using as a JNDI provider. It is likely that the transitive Xbean dependency has changed because of the upgrade to ActiveMQ 5.6.0.
I found the issue, I added a jndi.properties file under the /conf directory containing the following and it works fine now (didn't need this under AMQ 5.5...strange)...
java.naming.factory.initial = org.apache.xbean.spring.jndi.SpringInitialContextFactory

Class load error on Spring MVC project for Spring newbie

Warning: newbie alert!
I'm in early days of learning Spring and am trying to get my first app up and running which will simply read some data from a DB and display it.
I'm using SpringSource Tool Suite 2.8.0.RELEASE. I've created a new Spring MVC project and want to read some data from a local MySQL DB.
I wrote a simple DAO class:
package com.blah.blah;
import org.springframework.jdbc.core.support.JdbcDaoSuppo rt;
public class MyDAO extends JdbcDaoSupport {
I've added this to the pom.xml file:
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>${org.springframework-version}</version>
</dependency>
I've added this to the root-context.xml (is this the right config file to update?):
<bean id="myDataSource"
class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="com.mysql.jdbc.Driver" />
<property name="url" value="jdbc:mysql://localhost:3306/dbname" />
<property name="username" value="root" />
<property name="password" value="mypw" />
</bean>
<bean id="jdbcTemplate"
class="org.springframework.jdbc.core.JdbcTemplate" >
<constructor-arg ref="myDataSource"></constructor-arg>
</bean>
<bean id="parentDAO"
class="org.springframework.jdbc.core.support.JdbcD aoSupport">
<property name="dataSource" ref="myDataSource"></property>
</bean>
When I right-click on the project and select Debug As > Debug On Server I get the error:
24-Mar-2012 16:13:42 org.apache.catalina.core.StandardContext listenerStart
SEVERE: Exception sending context initialized event to listener instance of
class org.springframework.web.context.ContextLoaderListener
org.springframework.beans.factory.CannotLoadBeanClassException:
Cannot find class [org.springframework.jdbc.datasource.DriverManagerDataSource]
for bean with name 'myDataSource' defined in ServletContext resource
[/WEB-INF/spring/root-context.xml]; nested exception is
java.lang.ClassNotFoundException: org.springframework.jdbc.datasource.DriverManagerDataSource
I've been looking at this for a while and can't figure out what I'm doing wrong. I've found the folder where the app is deployed to (C:\Program Files\springsource\vfabric-tc-server-developer-2.6.1.RELEASE\spring-insight-instance\wtpwebapps\MyAppName\WEB-INF\lib on my machine) and the lib folder contains spring-jdbc-3.1.0.RELEASE.jar and when I open it, I can see the DriverManagerDataSource class file so I don't know why I'm getting the error above.
Any advice greatly appreciated.
Check that the Spring libraries are in the classpath so they are available for the server.
I had the same jar file included in the project twice. Removed one and it worked.
I had the same problem in Eclipse and creating a new workspace solved this problem.
I had added required jar source instead of release. Strange but changing that to release version fixed this problem.

Resources