I am trying go get Connection Pool with Tomcat DataSource and MySQL in ntellij idea 14. I've done these steps:
Select "Project Structure" from the File menu
From there, select the "Facets" option. Make sure that you have a Web
facet configured. If not, add one.
Once the web facet is added, select "Add Application Server specific
descriptor..."
Select Tomcat Context Descriptor from the options and click OK.
I got META-INF/context.xml in web directory. I added next lines in context.xml
<?xml version="1.0" encoding="UTF-8"?>
<Context>
<Resource name="jdbc/payments"
auth="Container"
type="javax.sql.DataSource"
driverClassName="com.mysql.jdbc.Driver"
url="jdbc:mysql://localhost:3306/paymentsdb"
username="root"
password="password"
maxActive="100"
maxIdle="20"
minIdle="5"
maxWait="10000"/>
</Context>
And this into web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
version="3.1">
<!--DB Connection start-->
<description>MySQL Test App</description>
<resource-ref>
<description>DB Connection</description>
<res-ref-name>jdbc/payments</res-ref-name>
<res-type>javax.sql.DataSource</res-type>
<res-auth>Container</res-auth>
</resource-ref>
</web-app>
This is my method to get connection
public static Connection createConnection(){
Context context = null;
DataSource dataSource = null;
Connection connection = null;
try {
context = (Context) new InitialContext().lookup("java:comp/env");
dataSource = (DataSource) context.lookup("jdbc/payments");
connection = dataSource.getConnection();
} catch (NamingException e) {
e.printStackTrace();
} catch (SQLException e) {
e.printStackTrace();
}
return connection;
}
I got this exception in line
dataSource = (DataSource)
context.lookup("java:comp/env/jdbc/payments");
javax.naming.NoInitialContextException: Need to specify class name in environment or system property, or as an applet parameter, or in an application resource file: java.naming.factory.initial
at javax.naming.spi.NamingManager.getInitialContext(NamingManager.java:662)
at javax.naming.InitialContext.getDefaultInitCtx(InitialContext.java:313)
at javax.naming.InitialContext.getURLOrDefaultInitCtx(InitialContext.java:350)
at javax.naming.InitialContext.lookup(InitialContext.java:417)
at ua.epam.kuts.dao.MySQLDAOFactory.createConnection(MySQLDAOFactory.java:22)
at Test.main(Test.java:17)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:497)
at com.intellij.rt.execution.application.AppMain.main(AppMain.java:134)
I use Tomcat 8.0.23. Any idea? I googled for several hours and didn't find anything that helped me. Drew me mad. I checked connection with Statment and it works. I have connector.jar.
I've done stupid mistake. I was trying to test DataSource connection running it in public static main(String[] args) method instead of running it on the server. That's why InitialContext was not initialized. Found answer here in second post.
Related
I want to expose service with Spring framework (not with spring boot). Then i can use the service to feed a dashboard. Charts in the dashboard need data with json format. My question is similar to this topic but with more question about code.[question]: Expose Service Layer directly in spring mvc
I first did the model, repository to access database. I am using Hibernate and MySQL. I run my application with a class containing the main method. Then i tried to add a rest controller to access the method findAll. But when i deployed the application on Tomcat, i only get the message 404 not found.
This is my first controller
#RestController
#RequestMapping("/fruit")
public class FruitController {
#Autowired
private IFruitRepository fruitRepo = new FruitRepository();
#RequestMapping( value = "/all", method = RequestMethod.GET )
public #ResponseBody List<Port> getFruit() {
List<Fruit> res = fruitRepo.findAll();
return res;
}
}
this is the interface
public interface IFruitRepository {
Boolean create(Fruit p);
Fruit findById(int id);
List<Fruit> findAll();
Fruit update(Fruit f);
boolean delete(int id);
}
this is the implementation of findAll method
public List<Fruit> findAll(){
List<Fruit> à_retourner = new ArrayList<>();
try (SessionFactory factory = HibernateUtil.getSessionFactory()) {
Session session = factory.openSession();
Query query = session.createQuery("from Fruit");
à_retourner = query.getResultList();
} catch (Exception e) {
System.out.println("exception _ findAll _ Fruit : " + e);
}
return à_retourner;
}
EDIT:
web .xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
version="4.0">
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/applicationContext.xml</param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<servlet>
<servlet-name>dispatcher</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>dispatcher</servlet-name>
<url-pattern>*.form</url-pattern>
</servlet-mapping>
</web-app>
dispacher-servlet.xml
<?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">
</beans>
applicationcontext.xml
<?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">
</beans>
Should i add servlet , dispacher servlet , application context to find the resource through URI ?
I don't know what is exactly the url you are using to test the service but if you are trying to invoke /fruit/all, it won't work because the servlet dispatcher is configured to handle request that ends with .form. To make it work you should change the url-pattern of the servlet dispatcher to something like /fruit/*
I have an Spring MVC4 web application:
It has one controller class as follows -
#Controller
public class SeleniumController
{
#Autowired
SeleniumService seleniumService;
#RequestMapping(value={"/service/echo"}, method={org.springframework.web.bind.annotation.RequestMethod.POST})
#ResponseBody
public String echo() {
System.out.println("Inside Echo .. ");
return "echo";
}
#RequestMapping(value={"/service/changeAddress"}, method={org.springframework.web.bind.annotation.RequestMethod.POST})
#ResponseBody
public AddressChangeRequest changeAddress(#RequestBody AddressChangeRequest req) {
System.out.println("Inside AddressChange .. ");
try
{
this.seleniumService.openOipaAddressScreenRemote(req.getPolicyNumber(), req.getCaseId(), req.getTaskId(), req.getAssignedTo());
}
catch (MalformedURLException e) {
e.printStackTrace();
return req;
}
return req;
}
}
And a service class -
#Service("oipaService")
public class SeleniumService {
private static final String HUB_URL = "http://10.227.181.36:4444/wd/hub";
public void openOipaAddressScreenRemote(String policyNumber, String caseID, String taskID, String assignedTo) throws MalformedURLException {
System.out.println("Policy number input : " + policyNumber);
String oipaURL = "https://myDom.com/PASJava_Term";
DesiredCapabilities caps = DesiredCapabilities.internetExplorer();
caps.setCapability(InternetExplorerDriver.INTRODUCE_FLAKINESS_BY_IGNORING_SECURITY_DOMAINS, true);
WebDriver driver = new RemoteWebDriver(new URL(HUB_URL), caps);
WebDriverWait wait = new WebDriverWait(driver, 60);
Actions oAction = new Actions(driver);
driver.get(oipaURL);
}
}
Selenium related jars used in service class are as follows -
I have selenium hub set up at 10.227.181.36:4444
and a node in client system. jars used to set up selenium hub and node is-
selenium-server-standalone-2.53.1.jar
My goal is to post json data to REST controller from client and initiate selenium test in client browser.
And it works fine when the spring application is hosted in apache-tomcat-7(windows) and hub is set up in windows machine (jdk1.7.0_55) and node in windows machine (jdk1.7.0_55 or greater).
But When I am hosting the app in weblogic 12C(unix) and setting up hub in unix system (jdk1.7.0_55) and node in windows(jdk1.7.0_55 or greater), I get following error after posting a json to my rest service-
java.lang.NoSuchMethodError: com.google.common.collect.Multimaps.transformValues(Lcom/google/common/collect/ListMultimap;Lcom/google/common/base/Function;)Lcom/google/common/collect/ListMultimap;
at com.google.common.net.MediaType.toString(MediaType.java:708)
at org.openqa.selenium.remote.http.JsonHttpCommandCodec.encode(JsonHttpCommandCodec.java:197)
at org.openqa.selenium.remote.HttpCommandExecutor.execute(HttpCommandExecutor.java:130)
at org.openqa.selenium.remote.RemoteWebDriver.execute(RemoteWebDriver.java:572)
at org.openqa.selenium.remote.RemoteWebDriver.startSession(RemoteWebDriver.java:240)
at org.openqa.selenium.remote.RemoteWebDriver.(RemoteWebDriver.java:126)
at org.openqa.selenium.remote.RemoteWebDriver.(RemoteWebDriver.java:153)
at com.cts.bpaas.service.SeleniumService.openOipaAddressScreenRemote(SeleniumService.java:229)
at com.cts.bpaas.soe.controller.SeleniumController.changeAddress(SeleniumController.java:39)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:606)
at org.springframework.web.method.support.InvocableHandlerMethod.invoke(InvocableHandlerMethod.java:215)
at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:132)
at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:104)
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandleMethod(RequestMappingHandlerAdapter.java:745)
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:686)
at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:80)
at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:925)
at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:856)
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:953)
at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:855)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:751)
at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:829)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:844)
at weblogic.servlet.internal.StubSecurityHelper$ServletServiceAction.run(StubSecurityHelper.java:280)
at weblogic.servlet.internal.StubSecurityHelper$ServletServiceAction.run(StubSecurityHelper.java:254)
at weblogic.servlet.internal.StubSecurityHelper.invokeServlet(StubSecurityHelper.java:136)
at weblogic.servlet.internal.ServletStubImpl.execute(ServletStubImpl.java:341)
at weblogic.servlet.internal.TailFilter.doFilter(TailFilter.java:25)
at weblogic.servlet.internal.FilterChainImpl.doFilter(FilterChainImpl.java:79)
at com.cts.bpaas.soe.filter.SoECORSFilter.doFilter(SoECORSFilter.java:32)
at weblogic.servlet.internal.FilterChainImpl.doFilter(FilterChainImpl.java:79)
at weblogic.servlet.internal.WebAppServletContext$ServletInvocationAction.wrapRun(WebAppServletContext.java:3367)
at weblogic.servlet.internal.WebAppServletContext$ServletInvocationAction.run(WebAppServletContext.java:3333)
at weblogic.security.acl.internal.AuthenticatedSubject.doAs(AuthenticatedSubject.java:321)
at weblogic.security.service.SecurityManager.runAs(SecurityManager.java:120)
at weblogic.servlet.provider.WlsSubjectHandle.run(WlsSubjectHandle.java:57)
at weblogic.servlet.internal.WebAppServletContext.doSecuredExecute(WebAppServletContext.java:2220)
at weblogic.servlet.internal.WebAppServletContext.securedExecute(WebAppServletContext.java:2146)
at weblogic.servlet.internal.WebAppServletContext.execute(WebAppServletContext.java:2124)
at weblogic.servlet.internal.ServletRequestImpl.run(ServletRequestImpl.java:1564)
at weblogic.servlet.provider.ContainerSupportProviderImpl$WlsRequestExecutor.run(ContainerSupportProviderImpl.java:254)
at weblogic.work.ExecuteThread.execute(ExecuteThread.java:295)
at weblogic.work.ExecuteThread.run(ExecuteThread.java:254)</font>
The GET method on /service/echo is working for both set up, but POST method on /service/changeAddress is not working for unix set up.
What am I missing?
Figured it wasn't a issue with selenium. Problem was deploying the application in weblogic 12c. guava.jar was present in both my application and weblogic, I just had to made a little change in weblogic.xml to tell weblogic to take my jar, not weblogic's.
<?xml version="1.0" encoding="UTF-8"?>
<wls:weblogic-web-app xmlns:wls="http://xmlns.oracle.com/weblogic/weblogic-web-app" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/ejb-jar_3_0.xsd
http://xmlns.oracle.com/weblogic/weblogic-web-app
http://xmlns.oracle.com/weblogic/weblogic-web-app/1.4/weblogic-web-app.xsd">
<wls:context-root>/csoe_rest</wls:context-root>
<wls:container-descriptor>
<wls:prefer-application-packages>
<wls:package-name>com.google.common.*</wls:package-name>
</wls:prefer-application-packages>
</wls:container-descriptor>
</wls:weblogic-web-app>
It worked like a charm
I have to test my route builder using JUnit and I am getting java.lang.NoSuchMethodError, Am I missing any configuration or the way I am accessing my route builder should be changed. Please find RouteBuilder, context and Junit class here
#Component
public class MyRouteBuilder extends SpringRouteBuilder {
#Autowired
private SourcePoint sourcePoint;
#Autowired
private DestinationPoint destinationPoint;
#Override
public void configure() throws Exception {
from(sourcePoint.getString()).to(destinationPoint.getString());
}
I created JUnit test case and it's context in proper maven location like below
src/test/java/org/apache/camel/spring/patterns/MyRouteBuilderTest.java
src/test/resources/org/apache/camel/spring/patterns/MyRouteBuilderTest-context.xml
Here I am attaching the both the files
***** MyRouteBuilderTest-context.xml ***
<?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
http://camel.apache.org/schema/spring
http://camel.apache.org/schema/spring/camel-spring.xsd">
<camelContext xmlns="http://camel.apache.org/schema/spring">
<routeBuilder ref="MyRouteBuilder" />
</camelContext>
<context:component-scan base-package="com.myroute" />
***** MyRouteBuilderTest.class ***
#RunWith(CamelSpringJUnit4ClassRunner.class)
#BootstrapWith(CamelTest.class)
#ContextConfiguration
#DirtiesContext(classMode = ClassMode.AFTER_EACH_TEST_METHOD)
#MockEndpoints("log:*")
#DisableJmx(false)
public class EmypaRouteBuilderTest extends CamelSpringTestSupport {
private static final Logger logger = LoggerFactory.getLogger(MyRouteBuilderTest.class);
#Autowired
private MyRouteBuilder myRouteBuilder = null;
#Override
protected AbstractApplicationContext createApplicationContext() {
return new ClassPathXmlApplicationContext("Application-context.xml");
}
#Test
public void testRead throws exception(){
context.start();
Thread.sleep(10 * 60 * 1000);
}
}
For your verification I am attaching logs as well
java.lang.NoSuchMethodError: org.springframework.test.context.TestContextManager.<init>(Ljava/lang/Class;Ljava/lang/String;)V
at org.apache.camel.test.spring.CamelSpringJUnit4ClassRunner$CamelTestContextManager.<init>(CamelSpringJUnit4ClassRunner.java:68)
at org.apache.camel.test.spring.CamelSpringJUnit4ClassRunner.createTestContextManager(CamelSpringJUnit4ClassRunner.java:47)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.<init>(SpringJUnit4ClassRunner.java:114)
at org.apache.camel.test.spring.CamelSpringJUnit4ClassRunner.<init>(CamelSpringJUnit4ClassRunner.java:36)
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:57)
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
at java.lang.reflect.Constructor.newInstance(Constructor.java:526)
at org.junit.internal.builders.AnnotatedBuilder.buildRunner(AnnotatedBuilder.java:29)
at org.junit.internal.builders.AnnotatedBuilder.runnerForClass(AnnotatedBuilder.java:21)
at org.junit.runners.model.RunnerBuilder.safeRunnerForClass(RunnerBuilder.java:59)
at org.junit.internal.builders.AllDefaultPossibilitiesBuilder.runnerForClass(AllDefaultPossibilitiesBuilder.java:26)
at org.junit.runners.model.RunnerBuilder.safeRunnerForClass(RunnerBuilder.java:59)
at org.junit.internal.requests.ClassRequest.getRunner(ClassRequest.java:26)
at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.<init>(JUnit4TestReference.java:33)
at org.eclipse.jdt.internal.junit4.runner.JUnit4TestClassReference.<init>(JUnit4TestClassReference.java:25)
at org.eclipse.jdt.internal.junit4.runner.JUnit4TestLoader.createTest(JUnit4TestLoader.java:48)
at org.eclipse.jdt.internal.junit4.runner.JUnit4TestLoader.loadTests(JUnit4TestLoader.java:38)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:444)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:675)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:382)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:192)
You need to use Spring 4.0.x with Camel 2.14.x when using camel-test-spring as it does not support Spring 4.1. Support for Spring 4.1 is coming in Camel 2.15, where there is now 2 spring test modules
camel-test-spring40 - for Spring 4.0.x
camel-test-spring - for Spring 4.1 onwards
This is also documented in the release notes, in important changes to consider seciton
http://camel.apache.org/camel-2140-release.html
I created an OpenShift application (Tomcat 7 (JBoss EWS 2.0)) and with the help of developercorey I was able to deploy my application to OpenShift and connect to the the local MySQL database in OpenShift.
I am now trying to connect to the same database only on my local machine but when I call initialContext.lookup("jdbc/local") it throws an error. It's acting like its unable to find the context.xml file even though when the application is deployed in OpenShift it works correctly.
Exception: javax.naming.NoInitialContextException: Need to specify class name in environment or system property, or as an applet parameter, or in an application resource file: java.naming.factory.initialNeed to specify class name in environment or system property, or as an applet parameter, or in an application resource file: java.naming.factory.initial
Exception: java.lang.NullPointerExceptionnull
I am used to Tomcat and the location for datasources is located in:
WebContent\META-INF\context.xml
But for JBoss the context.xml is located in:
.openshift\config\context.xml
Is there additional mapping I need to do to make the application connect locally?
Thanks in advance!
private static DataSource getDataSource() {
DataSource datasource = null;
try {
InitialContext ic = new InitialContext();
Context initialContext = (Context) ic.lookup("java:comp/env");
datasource = (DataSource) initialContext.lookup("jdbc/local");
} catch (Exception ex) {
System.out.println("Exception: " + ex + ex.getMessage());
} finally {
return datasource;
}
}
<Resource name="jdbc/OpenShift"
url="jdbc:mysql://127.10.198.2:3306/remote"
driverClassName="com.mysql.jdbc.Driver"
username="root"
password="*****"
auth="Container"
type="javax.sql.DataSource"
maxActive="20"
maxIdle="5"
maxWait="10000"
/>
<Resource name="jdbc/local"
url="jdbc:mysql://127.0.0.1:3306/local"
driverClassName="com.mysql.jdbc.Driver"
username="root"
password="******"
auth="Container"
type="javax.sql.DataSource"
maxActive="20"
maxIdle="5"
maxWait="10000"
/>
You are correct. When working on OpenShift, the path you need to update the context.xml file is indeed .openshift\config\context.xml
However, if you're working locally. You need to update the context.xml under the following path - $CATALINA_BASE/conf/context.xml
I am using Servlet 2.4, Hibernate 4.2.4 Final, c3p0 0.9.2.1, Tomcat 7.0.42, MySQL 5.6 & JSP.
I had completed development using Oracle 11gR2 DB but at a later point was asked to switch to MySQL as the Database.
I have a rather unusual problem at hand.
The problem is Multiple MySQL Process/Connections being created for every single DB request, which are neither closed nor returned to the pool despite issuing the SessionFactoryUtil.close(); which was not the case with Oracle DB.
I tested the exact same code on these two different Databases, i.e after executing a Function/Request (ex: Login)
The application when tested with Oracle (11gR2) the DB created a single connection and used it for all requests henceforth.
SELECT * FROM V$RESOURCE_LIMIT
Gives me the following Output
RESOURCE_NAME: processes
CURRENT_UTILIZATION: 32
MAX_UTILIZATION: 36
INITIAL_ALLOCATION: 300
LIMIT_VALUE: 300
No matter how many users log in the Connection pool maintains it gracefully.
Now on the other hand when the same application was run on MySQL:
I did a SHOW PROCESSLIST; on MySQL which shows two processes being created for every request; c3p0 successfully terminates one connection but the other connection remains till the DB crashes because it exceeded the max connections available.
My SessionFactoryUtil is quite simple and straightforward and is as follows:
public class SessionFactoryUtil {
private static SessionFactory sessionFactory;
public static SessionFactory getSessionFactory() {
return sessionFactory = new Configuration().configure()
.buildSessionFactory();//deprecated method not changed due to official reason
}
public Session getCurrentSession() {
return sessionFactory.getCurrentSession();
}
public static void close() {
if (sessionFactory != null) {
sessionFactory.close();
}
sessionFactory = null;
}
My DAO Method is as follows
public User getUserByName(String userName) throws FetchException {
User user = null;
Session session = SessionFactoryUtil.getSessionFactory().getCurrentSession();
try {
session.beginTransaction();
user = (User) session.createQuery("from User where userName = '" + userName + "'").uniqueResult();
} catch (Exception e) {
logger.info("UserDaoImpl -> getUserByName() : Error : " +e);
e.printStackTrace();
} finally {
SessionFactoryUtil.close();
}
return user;
The stack trace where c3p0 destroys a connection is as follows:
20:45:43,692 INFO com.mchange.v2.resourcepool.BasicResourcePool:1493 - A checked-out resource is overdue, and will be destroyed: com.mchange.v2.c3p0.impl.NewPooledConnection#61f31fff
20:45:43,692 INFO com.mchange.v2.resourcepool.BasicResourcePool:1496 - Logging the stack trace by which the overdue resource was checked-out.
java.lang.Exception: DEBUG STACK TRACE: Overdue resource check-out stack trace.
at com.mchange.v2.resourcepool.BasicResourcePool.checkoutResource(BasicResourcePool.java:555)
at com.mchange.v2.c3p0.impl.C3P0PooledConnectionPool.checkoutAndMarkConnectionInUse(C3P0PooledConnectionPool.java:755)
at com.mchange.v2.c3p0.impl.C3P0PooledConnectionPool.checkoutPooledConnection(C3P0PooledConnectionPool.java:682)
at com.mchange.v2.c3p0.impl.AbstractPoolBackedDataSource.getConnection(AbstractPoolBackedDataSource.java:140)
at org.hibernate.service.jdbc.connections.internal.C3P0ConnectionProvider.getConnection(C3P0ConnectionProvider.java:84)
at org.hibernate.internal.AbstractSessionImpl$NonContextualJdbcConnectionAccess.obtainConnection(AbstractSessionImpl.java:292)
at org.hibernate.engine.jdbc.internal.LogicalConnectionImpl.obtainConnection(LogicalConnectionImpl.java:214)
at org.hibernate.engine.jdbc.internal.LogicalConnectionImpl.getConnection(LogicalConnectionImpl.java:157)
at org.hibernate.engine.transaction.internal.jdbc.JdbcTransaction.doBegin(JdbcTransaction.java:67)
at org.hibernate.engine.transaction.spi.AbstractTransactionImpl.begin(AbstractTransactionImpl.java:160)
at org.hibernate.internal.SessionImpl.beginTransaction(SessionImpl.java:1426)
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.hibernate.context.internal.ThreadLocalSessionContext$TransactionProtectionWrapper.invoke(ThreadLocalSessionContext.java:352)
at com.sun.proxy.$Proxy7.beginTransaction(Unknown Source)
at com.demo.access.impl.ConfDaoImp.showAllEvents(ConfDaoImp.java:939)
at com.demo.business.impl.ConfServiceImpl.showAllEvents(ConfServiceImpl.java:404)
at com.demo.controller.UserController.getControls(UserController.java:112)
at com.demo.controller.UserController.validateUser(UserController.java:93)
at com.demo.controller.UserController.process(UserController.java:42)
at com.demo.controller.ApplicationServlet.process(ApplicationServlet.java:75)
at com.demo.controller.ApplicationServlet.doPost(ApplicationServlet.java:53)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:641)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:722)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:304)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
at com.demo.controller.LoginFilter.doFilter(LoginFilter.java:37)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:243)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:224)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:185)
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:472)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:151)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:100)
at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:929)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:118)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:405)
at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:269)
at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:515)
at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:302)
at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
at java.lang.Thread.run(Unknown Source)
I have read almost all the question related to this particular scenario but none seems to work, or the thread was abandoned half way, or I am missing out something; could some one please help me get through with this.
This piece of your code did the trick for me:
public static void close() {
if(sessionFactory instanceof SessionFactoryImpl) {
SessionFactoryImpl sf = (SessionFactoryImpl)sessionFactory;
ConnectionProvider conn = sf.getConnectionProvider();
if(conn instanceof C3P0ConnectionProvider) {
((C3P0ConnectionProvider)conn).close();
}
}
sessionFactory.close(); }
Until then Tomcat had (correctly) complained about memory leaks at each hot deployment. Thanks!
a few ideas:
1) you are never closing the Session you create (implicitly by asking for a "current session"). that's a straightforward reason why you might have an unreturned Connection that eventually times out.
2) you are treating your SessionFactory like a Session, building up then tearing down the whole thing (which includes a Connection pool) just to get and use one Connection. not so good. your SessionFamily should have a long lifecycle, your sessions should be for one-time, short-term use.
Its been a while since I found out the answer to my strange problem and I thought that sharing it would help most.
To start with, A couple of things i did wrong was...
Firstly, I migrated from hibernate 3.6 to 4.2 and on doing so I was still using the deprecated buildSessionFactory() method.
Secondly, I was using SessionFactoryUtil.close() after the end of each query statement in my DAO, which defeats the purpose of using Connection Pooling.
Finally, The strange issue where Oracle seems to close the connection successfully after execution of a statement whereas MySql was unable to close the same still remains a mystery.
This, I suspect happened because I was asking SessionFactoryUtil to close a connection which was originally opened by C3P0ConnectionProvider (which I believe was in-turn causing the connection leaks).
After a lot of research and looking around I re-wrote the SessionFactoryUtil as follows...
public class SessionFactoryUtil {
private static SessionFactory sessionFactory;
private static ServiceRegistry serviceRegistry;
public static SessionFactory getSessionFactory() {
Configuration configuration = new Configuration();
configuration.configure();
serviceRegistry = new ServiceRegistryBuilder().applySettings(configuration.getProperties()).buildServiceRegistry();
sessionFactory = configuration.buildSessionFactory(serviceRegistry);
return sessionFactory;
}
public static Session getCurrentSession() {
if(sessionFactory == null){
getSessionFactory();
}
return sessionFactory.getCurrentSession();
}
public static void close() {
if(sessionFactory instanceof SessionFactoryImpl) {
SessionFactoryImpl sf = (SessionFactoryImpl)sessionFactory;
ConnectionProvider conn = sf.getConnectionProvider();
if(conn instanceof C3P0ConnectionProvider) {
((C3P0ConnectionProvider)conn).close();
}
}
sessionFactory.close();
}
Note that all my connections are opened by C3P0ConnectionProvider so it is only logical to close it using C3P0ConnectionProvider itself.
The following is my hibernate.cfg.xml along with c3p0 settings.
<!-- Database connection settings -->
<property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
<property name="hibernate.connection.url">jdbc:mysql://localhost:3306/application</property>
<property name="hibernate.connection.username">root</property>
<property name="hibernate.connection.password">root</property>
<property name="show_sql">true</property>
<property name="format_sql">false</property>
<!-- SQL dialect -->
<property name="dialect">org.hibernate.dialect.MySQLDialect</property>
<!-- Enable Hibernate's automatic session context management -->
<property name="hibernate.current_session_context_class">thread</property>
<property name="hibernate.connection.release_mode">auto</property>
<!-- Create or update the database schema on startup -->
<property name="hibernate.hbm2ddl.auto">none</property>
<!-- DEPRECATED -->
<!-- <property name="connection.provider_class">org.hibernate.connection.C3P0ConnectionProvider</property> -->
<!-- C3p0 connection pooling configuration -->
<property name="hibernate.connection.provider_class">org.hibernate.service.jdbc.connections.internal.C3P0ConnectionProvider</property>
<property name="c3p0.unreturnedConnectionTimeout">600</property>
<property name="c3p0.debugUnreturnedConnectionStackTraces">false</property>
<!-- configuration pool via c3p0 -->
<property name="c3p0.acquire_increment">1</property>
<property name="c3p0.idle_test_period">600</property>
<property name="c3p0.max_size">75</property>
<property name="c3p0.max_statements">5</property>
<property name="c3p0.min_size">5</property>
<property name="c3p0.timeout">600</property>
<property name="c3p0.checkoutTimeout">6000000</property>
<property name="c3p0.testConnectionOnCheckout">false</property>
<property name="c3p0.testConnectionOnCheckin">true</property>
<!-- Mapping -->
</session-factory>
This is again one of the methods from my DAO Class...
public User getUserByName(String userName) throws FetchException {
User user = null;
Session session = SessionFactoryUtil.getCurrentSession();
try {
session.beginTransaction();
user = (User) session.createQuery("from User where userName = '" + userName + "'").uniqueResult();
session.getTransaction().commit();
} catch (Exception e) {
logger.info("UserDaoImpl -> getUserByName() : Error : " +e);
e.printStackTrace();
} finally {
}
return user;
Note that in my DAO at the finally block i don't have to close my connection any more I let c3p0 handle the connection pool.
And voila...!! The Application runs!!! Had more than 2000 transaction hits on a single day in a span of 2 hours.
I hope this helps noob hibernate users like me.