Bilbo Baggins
Bilbo Baggins

Reputation: 3019

Spring batch admin integration in the existing app with Batch Jobs

I have a maven based spring web application where I also have several spring-batch jobs integrated. Now to monitor these jobs I want to add Spring Batch Admin to this app.

What I have done so far is this. 1. added this in web.xml inside contextConfigLocation

classpath*:/org/springframework/batch/admin/web/resources/servlet-config.xml,
classpath*:/org/springframework/batch/admin/web/resources/webapp-config.xml
  1. Added batch-default.properties file with following content.

    batch.jdbc.driver=com.microsoft.sqlserver.jdbc.SQLServerDriver batch.jdbc.url=jdbc:sqlserver://localhost:1433;SelectMethod=cursor;Database=TestMe batch.jdbc.user=aa batch.jdbc.password=aa

    batch.database.incrementer.class=org.springframework.jdbc.support.incremente.SqlServerMaxValueIncrementer batch.data.source.init=false batch.business.schema.script= batch.schema.script= batch.drop.script= batch.remote.base.url=

& the file with this name batch-SQLSERVER.properties

batch.jdbc.driver=com.microsoft.sqlserver.jdbc.SQLServerDriver
batch.jdbc.url=jdbc:sqlserver://localhost:1433;SelectMethod=cursor;Database=TestMe
batch.jdbc.user=aa
batch.jdbc.password=aa
batch.database.incrementer.class=org.springframework.jdbc.support.incrementer.SqlServerMaxValueIncrementer
batch.data.source.init=false
batch.business.schema.script=
batch.schema.script=
batch.drop.script=
batch.remote.base.url=
  1. My db tables for the jobs are already created.

I get the following error:

[TRACE] 2015-03-26 12:01:04.299 [localhost-startStop-1] PropertySourcesPropertyResolver - getProperty("ENVIRONMENT:hsql", String)
[DEBUG] 2015-03-26 12:01:04.299 [localhost-startStop-1] PropertySourcesPropertyResolver - Searching for key 'ENVIRONMENT:hsql' in [servletConfigInitParams]
[DEBUG] 2015-03-26 12:01:04.299 [localhost-startStop-1] PropertySourcesPropertyResolver - Searching for key 'ENVIRONMENT:hsql' in [servletContextInitParams]
[DEBUG] 2015-03-26 12:01:04.299 [localhost-startStop-1] PropertySourcesPropertyResolver - Searching for key 'ENVIRONMENT:hsql' in [jndiProperties]
[DEBUG] 2015-03-26 12:01:04.299 [localhost-startStop-1] JndiTemplate - Looking up JNDI object with name [ENVIRONMENT:hsql]
[DEBUG] 2015-03-26 12:01:04.302 [localhost-startStop-1] JndiPropertySource - JNDI lookup for name [ENVIRONMENT:hsql] threw NamingException with message: Name [ENVIRONMENT:hsql] is not bound in this Context. Unable to find [ENVIRONMENT:hsql].. Returning null.
[DEBUG] 2015-03-26 12:01:04.302 [localhost-startStop-1] PropertySourcesPropertyResolver - Searching for key 'ENVIRONMENT:hsql' in [systemProperties]
[DEBUG] 2015-03-26 12:01:04.302 [localhost-startStop-1] PropertySourcesPropertyResolver - Searching for key 'ENVIRONMENT:hsql' in [systemEnvironment]
[TRACE] 2015-03-26 12:01:04.303 [localhost-startStop-1] SystemEnvironmentPropertySource - PropertySource [systemEnvironment] does not contain 'ENVIRONMENT:hsql'
[TRACE] 2015-03-26 12:01:04.303 [localhost-startStop-1] SystemEnvironmentPropertySource - PropertySource [systemEnvironment] does not contain 'ENVIRONMENT:HSQL'
[DEBUG] 2015-03-26 12:01:04.303 [localhost-startStop-1] PropertySourcesPropertyResolver - Could not find key 'ENVIRONMENT:hsql' in any property source. Returning [null]
[TRACE] 2015-03-26 12:01:04.303 [localhost-startStop-1] PropertySourcesPropertyResolver - getProperty("ENVIRONMENT", String)
[DEBUG] 2015-03-26 12:01:04.303 [localhost-startStop-1] PropertySourcesPropertyResolver - Searching for key 'ENVIRONMENT' in [servletConfigInitParams]
[DEBUG] 2015-03-26 12:01:04.303 [localhost-startStop-1] PropertySourcesPropertyResolver - Searching for key 'ENVIRONMENT' in [servletContextInitParams]
[DEBUG] 2015-03-26 12:01:04.303 [localhost-startStop-1] PropertySourcesPropertyResolver - Searching for key 'ENVIRONMENT' in [jndiProperties]
[DEBUG] 2015-03-26 12:01:04.303 [localhost-startStop-1] JndiTemplate - Looking up JNDI object with name [java:comp/env/ENVIRONMENT]
[DEBUG] 2015-03-26 12:01:04.304 [localhost-startStop-1] JndiLocatorDelegate - Converted JNDI name [java:comp/env/ENVIRONMENT] not found - trying original name [ENVIRONMENT]. javax.naming.NameNotFoundException: Name [ENVIRONMENT] is not bound in this Context. Unable to find [ENVIRONMENT].
[DEBUG] 2015-03-26 12:01:04.304 [localhost-startStop-1] JndiTemplate - Looking up JNDI object with name [ENVIRONMENT]
[DEBUG] 2015-03-26 12:01:04.304 [localhost-startStop-1] JndiPropertySource - JNDI lookup for name [ENVIRONMENT] threw NamingException with message: Name [ENVIRONMENT] is not bound in this Context. Unable to find [ENVIRONMENT].. Returning null.
[DEBUG] 2015-03-26 12:01:04.304 [localhost-startStop-1] PropertySourcesPropertyResolver - Searching for key 'ENVIRONMENT' in [systemProperties]
[DEBUG] 2015-03-26 12:01:04.304 [localhost-startStop-1] PropertySourcesPropertyResolver - Found key 'ENVIRONMENT' in [systemProperties] with type [String] and value 'SQLSERVER'
[TRACE] 2015-03-26 12:01:04.306 [localhost-startStop-1] PropertyPlaceholderHelper - Resolved placeholder 'ENVIRONMENT:hsql'
[TRACE] 2015-03-26 12:01:04.316 [localhost-startStop-1] TypeConverterDelegate - Converting String to [boolean] using property editor [org.springframework.beans.propertyeditors.CustomBooleanEditor@59bde227]
[TRACE] 2015-03-26 12:01:04.317 [localhost-startStop-1] TypeConverterDelegate - Converting String to [boolean] using property editor [org.springframework.beans.propertyeditors.CustomBooleanEditor@59bde227]
[TRACE] 2015-03-26 12:01:04.317 [localhost-startStop-1] TypeConverterDelegate - Converting String to [int] using property editor [org.springframework.beans.propertyeditors.CustomNumberEditor@414a9c78]
[DEBUG] 2015-03-26 12:01:04.318 [localhost-startStop-1] DefaultListableBeanFactory - Finished creating instance of bean 'placeholderProperties'
[INFO ] 2015-03-26 12:01:04.319 [localhost-startStop-1] PropertyPlaceholderConfigurer - Loading properties file from class path resource [org/springframework/batch/admin/bootstrap/batch.properties]
[INFO ] 2015-03-26 12:01:04.319 [localhost-startStop-1] PropertyPlaceholderConfigurer - Loading properties file from class path resource [batch-default.properties]
[INFO ] 2015-03-26 12:01:04.320 [localhost-startStop-1] PropertyPlaceholderConfigurer - Loading properties file from class path resource [batch-SQLSERVER.properties]
[ERROR] 2015-03-26 12:01:04.325 [localhost-startStop-1] ContextLoader - Context initialization failed
org.springframework.beans.factory.BeanDefinitionStoreException: Invalid bean definition with name 'sessionFactory' defined in URL [file:/C:/tomcat-7.0.54/wtpwebapps/testme/WEB-INF/classes/applicationContext-dao.xml]: Could not resolve placeholder 'hibernate.dialect' in string value "
                hibernate.dialect=${hibernate.dialect}
                hibernate.hbm2ddl.auto=${hibernate.hbm2ddl.auto}
                hibernate.show_sql=${hibernate.show_sql}
                hibernate.format.sql=${hibernate.format.sql}
                hibernate.query.substitutions=${hibernate.query.substitutions}
            "
    at org.springframework.beans.factory.config.PlaceholderConfigurerSupport.doProcessProperties(PlaceholderConfigurerSupport.java:209) ~[spring-beans-3.2.3.RELEASE.jar:3.2.3.RELEASE]
    at org.springframework.beans.factory.config.PropertyPlaceholderConfigurer.processProperties(PropertyPlaceholderConfigurer.java:220) ~[spring-beans-3.2.3.RELEASE.jar:3.2.3.RELEASE]
    at org.springframework.beans.factory.config.PropertyResourceConfigurer.postProcessBeanFactory(PropertyResourceConfigurer.java:84) ~[spring-beans-3.2.3.RELEASE.jar:3.2.3.RELEASE]
    at org.springframework.context.support.AbstractApplicationContext.invokeBeanFactoryPostProcessors(AbstractApplicationContext.java:694) ~[spring-context-3.2.3.RELEASE.jar:3.2.3.RELEASE]
    at org.springframework.context.support.AbstractApplicationContext.invokeBeanFactoryPostProcessors(AbstractApplicationContext.java:669) ~[spring-context-3.2.3.RELEASE.jar:3.2.3.RELEASE]
    at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:461) ~[spring-context-3.2.3.RELEASE.jar:3.2.3.RELEASE]
    at org.springframework.web.context.ContextLoader.configureAndRefreshWebApplicationContext(ContextLoader.java:389) ~[spring-web-3.2.3.RELEASE.jar:3.2.3.RELEASE]
    at org.springframework.web.context.ContextLoader.initWebApplicationContext(ContextLoader.java:294) [spring-web-3.2.3.RELEASE.jar:3.2.3.RELEASE]
    at org.springframework.web.context.ContextLoaderListener.contextInitialized(ContextLoaderListener.java:112) [spring-web-3.2.3.RELEASE.jar:3.2.3.RELEASE]
    at org.apache.catalina.core.StandardContext.listenerStart(StandardContext.java:4973) [catalina.jar:7.0.54]
    at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5467) [catalina.jar:7.0.54]
    at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:150) [catalina.jar:7.0.54]
    at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1559) [catalina.jar:7.0.54]
    at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1549) [catalina.jar:7.0.54]
    at java.util.concurrent.FutureTask.run(FutureTask.java:262) [?:1.7.0_71]
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145) [?:1.7.0_71]
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615) [?:1.7.0_71]
    at java.lang.Thread.run(Thread.java:745) [?:1.7.0_71]
Mar 26, 2015 12:01:04 PM 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.BeanDefinitionStoreException: Invalid bean definition with name 'sessionFactory' defined in URL [file:/C:/tomcat-7.0.54/wtpwebapps/testme/WEB-INF/classes/applicationContext-dao.xml]: Could not resolve placeholder 'hibernate.dialect' in string value "
                hibernate.dialect=${hibernate.dialect}
                hibernate.hbm2ddl.auto=${hibernate.hbm2ddl.auto}
                hibernate.show_sql=${hibernate.show_sql}
                hibernate.format.sql=${hibernate.format.sql}
                hibernate.query.substitutions=${hibernate.query.substitutions}
            "
    at org.springframework.beans.factory.config.PlaceholderConfigurerSupport.doProcessProperties(PlaceholderConfigurerSupport.java:209)
    at org.springframework.beans.factory.config.PropertyPlaceholderConfigurer.processProperties(PropertyPlaceholderConfigurer.java:220)
    at org.springframework.beans.factory.config.PropertyResourceConfigurer.postProcessBeanFactory(PropertyResourceConfigurer.java:84)
    at org.springframework.context.support.AbstractApplicationContext.invokeBeanFactoryPostProcessors(AbstractApplicationContext.java:694)
    at org.springframework.context.support.AbstractApplicationContext.invokeBeanFactoryPostProcessors(AbstractApplicationContext.java:669)
    at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:461)
    at org.springframework.web.context.ContextLoader.configureAndRefreshWebApplicationContext(ContextLoader.java:389)
    at org.springframework.web.context.ContextLoader.initWebApplicationContext(ContextLoader.java:294)
    at org.springframework.web.context.ContextLoaderListener.contextInitialized(ContextLoaderListener.java:112)
    at org.apache.catalina.core.StandardContext.listenerStart(StandardContext.java:4973)
    at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5467)
    at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:150)
    at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1559)
    at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1549)
    at java.util.concurrent.FutureTask.run(FutureTask.java:262)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
    at java.lang.Thread.run(Thread.java:745)

About my requirements I need to be able to monitor jobs in my current application using the Spring batch admin.

Thank you for viewing it. I did follow the documentation on site. I also refer the code from spring in action book. I am using the version 1.3.0.RELEASE of spring batch with spring 3.2.0.RELEASE. From the stacktrace itself I can say that the issue is with not reading the properties properly. But if I remove these file/configurations my application works just fine. I am passing -DEVIRONMENT="SQLSERVER" as runtime arguement. Please provide your inputs.

I have refered this question on SO : Integrating Spring Batch Admin in existing application.

Upvotes: 1

Views: 2559

Answers (1)

Nenad Bozic
Nenad Bozic

Reputation: 3784

I have answered similar issue in this question. When you integrate spring batch admin and spring batch application picks property resource loading configuration from spring batch admin. You need to override it to include locations where spring boot usually keeps config files.

Also I added comment there, we started with similar approach to have single spring boot application with spring batch jobs and spring batch admin for monitoring, this proved to be pain to integrate, we made it work but we had to configure all aspects much harder than if it was spring batch only app. You cannot use java configuration, only xml and much things are colliding (when you add @EnableScheduling annotation to use spring schedulers some of spring batch beans starts to be scheduled etc.)

We ended up with two apps, one which holds jobs and has spring batch only, and other application that has spring batch admin on top of same mysql DB which we use for monitoring only. You loose triggering of jobs through UI and rest from spring batch admin but we are triggering jobs through message queue so we needed only monitoring and that is good solution for us.

Upvotes: 1

Related Questions