Erro ao pegar DataSource no Tomcat

24 respostas
G

Bom dia pessoal, mais um problema que não estou conseguindo resolver sozinho.

Preciso trocar o modo de conexão de minha página para que a mesma fique mais rápida, estou fazendo no braço no momento e quero passas para que o Tomcat gerencie isto para mim. Porém quando peço para procurar o contexto ele me retorna o contexto certo, mas os dados não são obtidos.
segue abaixo o server.xml

.
.
.
<Resource
      name="TesteConexao"
      type="javax.sql.DataSource"
      maxActive="4"
      maxIdle="2"
      username="root"
      maxWait="5000"
      driverClassName="com.mysql.jdbc.Driver"
      password="root"
      url="jdbc:mysql://localhost:3306/bd?autoReconnect=true"/>
.
.
.

Abaixo meu web.xml:

<?xml version="1.0" encoding="ISO-8859-1"?>
<web-app xmlns="http://java.sun.com/xml/ns/j2ee" version="2.4">
	<taglib>
		<taglib-uri>http://java.sun.com/jsp/jstl/core</taglib-uri>
		<taglib-location>/WEB-INF/tld/c.tld</taglib-location>
	</taglib>
	<resource-ref>  
    	<description>DB Connection</description>  
      	<res-ref-name>TesteConexao</res-ref-name>  
      	<res-type>javax.sql.DataSource</res-type>  
      	<res-auth>Container</res-auth>  
   	</resource-ref>
    <servlet>
        <servlet-name>insereFormAction</servlet-name>
        <servlet-class>controller.servlets.insereFormAction</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>insereFormAction</servlet-name>
        <url-pattern>/insereFormAction</url-pattern>
    </servlet-mapping>
    <servlet>
        <servlet-name>removerAction</servlet-name>
        <servlet-class>controller.servlets.removerAction</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>removerAction</servlet-name>
        <url-pattern>/removerAction</url-pattern>
    </servlet-mapping>
    <servlet>
        <servlet-name>atualizaFormAction</servlet-name>
        <servlet-class>controller.servlets.atualizaFormAction</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>atualizaFormAction</servlet-name>
        <url-pattern>/atualizaFormAction</url-pattern>
    </servlet-mapping>
</web-app>

e a classe que pega o contexto e a conexão

package br.com.adelino.bd;
import java.sql.Connection;
import java.sql.SQLException;
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;
import javax.sql.DataSource;

public class ConnectionFactory
{	
	public static Connection getConnection () throws SQLException
	{
		Connection con = null;
		try 
		{  
			InitialContext initContext = new InitialContext();  
			Context envContext  = (Context)initContext.lookup("java:/comp/env");
			DataSource ds = (DataSource)envContext.lookup("TesteConexao");
			con = ds.getConnection();  
		}
		catch (NamingException ne)
		{  
			throw new SQLException(ne.getMessage());
		}
		catch (SQLException se)
		{  
			throw se;  
		}  

		return con;
	}
}

erro gerado no tomcat

javax.servlet.ServletException: Cannot create JDBC driver of class '' for connect URL 'null'
	org.apache.jasper.runtime.PageContextImpl.doHandlePageException(PageContextImpl.java:843)
	org.apache.jasper.runtime.PageContextImpl.handlePageException(PageContextImpl.java:776)
	org.apache.jsp.listar_jsp._jspService(listar_jsp.java:170)
	org.apache.jasper.runtime.HttpJspBase.service(HttpJspBase.java:97)
	javax.servlet.http.HttpServlet.service(HttpServlet.java:802)
	org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:334)
	org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:314)
	org.apache.jasper.servlet.JspServlet.service(JspServlet.java:264)
	javax.servlet.http.HttpServlet.service(HttpServlet.java:802)

Agradeço desde já a atenção.

24 Respostas

A


.
.
.

Esse resource está entre as tags no server.xml?

G

Olá andersondamasio, antes de mais nada muito obrigado por tentar ajudar.

o trecho esta entre as tags no server.xml sim. Teria algo mais a ser feito?

Obrigado

F

gilsonpolito:
Olá andersondamasio, antes de mais nada muito obrigado por tentar ajudar.

o trecho esta entre as tags no server.xml sim. Teria algo mais a ser feito?

Obrigado

Se for Tomcat 5 ou superior, tente assim:

<Context docBase="path_da_sua_aplicacao" path="/ocontextodasuaplicacao" reloadable="true">
      	<Resource auth="Container" ........./>
      </Context>
G

olá felipeguerra,

Obrigado pela ajuda, mas gostaria de saber onde devo colocar esta instrução. no server.xml? em qual parte dele?

Obrigado

F

gilsonpolito:
olá felipeguerra,

Obrigado pela ajuda, mas gostaria de saber onde devo colocar esta instrução. no server.xml? em qual parte dele?

Obrigado


No server.xml, dentro da tag <host>.

S

felipeguerra:
gilsonpolito:
olá felipeguerra,

Obrigado pela ajuda, mas gostaria de saber onde devo colocar esta instrução. no server.xml? em qual parte dele?

Obrigado


No server.xml, dentro da tag <host>.

O melhor, na minha opinião, é colocar dentro também da tag context… exemplo:

<Host...> <Context path="/sistema" reloadable="true" docBase="D:/Sistema" workDir="D:/Sistema/work"> <Resource name="jdbc/sistema" type="javax.sql.DataSource" maxActive="100" maxIdle="30" maxWait="10000" username="root" password="root" driverClassName="com.mysql.jdbc.Driver" url="jdbc:mysql://localhost:3306/bd_sistema?autoReconnect=true"/> </Context> </Host>

G

Olá pessoal,

Consegui fazer funcionar, mas acredito que não seja a melhor maneira. Precisei alterar o arquivo context.xml e o server.xml.

os arquivos ficaram assim:

server.xml:

<?xml version="1.0" encoding="UTF-8"?>
<Server>
  <Listener className="org.apache.catalina.core.AprLifecycleListener"/>
  <Listener className="org.apache.catalina.mbeans.GlobalResourcesLifecycleListener"/>
  <Listener className="org.apache.catalina.storeconfig.StoreConfigLifecycleListener"/>
  <Listener className="org.apache.catalina.mbeans.ServerLifecycleListener"/>
  <GlobalNamingResources>
    <Environment
      name="simpleValue"
      type="java.lang.Integer"
      value="30"/>
    <Resource
      name="TesteConexao"
      type="javax.sql.DataSource"
      auth="Container"
      maxActive="4"
      maxIdle="2"
      username="root"
      maxWait="5000"
      driverClassName="com.mysql.jdbc.Driver"
      password="root"
      url="jdbc:mysql://localhost:3306/monografia?autoReconnect=true"/>
    <Resource
      auth="Container"
      description="User database that can be updated and saved"
      name="UserDatabase"
      type="org.apache.catalina.UserDatabase"
      factory="org.apache.catalina.users.MemoryUserDatabaseFactory"
      pathname="conf/tomcat-users.xml"/>
  </GlobalNamingResources>
  <Service
      name="Catalina">
    <Connector
        port="9090"
        redirectPort="8443"
        minSpareThreads="25"
        connectionTimeout="20000"
        maxThreads="150"
        maxSpareThreads="75">
    </Connector>
    <Connector
        port="8009"
        redirectPort="8443"
        connectionTimeout="-1"
        protocol="AJP/1.3">
    </Connector>
    <Engine
        defaultHost="localhost"
        name="Catalina">
      <Realm className="org.apache.catalina.realm.UserDatabaseRealm"/>
      <Host
          appBase="webapps"
          name="localhost">
        <Context
            path="/testejsp">
        </Context>
      </Host>
    </Engine>
  </Service>
</Server>

context.xml:

<!-- The contents of this file will be loaded for each web application -->
<Context>

    <!-- Default set of monitored resources -->
    <WatchedResource>WEB-INF/web.xml</WatchedResource>
	
    <!-- Uncomment this to disable session persistence across Tomcat restarts -->
    <!--
    <Manager pathname="" />
    -->
	

<Resource
      name="TesteConexao"
      type="javax.sql.DataSource"
      auth="Container"
      maxActive="4"
      maxIdle="2"
      username="root"
      maxWait="5000"
      driverClassName="com.mysql.jdbc.Driver"
      password="root"
      url="jdbc:mysql://localhost:3306/monografia?autoReconnect=true"/>

</Context>

Está certo isto? ou existe uma forma mais elegante e que melhore o desenpenho?

Obrigado

G

detalhe… o trecho gerado dentro do arquivo server.xml foi criado a partir do administrador (ferramenta) do tomcat.

Obrigado

F

context.xml?

Qual Tomcat vc está usando?

G

a versão do tomcat é 5.5.20

G

Esta versão é necessário mesmo fazer o que fiz? ou possui uma outra maneira?

Obrigado

S

gilsonpolito:
Esta versão é necessário mesmo fazer o que fiz? ou possui uma outra maneira?

Obrigado

Na verdade você fez apenas uma redundância de conexões, pois tanto no server.xml, quanto no context.xml, estão setando o mesmo nome “TesteConexao”.

Você tentou efetuar o procedimento que sugerir anteriormente, sentanto a conexão dentro do seu conext?

<Host...> <Context path="/testejsp"> <Resource name="TesteConexao" type="javax.sql.DataSource" auth="Container" maxActive="4" maxIdle="2" username="root" maxWait="5000" driverClassName="com.mysql.jdbc.Driver" password="root" url="jdbc:mysql://localhost:3306/monografia?autoReconnect=true"/> </Context> </Host>

G

Olá sergio,

Eu tentei sim, mas continuou com o mesmo problema…vou tentar mudar para esta forma novamente.

Outra coisa, convém migrar a aplicação para o tomcat 6 ??

Obrigado pela ajuda!

F

Tenho CERTEZA que as libs do driver jdbc não estão no diretório common/lib do Tomcat!

S

gilsonpolito:
Olá sergio,

Eu tentei sim, mas continuou com o mesmo problema…vou tentar mudar para esta forma novamente.

Outra coisa, convém migrar a aplicação para o tomcat 6 ??

Obrigado pela ajuda!

Quando você alterou o server.xml para o exemplo que sugeri, qual foi o erro apresentado??

G

olá sérgio,

O que acontece é que os dados de url, usuário, senha por exemplo voltam todos nulos…

F

Vc viu a minha resposta anterior?

L

Para configurar o JNDI, vc apenas tem que modificar o arquivo META-INF/context.xml (ou acrestar se não existir, no NetBeans já vem esse arquivo) e colocar a informação do JNDI nesse arquivo. Não é necessário acrescentar nada no Tomcat. Estou usando o Tomcat 6. Não sei se funciona se usar o JBoss, mas acho que deve funcionar pois li isso em algum lugar, se alguém testar posta uma mensagem aqui.

Abaixo o código com dois JNDI, um para acessar o Oracle e outro para acessar o MySQL.
:shock: Demorei um tempão para fazer isso funcionar… até descobrir isso … :twisted: … :stuck_out_tongue:

&lt;?xml version="1.0" encoding="UTF-8"?&gt;
&lt;Context path="/WebModelo"&gt;
      &lt;Resource
      name="jdbc/SadegeDB"
      type="javax.sql.DataSource"
      maxActive="4"
      maxIdle="2"
      maxWait="5000"
      username="sadege"
      password="sadege"
      driverClassName="oracle.jdbc.driver.OracleDriver"
      url="jdbc:oracle:thin:@server:1521:oracle"
      auth="Container"
      /&gt;
      &lt;Resource
      name="jdbc/LivrariaDB"
      type="javax.sql.DataSource"
      maxActive="4"
      maxIdle="2"
      maxWait="5000"
      username="maximiza"
      password="maximiza"
      driverClassName="com.mysql.jdbc.Driver"
      url="jdbc:mysql://server:3306/livraria"
      auth="Container"
      /&gt;  
&lt;/Context&gt;


L

Opss…
Além do que coloquei acima, tem que colocar no WEB-INF/web.xml o código para chamar o JNDI:

&lt;resource-ref&gt;
        &lt;description&gt;Conexão Banco de Dados&lt;/description&gt; 
        &lt;res-ref-name&gt;jdbc/LivrariaDB&lt;/res-ref-name&gt;
        &lt;res-type&gt;javax.sql.DataSource&lt;/res-type&gt;
        &lt;res-auth&gt;Container&lt;/res-auth&gt;
    &lt;/resource-ref&gt;
L

Oopa! Será q ainda consigo ajuda nesse item??!

Olha só, eu fiz exatamente a configuração como o amigo sugeriu:

META-INF/context.xml

<?xml version="1.0" encoding="UTF-8"?>  
<Context path="/Gaivota">  
      <Resource name="jdbc/MySqlLuciano"  
		      type="javax.sql.DataSource"  
		      maxActive="4"  
		      maxIdle="2"  
		      maxWait="5000"  
		      username="root"  
		      password="xxxx"  
		      driverClassName="com.mysql.jdbc.Driver"  
		      url="jdbc:mysql://localhost:3306/lucianosilva"  
		      auth="Container"/>    
</Context>

no web.xml

<resource-ref> 
	<description>DB Connection</description> 
	<res-ref-name>jdbc/MySqlLuciano</res-ref-name> 
	<res-type>javax.sql.DataSource</res-type> 
	<res-auth>Container</res-auth> 
 </resource-ref>

Testei usando EL e funcionou perfeitamente, mas quando crio uma classe para devolver a conexão dá a seguinte exception:

javax.naming.NameNotFoundException: Name jdbc is not bound in this Context
	at org.apache.naming.NamingContext.lookup(NamingContext.java:770)
	at org.apache.naming.NamingContext.lookup(NamingContext.java:153)
	at org.apache.naming.SelectorContext.lookup(SelectorContext.java:137)
	at javax.naming.InitialContext.lookup(InitialContext.java:351)
	at gaivota.util.ConnManager.getConn(ConnManager.java:41)
	at gaivota.bean.Editora.findEditora(Editora.java:65)
	at gaivota.bean.Editora.getListaEditora(Editora.java:50)
	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:585)
	at javax.el.BeanELResolver.getValue(BeanELResolver.java:62)
	at javax.el.CompositeELResolver.getValue(CompositeELResolver.java:53)
	at com.sun.faces.el.FacesCompositeELResolver.getValue(FacesCompositeELResolver.java:72)
	at org.apache.el.parser.AstValue.getValue(AstValue.java:114)
	at org.apache.el.ValueExpressionImpl.getValue(ValueExpressionImpl.java:186)
	at org.apache.jasper.el.JspValueExpression.getValue(JspValueExpression.java:101)
	at javax.faces.component.UIData.getValue(UIData.java:608)
	at javax.faces.component.UIData.getDataModel(UIData.java:1112)
	at javax.faces.component.UIData.getRowCount(UIData.java:343)
	at org.apache.myfaces.shared_impl.renderkit.html.HtmlTableRendererBase.encodeInnerHtml(HtmlTableRendererBase.java:235)
	at org.apache.myfaces.shared_impl.renderkit.html.HtmlTableRendererBase.encodeChildren(HtmlTableRendererBase.java:137)
	at javax.faces.component.UIComponentBase.encodeChildren(UIComponentBase.java:832)
	at javax.faces.component.UIComponent.encodeAll(UIComponent.java:936)
	at javax.faces.component.UIComponent.encodeAll(UIComponent.java:942)
	at javax.faces.component.UIComponent.encodeAll(UIComponent.java:942)
	at org.apache.myfaces.application.jsp.JspViewHandlerImpl.actuallyRenderView(JspViewHandlerImpl.java:424)
	at org.apache.myfaces.application.jsp.JspViewHandlerImpl.renderView(JspViewHandlerImpl.java:380)
	at com.sun.faces.lifecycle.RenderResponsePhase.execute(RenderResponsePhase.java:109)
	at com.sun.faces.lifecycle.Phase.doPhase(Phase.java:100)
	at com.sun.faces.lifecycle.LifecycleImpl.render(LifecycleImpl.java:139)
	at javax.faces.webapp.FacesServlet.service(FacesServlet.java:266)
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:290)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
	at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:233)
	at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:175)
	at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:128)
	at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102)
	at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109)
	at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:286)
	at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:844)
	at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:583)
	at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:447)
	at java.lang.Thread.run(Thread.java:595)

A classe é a seguinte (bem-simples):

public class ConnManager{
	private static final String DATASOURCE_CONTEXT	= "jdbc/";
	private String dataSource 						= null;

	/**
	 * 
	 * @param dataSourceName
	 */
	public ConnManager(String dataSourceName){
		this.dataSource = dataSourceName;
	}

	public ConnManager(){
	}

	public Connection getConn(){
		Connection cn		= null;
		DataSource ds		= null;
		InitialContext ic 	= null;

		try{
			ic = new InitialContext();
			
			if( ic == null || dataSource == null ){
				System.out.println("Erro ao iniciar contexto.");
			}else{
				ds = (DataSource) ic.lookup(DATASOURCE_CONTEXT + dataSource);
				cn = ds.getConnection();
			}

		}catch(NamingException e){
			e.printStackTrace();
		}catch(SQLException e){
			e.printStackTrace();
		}finally{
			return cn;
		}
	}	
}

Alguém pode me ajudar com esse problema por favor?!!

Valeu!

L

Bem pessoal, acabei resolvendo o problema na classe de conexão, assim:

public Connection getConn(){
		Connection cn		= null;
		DataSource ds		= null;
		InitialContext ic 	= null;
		Context cxt			= null;

		try{
			ic = new InitialContext();
			
			if( ic == null || dataSource == null ){
				System.out.println("Erro ao iniciar contexto.");
			}else{
				cxt = (Context) ic.lookup("java:/comp/env");
				ds  = (DataSource) cxt.lookup(DATASOURCE_CONTEXT + dataSource);
				cn  = ds.getConnection();
			}

		}catch(NamingException e){
			e.printStackTrace();
		}catch(SQLException e){
			e.printStackTrace();
		}finally{
			return cn;
		}
	}

Valeu!

K

Olá pessoal!
Peço um pouco de paciência ao insistir nesse tópico, mas, o “gilsonpolito” conseguiu resolver o problema da conexão ficar com os valores nulos? É porque estou com o mesmo problema e ainda não consegui resolver…

Lembrando a exceção:

org.apache.jasper.JasperException: Unable to get connection, DataSource invalid: "org.apache.tomcat.dbcp.dbcp.SQLNestedException: Cannot create JDBC driver of class '' for connect URL 'null'"

Já tentei utilizar um código do mesmo jeito que o “lusilva1982” (pág. 2) postou e, ainda, continua a exceção acima.

Por gentileza, alguém pode dar uma ajuda?
Valeu.

Kallás.

A

tenta colocar o jar de conexao dentro da lib do tomCat

K

Olá Anderson!
já fiz isso e, ainda assim, me retorna o erro que comentei.

Como informação extra:

  • Já coloquei o jar de conexão no common/lib e, também, em WEB-INF/lib (e em todas as variações possíveis);
  • Fiz o exemplo mostrado no site do tomcat e, colocando o direto no server.xml, dá certo, porém, ao colocar a configuração de contexto no META-INF/context.xml, sempre obtenho a exceção indicada.

De qualquer forma, obrigado pela atenção!
Kallás.

Criado 17 de dezembro de 2007
Ultima resposta 29 de jun. de 2008
Respostas 24
Participantes 7