JBoss AS 7 shutdown - connection manager closed before WAR deployment stopped - java

Env: JBoss AS 7.1.1.Final.
I have a WAR application using a data source taken from JBoss AS JNDI. When I shut down the server (Ctrl+C in the console), the application receives a shutdown command and starts to destroy its Spring context. However, I use a scheduler to perform some DB operations. When the application is closing, I want the tasks that are currently in the queue to be finished (but no new tasks are accepted - standard JDK Executor.shutdown() behaviour). This works fine when I undeploy the application without stopping the server. However, when I stop the whole server, the connection manager is closed before the application undeployment, which results in
14:31:51,604 INFO [org.jboss.as.logging] JBAS011503: Restored bootstrap log handlers
14:31:51,617 INFO [org.apache.coyote.http11.Http11Protocol] Stopping Coyote HTTP/1.1 on http-127.0.0.1-127.0.0.1-18080
14:31:51,638 INFO [org.hornetq.ra.HornetQResourceAdapter] HornetQ resource adapter stopped
14:31:51,653 INFO [org.apache.catalina.core.ContainerBase.[jboss.web].[default-host].[/MY-APP]] Closing Spring root WebApplicationContext
14:31:51,656 INFO [org.springframework.web.context.support.XmlWebApplicationContext] Closing Root WebApplicationContext: startup date [Tue Jul 09 14:30:56 CST 2013]; root of context hierarchy
14:31:51,659 INFO [org.springframework.beans.factory.support.DefaultListableBeanFactory] Destroying singletons in org.springframework.beans.factory.support.DefaultListableBeanFactory#2c591927: defining beans [<snipped>]; root of factory hierarchy
14:31:51,662 INFO [org.hornetq.core.server.impl.HornetQServerImpl] HornetQ Server version 2.2.13.Final (HQ_2_2_13_FINAL_AS7, 122) [5f713ff6-5f86-11e2-a25d-1f3857764d50] stopped
14:31:51,673 INFO [MY-APP.Shutdown] Initializing shutdown. Already running tasks will be finished, new tasks will not be executed.
14:31:53,626 ERROR [org.springframework.scheduling.support.TaskUtils$LoggingErrorHandler] Unexpected error occurred in scheduled task.: org.springframework.jdbc.CannotGetJdbcConnectionException: Could not get JDBC Connection; nested exception is java.sql.SQLException: javax.resource.ResourceException: IJ000451: The connection manager is shutdown: java:/my/DS1
at org.springframework.jdbc.datasource.DataSourceUtils.getConnection(DataSourceUtils.java:80) [spring-jdbc-3.2.3.RELEASE.jar:3.2.3.RELEASE]
at org.springframework.jdbc.core.JdbcTemplate.execute(JdbcTemplate.java:575) [spring-jdbc-3.2.3.RELEASE.jar:3.2.3.RELEASE]
at org.springframework.jdbc.core.JdbcTemplate.update(JdbcTemplate.java:818) [spring-jdbc-3.2.3.RELEASE.jar:3.2.3.RELEASE]
at org.springframework.jdbc.core.JdbcTemplate.update(JdbcTemplate.java:874) [spring-jdbc-3.2.3.RELEASE.jar:3.2.3.RELEASE]
at org.springframework.jdbc.core.JdbcTemplate.update(JdbcTemplate.java:882) [spring-jdbc-3.2.3.RELEASE.jar:3.2.3.RELEASE]
at com.my.app.scanner.db.SyncEntryRepository.deleteById(SyncEntryRepository.java:26) [classes:]
at com.my.app.rules.orphanentries.OrphanedEntriesProcessor.process(OrphanedEntriesProcessor.java:22) [classes:]
at com.my.app.routing.Router$RoutingWorker.performRouting(Router.java:49) [classes:]
at com.my.app.routing.Router$RoutingWorker.route(Router.java:32) [classes:]
at com.my.app.routing.Router.route(Router.java:18) [classes:]
at com.my.app.transformation.Transformation.perform(Transformation.java:21) [classes:]
at com.my.app.MyApp.run(MyApp.java:18) [classes:]
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) [rt.jar:1.6.0_45]
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39) [rt.jar:1.6.0_45]
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25) [rt.jar:1.6.0_45]
at java.lang.reflect.Method.invoke(Method.java:597) [rt.jar:1.6.0_45]
at org.springframework.scheduling.support.ScheduledMethodRunnable.run(ScheduledMethodRunnable.java:64) [spring-context-3.2.3.RELEASE.jar:3.2.3.RELEASE]
at org.springframework.scheduling.support.DelegatingErrorHandlingRunnable.run(DelegatingErrorHandlingRunnable.java:53) [spring-context-3.2.3.RELEASE.jar:3.2.3.RELEASE]
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:439) [rt.jar:1.6.0_45]
at java.util.concurrent.FutureTask$Sync.innerRunAndReset(FutureTask.java:317) [rt.jar:1.6.0_45]
at java.util.concurrent.FutureTask.runAndReset(FutureTask.java:150) [rt.jar:1.6.0_45]
at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$101(ScheduledThreadPoolExecutor.java:98) [rt.jar:1.6.0_45]
at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.runPeriodic(ScheduledThreadPoolExecutor.java:180) [rt.jar:1.6.0_45]
at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:204) [rt.jar:1.6.0_45]
at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:895) [rt.jar:1.6.0_45]
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:918) [rt.jar:1.6.0_45]
at java.lang.Thread.run(Thread.java:662) [rt.jar:1.6.0_45]
Caused by: java.sql.SQLException: javax.resource.ResourceException: IJ000451: The connection manager is shutdown: java:/my/DS1
at org.jboss.jca.adapters.jdbc.WrapperDataSource.getConnection(WrapperDataSource.java:137)
at org.springframework.jdbc.datasource.DataSourceUtils.doGetConnection(DataSourceUtils.java:111) [spring-jdbc-3.2.3.RELEASE.jar:3.2.3.RELEASE]
at org.springframework.jdbc.datasource.DataSourceUtils.getConnection(DataSourceUtils.java:77) [spring-jdbc-3.2.3.RELEASE.jar:3.2.3.RELEASE]
... 26 more
Caused by: javax.resource.ResourceException: IJ000451: The connection manager is shutdown: java:/my/DS1
at org.jboss.jca.core.connectionmanager.AbstractConnectionManager.getManagedConnection(AbstractConnectionManager.java:321)
at org.jboss.jca.core.connectionmanager.tx.TxConnectionManagerImpl.getManagedConnection(TxConnectionManagerImpl.java:368)
at org.jboss.jca.core.connectionmanager.AbstractConnectionManager.allocateConnection(AbstractConnectionManager.java:464)
at org.jboss.jca.adapters.jdbc.WrapperDataSource.getConnection(WrapperDataSource.java:129)
... 28 more
14:31:53,640 INFO [MY-APP.Shutdown] Shutdown complete
14:31:53,651 INFO [org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean] Closing JPA EntityManagerFactory for persistence unit 'default'
14:31:53,656 INFO [org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean] Closing JPA EntityManagerFactory for persistence unit 'default'
14:31:53,837 INFO [org.jboss.as.server.deployment] JBAS015877: Stopped deployment MY-APP.war in 2259ms
14:31:56,158 INFO [com.arjuna.ats.jbossatx] ARJUNA032018: Destroying TransactionManagerService
14:31:56,158 INFO [com.arjuna.ats.jbossatx] ARJUNA032014: Stopping transaction recovery manager
14:31:56,160 INFO [org.jboss.as] JBAS015950: JBoss AS 7.1.1.Final "Brontes" stopped in 4567ms
In my standalone.xml I have
<subsystem xmlns="urn:jboss:domain:datasources:1.0">
<datasources>
<datasource jndi-name="java:/my/DS1" pool-name="My1" enabled="true" use-java-context="true">
<connection-url>jdbc:oracle:thin:#10.172.1.1:1521:ABCD</connection-url>
<driver>oracle</driver>
<pool>
<min-pool-size>1</min-pool-size>
<max-pool-size>10</max-pool-size>
<prefill>true</prefill>
<use-strict-min>false</use-strict-min>
</pool>
<security>
<user-name>xxx</user-name>
<password>xxx</password>
</security>
<timeout>
<idle-timeout-minutes>5</idle-timeout-minutes>
</timeout>
<statement>
<prepared-statement-cache-size>500</prepared-statement-cache-size>
<share-prepared-statements>true</share-prepared-statements>
</statement>
</datasource>
<drivers>
<driver name="oracle" module="com.oracle"/>
</drivers>
</datasources>
</subsystem>
then, I lookup the datasources in the code:
DataSource ds = new InitialContext().lookup("java:/my/DS1");
JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource);
The datasource has to be looked up programmatically and not hard-coded in spring.xml since there can be multiple data sources and their JNDI names are configured in external properties file that the application scans on startup.
Then, the jdbcTemplate is passed to a TableScanner that is invoked with Spring scheduling:
public TableScanner(JdbTemplate jdbcTemplate) {
this.jdbcTemplate = jdbcTemplate;
}
#Scheduled(fixedDelay = 5000)
public void run() {
// query a table using jdbcTemplate and process the retrieved records, deleting them at the end of processing
}
When stopping of the server occurs during run() method invocation, all the retrieved records should be processed and deleted. When the application tries to delete them, the connection manager is already closed, hence the exception.
Is there any way to make the connection manager (or any other JBoss AS subsystem I might need) to wait until the application is stopped?

I had the same problem, and I have now found the cause described in https://issues.jboss.org/browse/WFLY-944 . The solution proposed there in order to avoid it, is to declare the jndi as a resource in your web application, so that it does not unbind from the jboss server before your application terminates.
To achieve this add the following part to your web.xml which sets a reference to your jboss jndi with name "jdbc/myDS".
<resource-ref>
<res-ref-name>jdbc/myDS</res-ref-name>
<res-type>javax.sql.DataSource</res-type>
<res-auth>Container</res-auth>
<lookup-name>java:/my/DS1</lookup-name>
</resource-ref>
Then instead of looking up "java:/my/DS1" from your code part that points to the actual jndi, you should now instead look up "java:comp/env/jdbc/myDS" which will reference the resource you put in the web.xml that actually points to the actual jndi (that we previously specified as the 'lookup-name' xml property in the part added in the web.xml):
DataSource ds = (DataSource)
ctx.lookup("java:comp/env/jdbc/myDS");

I don't know which functionality is offered by Spring Scheduling, but if you had used an executor from the standard API, the solution would have been to add a ServletContextListener to your web application, which is invoked by the container when undeploying or stopping your application. In the contextDestroyed(ServletContextEvent sce) method, you would then invoke something like executor.shutdown(); executor.awaitTermination(Long.MAX_VALUE, TimeUnit.SECONDS), which will stop the executor and wait for all pending tasks to finish. You may want to consider using a shorter timeout when invoking awaitTermination.
IMHO the better solution may be to avoid using Spring within Java EE applications, at least when exactly the same functionality is offered by the Java EE application server as well, as in this case.

Have you considered using EJB Scheduled bean? This way jboss will spawn the worker thread.

I found this JBoss AS issue, which reflects my problem. It appears that if the data sources are not bound in a static way, via #Resource, then the server does not know that the data source is still in use. I went with letting Spring manage the data sources on its own, which may not be the Java EE way, but gets the work done and is appropriate in my situation.

Related

Unable to add SQL Server DataSource in JBoss EAP 7.2

I am trying to add an SQL Server datasource in JBoss EAP 7.2 through the management console. However, the Test Connection operation is failing. Below are the version details:
JBoss EAP - 7.2
MSSQL Driver Jar - mssql-jdbc-6.1.0.jre8.jar
Module.xml:
<module name="com.microsoft.sqlserver" xmlns="urn:jboss:module:1.3">
<resources>
<resource-root path="mssql-jdbc-6.1.0.jre8.jar"/>
</resources>
<dependencies>
<module name="javax.api"/>
<module name="javax.transaction.api"/>
<module name="javax.servlet.api" optional="true"/>
</dependencies>
</module>
Module Directory Structure:
jboss-eap-7.2\modules\system\layers\base\com\microsoft\sqlserver\main
Standalone.xml Datasource and Driver Configuration:
<datasource jndi-name="java:/MSSQLDS" pool-name="MSSQLDS">
<connection-url>jdbc:sqlserver://192.168.XX.XX;DatabaseName=MYTESTDB1</connection-url>
<datasource-class>com.microsoft.sqlserver.jdbc.SQLServerDataSource</datasource-class>
<driver>sqlserver</driver>
<security>
<user-name>mydb_xxxx</user-name>
<password>xxxxxxxx</password>
</security>
</datasource>
<driver name="sqlserver" module="com.microsoft.sqlserver">
<xa-datasource-class>com.microsoft.sqlserver.jdbc.SQLServerXADataSource</xa-datasource-class>
<datasource-class>com.microsoft.sqlserver.jdbc.SQLServerDataSource</datasource-class>
</driver>
Server Logs:
13:21:52,267 WARN [org.jboss.as.connector.subsystems.datasources.AbstractDataSourceService$AS7DataSourceDeployer] (MSC service thread 1-5) IJ020020: Connection Properties for DataSource: 'java:/MSSQLDS' is empty, try to use driver-class: 'com.microsoft.sqlserver.jdbc.SQLServerDriver' and connection-url: 'jdbc:sqlserver://192.168.XX.XX;DatabaseName=MYTESTDB1' to connect database
13:21:52,279 INFO [org.jboss.as.connector.subsystems.datasources] (MSC service thread 1-1) WFLYJCA0001: Bound data source [java:jboss/datasources/ExampleDS]
13:21:52,279 INFO [org.jboss.as.connector.subsystems.datasources] (MSC service thread 1-7) WFLYJCA0001: Bound data source [java:/MSSQLDS]
13:21:52,640 INFO [org.wildfly.extension.undertow] (MSC service thread 1-2) WFLYUT0006: Undertow HTTPS listener https listening on 127.0.0.1:8443
13:21:52,803 INFO [org.jboss.ws.common.management] (MSC service thread 1-8) JBWS022052: Starting JBossWS 5.2.4.Final-redhat-00001 (Apache CXF 3.2.5.redhat-00001)
13:21:54,308 INFO [org.infinispan.factories.GlobalComponentRegistry] (MSC service thread 1-7) ISPN000128: Infinispan version: Infinispan 'Estrella Galicia' 9.3.3.Final-redhat-00001
13:21:54,598 INFO [org.jboss.as.clustering.infinispan] (ServerService Thread Pool -- 72) WFLYCLINF0002: Started client-mappings cache from ejb container
13:21:54,792 INFO [org.jboss.as] (Controller Boot Thread) WFLYSRV0060: Http management interface listening on http://127.0.0.1:9990/management
13:21:54,924 INFO [org.jboss.as] (Controller Boot Thread) WFLYSRV0051: Admin console listening on http://127.0.0.1:9990
13:21:54,929 INFO [org.jboss.as] (Controller Boot Thread) WFLYSRV0025: JBoss EAP 7.2.0.GA (WildFly Core 6.0.11.Final-redhat-00001) started in 8695ms - Started 477 of 663 services (333 services are lazy, passive or on-demand)
13:22:21,345 WARN [org.jboss.jca.core.connectionmanager.pool.strategy.OnePool] (External Management Request Threads -- 1) IJ000604: Throwable while attempting to get a new connection: null: javax.resource.ResourceException: IJ031084: Unable to create connection
at org.jboss.jca.adapters.jdbc.local.LocalManagedConnectionFactory.createLocalManagedConnection(LocalManagedConnectionFactory.java:345)
at org.jboss.jca.adapters.jdbc.local.LocalManagedConnectionFactory.getLocalManagedConnection(LocalManagedConnectionFactory.java:352)
at org.jboss.jca.adapters.jdbc.local.LocalManagedConnectionFactory.createManagedConnection(LocalManagedConnectionFactory.java:287)
at org.jboss.jca.core.connectionmanager.pool.mcp.SemaphoreConcurrentLinkedDequeManagedConnectionPool.createConnectionEventListener(SemaphoreConcurrentLinkedDequeManagedConnectionPool.java:1326)
at org.jboss.jca.core.connectionmanager.pool.mcp.SemaphoreConcurrentLinkedDequeManagedConnectionPool.getConnection(SemaphoreConcurrentLinkedDequeManagedConnectionPool.java:499)
at org.jboss.jca.core.connectionmanager.pool.AbstractPool.internalTestConnection(AbstractPool.java:1067)
at org.jboss.jca.core.connectionmanager.pool.strategy.OnePool.testConnection(OnePool.java:93)
at org.jboss.as.connector.subsystems.common.pool.PoolOperations$TestConnectionInPool.invokeCommandOn(PoolOperations.java:240)
at org.jboss.as.connector.subsystems.common.pool.PoolOperations$1.execute(PoolOperations.java:97)
at org.jboss.as.controller.AbstractOperationContext.executeStep(AbstractOperationContext.java:999)
at org.jboss.as.controller.AbstractOperationContext.processStages(AbstractOperationContext.java:743)
at org.jboss.as.controller.AbstractOperationContext.executeOperation(AbstractOperationContext.java:467)
at org.jboss.as.controller.OperationContextImpl.executeOperation(OperationContextImpl.java:1411)
at org.jboss.as.controller.ModelControllerImpl.internalExecute(ModelControllerImpl.java:423)
at org.jboss.as.controller.ModelControllerImpl.lambda$execute$1(ModelControllerImpl.java:243)
at org.wildfly.security.auth.server.SecurityIdentity.runAs(SecurityIdentity.java:265)
at org.wildfly.security.auth.server.SecurityIdentity.runAs(SecurityIdentity.java:231)
at org.jboss.as.controller.ModelControllerImpl.execute(ModelControllerImpl.java:243)
at org.jboss.as.domain.http.server.DomainApiHandler.handleRequest(DomainApiHandler.java:212)
at io.undertow.server.handlers.encoding.EncodingHandler.handleRequest(EncodingHandler.java:72)
at org.jboss.as.domain.http.server.DomainApiCheckHandler.handleRequest(DomainApiCheckHandler.java:93)
at org.jboss.as.domain.http.server.security.ElytronIdentityHandler.lambda$handleRequest$0(ElytronIdentityHandler.java:62)
at org.wildfly.security.auth.server.SecurityIdentity.runAs(SecurityIdentity.java:289)
at org.wildfly.security.auth.server.SecurityIdentity.runAs(SecurityIdentity.java:246)
at org.jboss.as.controller.AccessAuditContext.doAs(AccessAuditContext.java:254)
at org.jboss.as.controller.AccessAuditContext.doAs(AccessAuditContext.java:225)
at org.jboss.as.domain.http.server.security.ElytronIdentityHandler.handleRequest(ElytronIdentityHandler.java:61)
at io.undertow.server.handlers.BlockingHandler.handleRequest(BlockingHandler.java:56)
at io.undertow.server.Connectors.executeRootHandler(Connectors.java:360)
at io.undertow.server.HttpServerExchange$1.run(HttpServerExchange.java:830)
at org.jboss.threads.ContextClassLoaderSavingRunnable.run(ContextClassLoaderSavingRunnable.java:35)
at org.jboss.threads.EnhancedQueueExecutor.safeRun(EnhancedQueueExecutor.java:1985)
at org.jboss.threads.EnhancedQueueExecutor$ThreadBody.doRunTask(EnhancedQueueExecutor.java:1487)
at org.jboss.threads.EnhancedQueueExecutor$ThreadBody.run(EnhancedQueueExecutor.java:1378)
at java.lang.Thread.run(Thread.java:748)
at org.jboss.threads.JBossThread.run(JBossThread.java:485)
Caused by: com.microsoft.sqlserver.jdbc.SQLServerException: The TCP/IP connection to the host localhost, port 1433 has failed. Error: "Connection refused: no further information. Verify the connection properties. Make sure that an instance of SQL Server is running on the host and accepting TCP/IP connections at the port. Make sure that TCP connections to the port are not blocked by a firewall.".
at com.microsoft.sqlserver.jdbc.SQLServerException.makeFromDriverError(SQLServerException.java:206)
at com.microsoft.sqlserver.jdbc.SQLServerException.ConvertConnectExceptionToSQLServerException(SQLServerException.java:257)
at com.microsoft.sqlserver.jdbc.SocketFinder.findSocket(IOBuffer.java:2385)
at com.microsoft.sqlserver.jdbc.TDSChannel.open(IOBuffer.java:567)
at com.microsoft.sqlserver.jdbc.SQLServerConnection.connectHelper(SQLServerConnection.java:1955)
at com.microsoft.sqlserver.jdbc.SQLServerConnection.login(SQLServerConnection.java:1616)
at com.microsoft.sqlserver.jdbc.SQLServerConnection.connectInternal(SQLServerConnection.java:1447)
at com.microsoft.sqlserver.jdbc.SQLServerConnection.connect(SQLServerConnection.java:788)
at com.microsoft.sqlserver.jdbc.SQLServerDataSource.getConnectionInternal(SQLServerDataSource.java:719)
at com.microsoft.sqlserver.jdbc.SQLServerDataSource.getConnection(SQLServerDataSource.java:79)
at org.jboss.jca.adapters.jdbc.local.LocalManagedConnectionFactory.createLocalManagedConnection(LocalManagedConnectionFactory.java:314)
... 35 more
13:22:21,350 ERROR [org.jboss.as.controller.management-operation] (External Management Request Threads -- 1) WFLYCTL0013: Operation ("test-connection-in-pool") failed - address: ([
("subsystem" => "datasources"),
("data-source" => "MSSQLDS")
]) - failure description: "WFLYJCA0040: failed to invoke operation: WFLYJCA0047: Connection is not valid"
Update -
Even though i have specified the IP address of my database, JBoss is trying to connect to localhost instead of that IP.
I have verified and ruled out any network / firewall related problems. Through a sample Java/SpringBoot project, i am able to open a JDBC connection to the database. However, the datasource creation from JBoss is failing.
Found the solution finally. It’s a problem with Wildfly when the datasource-class is used while adding the driver module.
With the datasource class, explicit connection properties are required and the connection-url tag is “effectively” ignored. By “effectively” ignored, I mean JBoss erroneously expects connection-url tag to be present and just ignores it.
This issue has been called out in issues - WFLY-6157 and WFLY-6200.
This is a little bit late but the solution can be found in redhat solutions. The issue is when defining non-XA datasource, datasource-class has been define in the datasource setup.
So what I did is goto admin console > configuration > subsystems > Datasource & drivers > Datasources > < datasource name > > click view.
on the attributes tab > click edit > delete the value in Datasource Class > save and reload server.
Test your connection now and it should be successful.
Solution for me, edit file standalone.xml:
<datasource jndi-name="java:jboss/datasources/SqlServerdb" pool-name="SqlServerdb" statistics-enabled="true">
<datasource-class>com.microsoft.sqlserver.jdbc.SQLServerDataSource</datasource-class>
<connection-property name="databaseName">
DATABASENAME
</connection-property>
<connection-property name="ServerName">
IP(WITHOUT PORT)
</connection-property>
<driver>sqlserver</driver>
<security>
<user-name>USER</user-name>
<password>PASSWORD</password>
</security>
<validation>
<valid-connection-checker class-name="org.jboss.jca.adapters.jdbc.extensions.mssql.MSSQLValidConnectionChecker"/>
<background-validation>true</background-validation>
</validation>
</datasource>
and:
<driver name="sqlserver" module="com.microsoft.sqlserver">
<driver-class>com.microsoft.sqlserver.jdbc.SQLServerDriver</driver-class>
<xa-datasource-class>com.microsoft.sqlserver.jdbc.SQLServerXADataSource</xa-datasource-class>
</driver>
Taking into account Vaibhav1988's comments about "the datasource class needs explicit connection properties", in my case the solution was adding the following 2 properties under the datasource configuration:
databaseName=
ServerName=
In the Management Console go to "Subsystems" -> "Datasources & Drivers" -> "Datasources" then click on "View" in your datasource, go to "Connection" tab, click on "Edit" and add the properties in the field that says "Connection Properties".

Spring boot application fials to deploy in a particular environment

I am facing a very unique problem where the spring boot application fails to deploy in a particular environment. I was able to successfully deploy the application with out an issue in other environment. Following is the stacktace
21:06:29,812 ERROR [org.jboss.web] (MSC service thread 1-1) JBAS018202: **Error calling onStartup for servlet container initializer: org.springframework.web.SpringServletContainerInitializer: java.lang.IllegalArgumentException: LoggerFactory is not a Logback LoggerContext but Logback is on the classpath. Either remove Logback or the competing implementation (class org.slf4j.impl.Log4jLoggerFactory loaded from vfs:/content/dmcacctservices.war/WEB-INF/lib/slf4j-log4j12-1.7.12.jar). If you are using Weblogic you will need to add 'org.slf4j' to prefer-application-packages in WEB-INF/weblogic.xml Object of class [org.slf4j.impl.Log4jLoggerFactory] must be an instance of class ch.qos.logback.classic.LoggerContext**
at org.springframework.util.Assert.isInstanceOf(Assert.java:339) [spring-core-4.1.7.RELEASE.jar:4.1.7.RELEASE]
at org.springframework.boot.logging.logback.LogbackLoggingSystem.getLoggerContext(LogbackLoggingSystem.java:151) [spring-boot-1.2.5.RELEASE.jar:1.2.5.RELEASE]
at org.springframework.boot.logging.logback.LogbackLoggingSystem.getLogger(LogbackLoggingSystem.java:143) [spring-boot-1.2.5.RELEASE.jar:1.2.5.RELEASE]
at org.springframework.boot.logging.logback.LogbackLoggingSystem.beforeInitialize(LogbackLoggingSystem.java:89) [spring-boot-1.2.5.RELEASE.jar:1.2.5.RELEASE]
at org.springframework.boot.logging.LoggingApplicationListener.onApplicationStartedEvent(LoggingApplicationListener.java:152) [spring-boot-1.2.5.RELEASE.jar:1.2.5.RELEASE]
at org.springframework.boot.logging.LoggingApplicationListener.onApplicationEvent(LoggingApplicationListener.java:139) [spring-boot-1.2.5.RELEASE.jar:1.2.5.RELEASE]
at org.springframework.context.event.SimpleApplicationEventMulticaster.invokeListener(SimpleApplicationEventMulticaster.java:151) [spring-context-4.1.7.RELEASE.jar:4.1.7.RELEASE]
at org.springframework.context.event.SimpleApplicationEventMulticaster.multicastEvent(SimpleApplicationEventMulticaster.java:128) [spring-context-4.1.7.RELEASE.jar:4.1.7.RELEASE]
at org.springframework.boot.context.event.EventPublishingRunListener.publishEvent(EventPublishingRunListener.java:100) [spring-boot-1.2.5.RELEASE.jar:1.2.5.RELEASE]
at org.springframework.boot.context.event.EventPublishingRunListener.started(EventPublishingRunListener.java:54) [spring-boot-1.2.5.RELEASE.jar:1.2.5.RELEASE]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:277) [spring-boot-1.2.5.RELEASE.jar:1.2.5.RELEASE]
at org.springframework.boot.context.web.SpringBootServletInitializer.run(SpringBootServletInitializer.java:119) [spring-boot-1.2.5.RELEASE.jar:1.2.5.RELEASE]
at org.springframework.boot.context.web.SpringBootServletInitializer.createRootApplicationContext(SpringBootServletInitializer.java:110) [spring-boot-1.2.5.RELEASE.jar:1.2.5.RELEASE]
at org.springframework.boot.context.web.SpringBootServletInitializer.onStartup(SpringBootServletInitializer.java:69) [spring-boot-1.2.5.RELEASE.jar:1.2.5.RELEASE]
at com.disney.dmcacctservices.config.DmcacctservicesApplication.onStartup(DmcacctservicesApplication.java:54) [classes:]
at org.springframework.web.SpringServletContainerInitializer.onStartup(SpringServletContainerInitializer.java:175) [spring-web-4.1.7.RELEASE.jar:4.1.7.RELEASE]
at org.jboss.as.web.deployment.JBossContextConfig.lifecycleEvent(JBossContextConfig.java:148) [jboss-as-web-7.1.1.Final.jar:7.1.1.Final]
at org.apache.catalina.util.LifecycleSupport.fireLifecycleEvent(LifecycleSupport.java:115) [jbossweb-7.0.13.Final.jar:]
at org.apache.catalina.core.StandardContext.start(StandardContext.java:3845) [jbossweb-7.0.13.Final.jar:]
at org.jboss.as.web.deployment.WebDeploymentService.start(WebDeploymentService.java:90) [jboss-as-web-7.1.1.Final.jar:7.1.1.Final]
at org.jboss.msc.service.ServiceControllerImpl$StartTask.startService(ServiceControllerImpl.java:1811)
at org.jboss.msc.service.ServiceControllerImpl$StartTask.run(ServiceControllerImpl.java:1746)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145) [rt.jar:1.7.0_72]
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615) [rt.jar:1.7.0_72]
at java.lang.Thread.run(Thread.java:745) [rt.jar:1.7.0_72]
We even tried copying the JBOSS instance from other environments over to this particular environment and still get the error, eliminating JBOSS being the culprit. we even checked the jdk on the vms and its the same version.
The error seems like a classpath issue and can probably be fixed by excluding the logback from the pom file. But the question is how come it works on other environment and whats different in this particular environment. I have exhausted all ideas and would appreciate your input on this.
Looks like you have both Log4j and Logback in your war. Assuming that you want to use Logback, you should exclude Log4j. As for why the problem doesn't happen consistently, I would guess that the jars in WEB-INF/lib are being loaded in different orders by JBoss.

Global Tomcat 8 DataSource resource closed before `ServletContextListener.contextDestroyed()` is executed

I deployed a web application onto Tomcat 8. In that application a global JNDI DataSource is defined that is shared between several servlets. Inside the application it is wrapped within a Spring bean which uses a factory method to retrieve that once from JNDI. There is also a ServletContextListener implemented to react when the web applications context gets destroyed. The application itself works fine and the DataSource can be properly retrieved and used.
The Problem: On a Tomcat shutdown (catalina.sh stop, SIGINT or SIGTERM) the DataSource gets closed before the ServletContextListener.contextDestroyed() is invoked. That is bad because I need to access the DB in that method (e.g. to shutdown our Quartz scheduler properly which has database access).
Here is a snippet of the server.xml:
<Server port="8005" shutdown="SHUTDOWN">
...
<GlobalNamingResources>
...
<Resource name="myDB" auth="Container" type="javax.sql.DataSource"
maxTotal="100" maxIdle="30" maxWaitMillis="10000" username="" password=""
removeAbandonedOnBorrow="true" removeAbandonedTimeout="60" driverClassName="org.h2.Driver"
url="jdbc:h2:myApp" defaultTransactionIsolation="READ_COMMITTED" />
...
</GlobalNamingResources>
...
</Server>
Here from the context.xml:
<Context path="/myApp" docBase="myApp"
reloadable="false" crossContext="false" antiResourceLocking="true" unloadDelay="5000">
<ResourceLink name="jdbc/myDB" global="myDB" type="javax.sql.DataSource" />
<Manager className="org.apache.catalina.session.PersistentManager"
distributable="false" saveOnRestart="false">
<Store className="org.apache.catalina.session.FileStore"/>
</Manager>
</Context>
Here a snippet of my ServletContextListener:
public class MyListener implements ServletContextListener {
...
#Override
public void contextDestroyed(ServletContextEvent sce) {
...
// using the DataSource here
...
}
...
}
In the logs I can see an Exception when I try to use the DataSource in the ServletContextListener saying that the Data source is already closed:
05 Aug 2015 14:59:17,915 [localhost-startStop-2] () || DEBUG DisposableBeanAdapter: Invoking destroy method 'close' on bean with name 'dataSource'
05-Aug-2015 14:59:17.918 WARNING [localhost-startStop-2] org.apache.tomcat.dbcp.dbcp2.BasicDataSource.close Failed to unregister the JMX name: Catalina:type=DataSource,class=javax.sql.DataSource,name="myDB"
javax.management.InstanceNotFoundException: Catalina:type=DataSource,class=javax.sql.DataSource,name="myDB"
at com.sun.jmx.interceptor.DefaultMBeanServerInterceptor.getMBean(Unknown Source)
at com.sun.jmx.interceptor.DefaultMBeanServerInterceptor.exclusiveUnregisterMBean(Unknown Source)
at com.sun.jmx.interceptor.DefaultMBeanServerInterceptor.unregisterMBean(Unknown Source)
at com.sun.jmx.mbeanserver.JmxMBeanServer.unregisterMBean(Unknown Source)
at org.apache.tomcat.dbcp.dbcp2.BasicDataSource.close(BasicDataSource.java:1916)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at org.springframework.beans.factory.support.DisposableBeanAdapter.invokeCustomDestroyMethod(DisposableBeanAdapter.java:327)
at org.springframework.beans.factory.support.DisposableBeanAdapter.destroy(DisposableBeanAdapter.java:253)
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.destroyBean(DefaultSingletonBeanRegistry.java:510)
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.destroySingleton(DefaultSingletonBeanRegistry.java:486)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.destroySingleton(DefaultListableBeanFactory.java:742)
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.destroySingletons(DefaultSingletonBeanRegistry.java:455)
at org.springframework.context.support.AbstractApplicationContext.destroyBeans(AbstractApplicationContext.java:1090)
at org.springframework.context.support.AbstractApplicationContext.doClose(AbstractApplicationContext.java:1064)
at org.springframework.context.support.AbstractApplicationContext.close(AbstractApplicationContext.java:1010)
at org.springframework.web.context.ContextLoader.closeWebApplicationContext(ContextLoader.java:586)
at org.springframework.web.context.ContextLoaderListener.contextDestroyed(ContextLoaderListener.java:143)
at org.apache.catalina.core.StandardContext.listenerStop(StandardContext.java:4776)
at org.apache.catalina.core.StandardContext.stopInternal(StandardContext.java:5390)
at org.apache.catalina.util.LifecycleBase.stop(LifecycleBase.java:232)
at org.apache.catalina.core.ContainerBase$StopChild.call(ContainerBase.java:1424)
at org.apache.catalina.core.ContainerBase$StopChild.call(ContainerBase.java:1413)
at java.util.concurrent.FutureTask.run(Unknown Source)
at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
at java.lang.Thread.run(Unknown Source)
...
Shutting down scheduler.
...
05 Aug 2015 14:59:24,098 [QuartzScheduler_DefaultQuartzScheduler-4424f282be6c1438786703813_ClusterManager] () || ERROR JobStoreTX : ClusterManager: Error managing cluster: Failed to obtain DB connection from data source 'qrtzds': java.sql.SQLException: Could not retrieve datasource via JNDI url 'java:comp/env/jdbc/myDB' java.sql.SQLException: Data source is closed
org.quartz.JobPersistenceException: Failed to obtain DB connection from data source 'qrtzds': java.sql.SQLException: Could not retrieve datasource via JNDI url 'java:comp/env/jdbc/myDB' java.sql.SQLException: Data source is closed [See nested exception: java.sql.SQLException: Could not retrieve datasource via JNDI url 'java:comp/env/jdbc/myDB' java.sql.SQLException: Data source is closed]
at org.quartz.impl.jdbcjobstore.JobStoreSupport.getConnection(JobStoreSupport.java:778)
at org.quartz.impl.jdbcjobstore.JobStoreTX.getNonManagedTXConnection(JobStoreTX.java:71)
at org.quartz.impl.jdbcjobstore.JobStoreSupport.doCheckin(JobStoreSupport.java:3245)
at org.quartz.impl.jdbcjobstore.JobStoreSupport$ClusterManager.manage(JobStoreSupport.java:3858)
at org.quartz.impl.jdbcjobstore.JobStoreSupport$ClusterManager.run(JobStoreSupport.java:3895)
Caused by: java.sql.SQLException: Could not retrieve datasource via JNDI url 'java:comp/env/jdbc/myDB' java.sql.SQLException: Data source is closed
at org.quartz.utils.JNDIConnectionProvider.getConnection(JNDIConnectionProvider.java:163)
at org.quartz.utils.DBConnectionManager.getConnection(DBConnectionManager.java:108)
at org.quartz.impl.jdbcjobstore.JobStoreSupport.getConnection(JobStoreSupport.java:775)
... 4 more
Question:
How can I control the lifecycle of Tomcat to close the global DataSource resource after the web application context is destroyed?
How can I tell Spring to not invoke the BasicDataSource.close() method? I tried to set the bean attribute destroy-method to an empty value. But it seems that when that is empty it still invokes the close() method because it detects an AutoClosable.

JBAS011006 Not installing optional component StandardServletAsyncWebRequest due to exception DeploymentUnitProcessingException [duplicate]

This question already has answers here:
Spring3.2 and jboss as 7
(4 answers)
Closed 9 years ago.
Since, Spring 3.2 GA release is out I wanted to upgrade my Spring 3.1.2 application to the newest release. The application runs on JBoss 7.1.1.Final. Everything else went fine except that I get the below JBoss error message which I find annoying (though the app runs ok). Any idea?
15:50:06,865 WARN [org.jboss.as.ee] (MSC service thread 1-13) JBAS011006: Not installing optional component org.springframework.web.context.request.async.StandardServletAsyncWebRequest due to exception: org.jboss.as.server.deployment.DeploymentUnitProcessingException: JBAS011054: Could not find default constructor for class org.springframework.web.context.request.async.StandardServletAsyncWebRequest
at org.jboss.as.ee.component.ComponentDescription$DefaultComponentConfigurator.configure(ComponentDescription.java:606)
at org.jboss.as.ee.component.deployers.EEModuleConfigurationProcessor.deploy(EEModuleConfigurationProcessor.java:81)
at org.jboss.as.server.deployment.DeploymentUnitPhaseService.start(DeploymentUnitPhaseService.java:113) [jboss-as-server-7.1.1.Final.jar:7.1.1.Final]
at org.jboss.msc.service.ServiceControllerImpl$StartTask.startService(ServiceControllerImpl.java:1811) [jboss-msc-1.0.2.GA.jar:1.0.2.GA]
at org.jboss.msc.service.ServiceControllerImpl$StartTask.run(ServiceControllerImpl.java:1746) [jboss-msc-1.0.2.GA.jar:1.0.2.GA]
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1110) [rt.jar:1.7.0_05]
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:603) [rt.jar:1.7.0_05]
at java.lang.Thread.run(Thread.java:722) [rt.jar:1.7.0_05]
In order to suppress this warning message add following lines to your Jboss config (standalone.xml if you're using it in standalone mode)
<?xml version='1.0' encoding='UTF-8'?>
<server xmlns="urn:jboss:domain:1.1">
...
<profile>
<subsystem xmlns="urn:jboss:domain:logging:1.1">
<console-handler name="CONSOLE">
<level name="INFO"/>
<filter>
<not>
<match pattern="JBAS011006"/>
</not>
</filter>
...
As you can check in javadocs, there's no default constructor for this class.
Since it's just a warning and everything goes fine, you can ignore it.

Why #Scheduled and <task:scheduled ../> behave differently for dependencies injection in Spring 3.1?

I need to schedule a task using Spring 3.1.
I'm using Roo's with ActiveRecord pattern for entities.
Method to be scheduled is very simple, in a dedicated service bean:
public void sessionCleanup() {
featureSessionManager.sessionCleanup();
}
...configured as:
<bean id="scheduledTaskService" class="it.blablabla.ScheduledTaskService">
[...dependencies...]
</bean>
If I schedule it using #Scheduled(fixedRate=120000) and enabling annotation-driven scheduling with <task:annotation-driven/> everything works as expected.
But if I want to schedule the same method using XML configuration...
<task:scheduler id="scheduler" pool-size="1"/>
<task:scheduled-tasks scheduler="scheduler" >
<task:scheduled ref="scheduledTaskService" method="sessionCleanup" fixed-rate="120000"/>
</task:scheduled-tasks>
...application throws an exception on initialization.
2012-07-24 12:26:56,293 [pool-2-thread-1] INFO org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler - Initializing ExecutorService 'scheduler'
2012-07-24 12:26:56,671 [scheduler-1] ERROR org.springframework.scheduling.support.TaskUtils$LoggingErrorHandler - Unexpected error occurred in scheduled task.
java.lang.IllegalStateException: Entity manager has not been injected (is the Spring Aspects JAR configured as an AJC/AJDT aspects library?)
at it.blablabla.model.AbstractFeatureSession_Roo_Jpa_ActiveRecord.entityManager_aroundBody0(AbstractFeatureSession_Roo_Jpa_ActiveRecord.aj:38)
at it.blablabla.model.AbstractFeatureSession_Roo_Jpa_ActiveRecord.ajc$interMethod$it.blablabla_model_AbstractFeatureSession_Roo_Jpa_ActiveRecord$it.blablabla_model_AbstractFeatureSession$entityManager(AbstractFeatureSession_Roo_Jpa_ActiveRecord.aj:1)
at it.blablabla.model.AbstractFeatureSession.entityManager(AbstractFeatureSession.java:1)
at it.blablabla.model.AbstractFeatureSession_Roo_Jpa_ActiveRecord.ajc$interMethodDispatch1$it.blablabla_model_AbstractFeatureSession_Roo_Jpa_ActiveRecord$it.blablabla_model_AbstractFeatureSession$entityManager(AbstractFeatureSession_Roo_Jpa_ActiveRecord.aj)
at it.blablabla.model.FeatureSession.updateAsDroppedAllExpiredAndNotDropped_aroundBody10(FeatureSession.java:245)
at it.blablabla.model.FeatureSession.updateAsDroppedAllExpiredAndNotDropped(FeatureSession.java:1)
at it.blablabla.service.FeatureSessionManagementServiceImpl.dropExpiredSessions(FeatureSessionManagementServiceImpl.java:154)
at it.blablabla.service.FeatureSessionManagementServiceImpl.sessionCleanup(FeatureSessionManagementServiceImpl.java:178)
at it.blablabla.task.ScheduledTaskWorker.sessionCleanup(ScheduledTaskWorker.java:37)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at org.springframework.scheduling.support.ScheduledMethodRunnable.run(ScheduledMethodRunnable.java:64)
at org.springframework.scheduling.support.DelegatingErrorHandlingRunnable.run(DelegatingErrorHandlingRunnable.java:53)
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:441)
at java.util.concurrent.FutureTask$Sync.innerRunAndReset(FutureTask.java:317)
at java.util.concurrent.FutureTask.runAndReset(FutureTask.java:150)
at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$101(ScheduledThreadPoolExecutor.java:98)
at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.runPeriodic(ScheduledThreadPoolExecutor.java:180)
at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:204)
at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908)
at java.lang.Thread.run(Thread.java:662)
Apparently it fails to inject EntityManager into entities instantiated by the task.
(Roo's ActiveRecords are #Configurable and EntityManager is injected on instance creation)
This happens either in Tomcat or in a JUnit.

Categories