如果你碰到了这样的问题:
1.birt通过JNDI配置数据源失败;
2.看到了这样的错误:
org.jboss.util.NestedSQLException: Unable to get managed connection for jdbc/...;
或者
javax.resource.ResourceException: Unable to get managed connection for jdbc/...
3.或者下面这个很诡异的问题:
这个问题是我在实际的开发中碰到的。具体是这样的:
在Jboss上面部署了一个web工程。有一个jsp页面需要将页面表单中的数据提交给报表,然后将查询数据后的报表展示在页面上。
在报表的数据源配置中,我采用的JNDI的方式。具体的数据源配置是这样的:
当我在Jboss启动这个系统后,第一次去点击上面提到的页面中的按钮去加载报表并显示,结果报birt相关的错误。但是重新再次点击后,就能成功加载报表并显示了。
查看birt-ReportEngine日志。发现第一次点击的时候的确有这样的错误信息: getJndiDSConnection: Unable to get JNDI data source connection; org.jboss.util.NestedSQLException: Unable to get managed connection for jdbc/ybi; - nested throwable: (javax.resource.ResourceException: Unable to get managed connection for jdbc/ybi)。之后不管你点击多少次,查看多少次报表,都不会再出现这样的错误信息了。
如果你碰到了上面这样的信息,下面的你就值得关注下。
出现这样的原因,我没有找到,但是可以提供一种很容易的处理方法:
通过查看birt日志,结合birt的源码,一步步去定位问题。发现打印的报JNDI连接数据源报错日志发生在org.eclipse.birt.report.data.oda.jdbc.JDBCDriverManger里面的getJbdiSconnection方法里面。下面是我工程里面的birt.jar包里面这个方法的详码:
private Connection getJndiDSConnection(String driverClass, String jndiNameUrl, Properties connectionProperties)
{
if ((jndiNameUrl == null) || (jndiNameUrl.length() == 0)) {
return null;
}
if (logger.isLoggable(Level.FINER)) {
logger.finer("Calling getJndiDSConnection: JNDI name URL=" + jndiNameUrl);
}
IConnectionFactory factory = new JndiDataSource();
Connection jndiDSConnection = null;
try
{
logger.finer("driverClass=" + driverClass + "\njndiNameUrl=" + jndiNameUrl +
"\nconnectionProperties=" + connectionProperties);
jndiDSConnection = factory.getConnection(driverClass, jndiNameUrl,
connectionProperties);
logger.finer("jndiDSConnection=" + jndiDSConnection);
}
catch (SQLException e)
{
if (logger.isLoggable(Level.FINE)) {
logger.info("getJndiDSConnection: Unable to get JNDI data source connection; " + e.toString());
return jndiDSConnection;
}
既然第一次在工程里面打开birt通过JNDI连接时,会进入这个catch里面,以后就不会发生了。最直接的方法就是直接在这个catch里面在尝试连接一次不就可以了?
所以,在catch里面增加如下连接JNDI数据源代码即可:
try
{
logger.finer("driverClass=" + driverClass + "\njndiNameUrl=" + jndiNameUrl +
"\nconnectionProperties=" + connectionProperties);
jndiDSConnection = factory.getConnection(driverClass, jndiNameUrl,
connectionProperties);
logger.finer("jndiDSConnection=" + jndiDSConnection);
}
catch (SQLException ex)
{
if (logger.isLoggable(Level.FINE)) {
logger.info("getJndiDSConnection: Unable to get JNDI data source connection; " + ex.toString());
}
}
还是那句话,不知道为什么会第一次连不上, 希望看到的高手能帮助解释下。万分感谢。
都说birt连接数据源首先会去查找JNDI,如果JNDI没有配置,才去JDBC里面查找。但是当我尝试在birt数据源里面JDBC配置时(Database URL等填上值),在工程里面打开birt会报JDBC连接失败的错。原因暂时没时间去找了。总之,如果你碰到了上面的情况,就这么处理吧,并且切记JDBC不要配置。然后如果还不行的话,就在web.xml里面把birt的日志等级设置为“ALL"。