Skip to Content
0
Former Member
Oct 17, 2012 at 11:59 AM

java.lang.UnsupportedOperationException - at sun.jdbc.odbc.JdbcOdbcDatabaseMetaData.getUDTs(JdbcOdbcDatabaseMetaData.java:3612) at com.crystaldecisions.reports.queryengine.driverImpl.jdbc.JDBCConnection.GetTables(Unknown Source)

111 Views

Hi,

I am using Crystal Report Viewer which has key components built on CR JAVA Runtime v. 12.2.214, JDK 1.7, Tomcat 7, Windows XP 32bit. All my reports using JNDI-JDBC work fine, but when I use Report created using ODBC connection, I am getting below error while changing Database Connection. Can you please suggest me how to rectify this problem. This is a very critical report for my business and I need to run this report only using ODBC since I am not provided with direct JDBC connection parameters. Please suggest a way.

----------------------------------- ERROR in LOG file -----------------------------------------------------------------------------------------------------------------------------------------------------------

2012-10-17 13:15:34,641 ERROR http-apr-8888-exec-8 com.businessobjects.reports.sdk.JRCCommunicationAdapter - detected an exception: java.lang.UnsupportedOperationException

at sun.jdbc.odbc.JdbcOdbcDatabaseMetaData.getUDTs(JdbcOdbcDatabaseMetaData.java:3612)

at com.crystaldecisions.reports.queryengine.driverImpl.jdbc.JDBCConnection.GetTables(Unknown Source)

at com.crystaldecisions.reports.queryengine.JDBConnectionWrapper.GetTables(SourceFile:112)

at com.crystaldecisions.reports.queryengine.Connection.be(SourceFile:1062)

at com.crystaldecisions.reports.queryengine.Table.bv(SourceFile:2310)

at com.crystaldecisions.reports.queryengine.Table.a(SourceFile:595)

at com.crystaldecisions.reports.queryengine.Table.vb(SourceFile:2419)

at com.crystaldecisions.reports.dataengine.datafoundation.AddDatabaseTableCommand.new(SourceFile:529)

at com.crystaldecisions.reports.common.CommandManager.a(SourceFile:71)

at com.crystaldecisions.reports.common.Document.a(SourceFile:203)

at com.businessobjects.reports.sdk.requesthandler.f.a(SourceFile:175)

at com.businessobjects.reports.sdk.requesthandler.DatabaseRequestHandler.byte(SourceFile:1079)

at com.businessobjects.reports.sdk.JRCCommunicationAdapter.do(SourceFile:1166)

at com.businessobjects.reports.sdk.JRCCommunicationAdapter.if(SourceFile:660)

at com.businessobjects.reports.sdk.JRCCommunicationAdapter.a(SourceFile:166)

at com.businessobjects.reports.sdk.JRCCommunicationAdapter$2.a(SourceFile:528)

at com.businessobjects.reports.sdk.JRCCommunicationAdapter$2.call(SourceFile:526)

at com.crystaldecisions.reports.common.ThreadGuard.syncExecute(SourceFile:102)

at com.businessobjects.reports.sdk.JRCCommunicationAdapter.for(SourceFile:524)

at com.businessobjects.reports.sdk.JRCCommunicationAdapter.int(SourceFile:423)

at com.businessobjects.reports.sdk.JRCCommunicationAdapter.request(SourceFile:351)

at com.businessobjects.sdk.erom.jrc.a.a(SourceFile:54)

at com.businessobjects.sdk.erom.jrc.a.execute(SourceFile:67)

at com.crystaldecisions.proxy.remoteagent.RemoteAgent$a.execute(SourceFile:716)

at com.crystaldecisions.proxy.remoteagent.CommunicationChannel.a(SourceFile:125)

at com.crystaldecisions.proxy.remoteagent.RemoteAgent.a(SourceFile:537)

at com.crystaldecisions.sdk.occa.report.application.ds.a(SourceFile:186)

at com.crystaldecisions.sdk.occa.report.application.an.a(SourceFile:108)

at com.crystaldecisions.sdk.occa.report.application.b0.if(SourceFile:148)

at com.crystaldecisions.sdk.occa.report.application.b0.b(SourceFile:95)

at com.crystaldecisions.sdk.occa.report.application.bb.int(SourceFile:96)

at com.crystaldecisions.proxy.remoteagent.UndoUnitBase.performDo(SourceFile:151)

at com.crystaldecisions.proxy.remoteagent.UndoUnitBase.a(SourceFile:106)

at com.crystaldecisions.sdk.occa.report.application.DatabaseController.a(SourceFile:2159)

at com.crystaldecisions.sdk.occa.report.application.DatabaseController.a(SourceFile:543)

at com.crystaldecisions.sdk.occa.report.application.DatabaseController.a(SourceFile:3898)

at com.crystaldecisions.sdk.occa.report.application.DatabaseController.setTableLocation(SourceFile:2906)

at crystalreport.CRJavaHelper.changeDataSource(CRJavaHelper.java:247)

at org.apache.jsp.RNDviewreport_jsp._jspService(RNDviewreport_jsp.java:120)

at org.apache.jasper.runtime.HttpJspBase.service(HttpJspBase.java:70)

at javax.servlet.http.HttpServlet.service(HttpServlet.java:722)

at org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:432)

at org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:390)

at org.apache.jasper.servlet.JspServlet.service(JspServlet.java:334)

at javax.servlet.http.HttpServlet.service(HttpServlet.java:722)

at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:305)

at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)

at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:222)

at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:123)

at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:472)

at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:168)

at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:99)

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:407)

at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1002)

at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:585)

at org.apache.tomcat.util.net.AprEndpoint$SocketProcessor.run(AprEndpoint.java:1813)

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)

---------------------------------------- This is my Java code to change Database connection ------------------------------------------------------------------------------------------------------

public void changeDataSource(ReportClientDocument clientDoc,
String reportName, String tableName,
String username, String password, String connectionURL,
String driverName,String jndiName) throws ReportSDKException {

PropertyBag propertyBag = null;
IConnectionInfo connectionInfo = null;
ITable origTable = null;
ITable newTable = null;

// Declare variables to hold ConnectionInfo values.
// Below is the list of values required to switch to use a JDBC/JNDI
// connection

String TRUSTED_CONNECTION = "false";
String SERVER_TYPE = "JDBC (JNDI)";
//String SERVER_TYPE = "ODBC (RDO)";
String USE_JDBC = "true";
//String USE_JDBC = "false";
String DATABASE_DLL = "crdb_jdbc.dll";
//String DATABASE_DLL = "crdb_odbc.dll";
String JNDI_DATASOURCE_NAME = jndiName;
String CONNECTION_URL = connectionURL;
String DATABASE_CLASS_NAME = driverName;

// The next few parameters are optional parameters which you may want to
// uncomment
// You may wish to adjust the arguments of the method to pass these
// values in if necessary
// String TABLE_NAME_QUALIFIER = "new_table_name";
// String SERVER_NAME = "new_server_name";
// String CONNECTION_STRING = "new_connection_string";
// String DATABASE_NAME = "new_database_name";
// String URI = "new_URI";

// Declare variables to hold database User Name and Password values
String DB_USER_NAME = username;
String DB_PASSWORD = password;

// Obtain collection of tables from this database controller
if (reportName == null || reportName.equals("")) {
Tables tables = clientDoc.getDatabaseController().getDatabase().getTables();
for(int i = 0;i < tables.size();i++){
origTable = tables.getTable(i);
if (tableName == null || origTable.getName().equals(tableName)) {

newTable = (ITable)origTable.clone(true);
newTable.setName(origTable.getName());
newTable.setQualifiedName(origTable.getQualifiedName());
newTable.setAlias(origTable.getAlias());

//Changing Something

// We set the Fully qualified name to the Table Alias to keep the
// method generic
// This workflow may not work in all scenarios and should likely be
// customized to work
// in the developer's specific situation. The end result of this
// statement will be to strip
// the existing table of it's db specific identifiers. For example
// Xtreme.dbo.Customer becomes just Customer
//newTable.setQualifiedName(origTable.getAlias());

// Change properties that are different from the original datasource
// For example, if the table name has changed you will be required
// to change it during this routine

//table.setQualifiedName(TABLE_NAME_QUALIFIER);

// Change connection information properties
connectionInfo = newTable.getConnectionInfo();

// Set new table connection property attributes
propertyBag = new PropertyBag();

// Overwrite any existing properties with updated values
propertyBag.put("Trusted_Connection", TRUSTED_CONNECTION);
propertyBag.put("Server Type", SERVER_TYPE);
propertyBag.put("Use JDBC", USE_JDBC);
propertyBag.put("Database DLL",DATABASE_DLL );
propertyBag.put("JNDI Datasource Name",JNDI_DATASOURCE_NAME );
propertyBag.put("Connection URL", CONNECTION_URL);
propertyBag.put("Database Class Name", DATABASE_CLASS_NAME);

/*
propertyBag.remove("Server Name"); //Optional property
propertyBag.remove("Server");
propertyBag.remove("PreQEServerName");
propertyBag.remove("DSN");
propertyBag.remove("UseDSNProperties");
*/

// propertyBag.put("Connection String", CONNECTION_STRING); //Optional property
// propertyBag.put("Database Name", DATABASE_NAME); //Optional property
// propertyBag.put("URI", URI); //Optional property
connectionInfo.setAttributes(propertyBag);

// Set database username and password
// NOTE: Even if the username and password properties do not change
// when switching databases, the
// database password is *not* saved in the report and must be set at
// runtime if the database is secured.
connectionInfo.setUserName(DB_USER_NAME);
connectionInfo.setPassword(DB_PASSWORD);

// Update the table information
clientDoc.getDatabaseController().setTableLocation(origTable, newTable);
}
}
}

// Next loop through all the subreports and pass in the same
// information. You may consider
// creating a separate method which accepts
if (reportName == null || !(reportName.equals(""))) {
IStrings subNames = clientDoc.getSubreportController().getSubreportNames();
for (int subNum=0;subNum<subNames.size();subNum++) {
Tables tables = clientDoc.getSubreportController().getSubreport(subNames.getString(subNum)).getDatabaseController().getDatabase().getTables();
for(int i = 0;i < tables.size();i++){
origTable = tables.getTable(i);
if (tableName == null || origTable.getName().equals(tableName)) {
newTable = (ITable)origTable.clone(true);
newTable.setName(origTable.getName());
newTable.setQualifiedName(origTable.getQualifiedName());
newTable.setAlias(origTable.getAlias());

// We set the Fully qualified name to the Table Alias to keep
// the method generic
// This workflow may not work in all scenarios and should likely
// be customized to work
// in the developer's specific situation. The end result of this
// statement will be to strip
// the existing table of it's db specific identifiers. For
// example Xtreme.dbo.Customer becomes just Customer
newTable.setQualifiedName(origTable.getAlias());

// Change properties that are different from the original
// datasource
// table.setQualifiedName(TABLE_NAME_QUALIFIER);

// Change connection information properties
connectionInfo = newTable.getConnectionInfo();

// Set new table connection property attributes
propertyBag = new PropertyBag();

// Overwrite any existing properties with updated values
propertyBag.put("Trusted_Connection", TRUSTED_CONNECTION);
propertyBag.put("Server Type", SERVER_TYPE);
propertyBag.put("Use JDBC", USE_JDBC);
propertyBag.put("Database DLL",DATABASE_DLL );
propertyBag.put("JNDI Datasource Name",JNDI_DATASOURCE_NAME );
propertyBag.put("Connection URL", CONNECTION_URL);
propertyBag.put("Database Class Name", DATABASE_CLASS_NAME);

/*
propertyBag.remove("Server Name"); //Optional property
propertyBag.remove("Server");
propertyBag.remove("PreQEServerName");
propertyBag.remove("DSN");
propertyBag.remove("UseDSNProperties");
*/

// propertyBag.put("Server Name", SERVER_NAME); //Optional property
// propertyBag.put("Connection String", CONNECTION_STRING); //Optional property
// propertyBag.put("Database Name", DATABASE_NAME); //Optional property
// propertyBag.put("URI", URI); //Optional property
connectionInfo.setAttributes(propertyBag);

// Set database username and password
// NOTE: Even if the username and password properties do not
// change when switching databases, the
// database password is *not* saved in the report and must be
// set at runtime if the database is secured.
connectionInfo.setUserName(DB_USER_NAME);
connectionInfo.setPassword(DB_PASSWORD);

// Update the table information
clientDoc.getSubreportController().getSubreport(subNames.getString(subNum)).getDatabaseController().setTableLocation(origTable, newTable);
}
}
}
}

}

Calling this function as below ---

objCRJavaHelper.changeDataSource(reportClientDoc, null, null, null, null, "jdbc:odbc:AR System DB", "sun.jdbc.odbc.JdbcOdbcDriver", null);

Regards,

Murtaza Ghodawala,

murtaza_ghoda82@hotmail.com

Mobile: +965 97180549