cancel
Showing results for 
Search instead for 
Did you mean: 

Migration from Crystal XI (RDC) to Crystal Reports 2013 (Java API)

Former Member
0 Kudos

We are in the process of getting current on the Crystal Reports and, since COM support is no longer available, want to migrate to the Java API.

The processing of reports is, at a high-level, as follows:

- open a report on disk

- pass in values for the parameters

- set the DB connection (this is dynamically defined but always pointing to a SQL server)

- export the report on disk

Given these, I put together the following code based on the sample published here

The problem I'm running into right now is that the report seems to be unable to connect to the database (the one saved with the template; didn't even get to re-set it at runtime)

// Open report.

            ReportClientDocument reportClientDocument = new ReportClientDocument();

            /*

             * Instantiate ReportClientDocument and specify the Java Print Engine as the report processor. Open a rpt

             * file.

             */

            ParameterFieldController parameterFieldController;

            // Calendar calendar;

            // ParameterFieldRangeValue parameterFieldRangeValue;

            // ParameterFieldRangeValue[] parameterFieldRangeValues;

            reportClientDocument.setReportAppServer(ReportClientDocument.inprocConnectionString);

            reportClientDocument.open(REPORT_NAME, OpenReportOptions._openAsReadOnly);

            /*

             * Set report parameter field values.

             */

            parameterFieldController = reportClientDocument.getDataDefController().getParameterFieldController();

            parameterFieldController.setCurrentValue("", "@ptxReportName", "All");

            parameterFieldController.setCurrentValue("", "@HSF_SESSION_USEROID", "6");

            parameterFieldController.setCurrentValue("", "@pchReportUsage", "2");

            // NOTE: If parameters or database login credentials are required, they need to be set before.

            // calling the export() method of the PrintOutputController.

            // Export report and obtain an input stream that can be written to disk.

            // See the Java Reporting Component Developer's Guide for more information on the supported export format

            // enumerations

            // possible with the JRC.

            ByteArrayInputStream byteArrayInputStream = (ByteArrayInputStream) reportClientDocument

                    .getPrintOutputController().export(ReportExportFormat.PDF);

            // Release report.

            reportClientDocument.close();

            // Use the Java I/O libraries to write the exported content to the file system.

            byte byteArray[] = new byte[byteArrayInputStream.available()];

            // Create a new file that will contain the exported result.

            File file = new File(EXPORT_FILE);

            FileOutputStream fileOutputStream = new FileOutputStream(file);

            ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream(byteArrayInputStream.available());

            int x = byteArrayInputStream.read(byteArray, 0, byteArrayInputStream.available());

            byteArrayOutputStream.write(byteArray, 0, x);

            byteArrayOutputStream.writeTo(fileOutputStream);

            // Close streams.

            byteArrayInputStream.close();

            byteArrayOutputStream.close();

            fileOutputStream.close();

            System.out.println("Successfully exported report to " + EXPORT_FILE);

        } catch (ReportSDKException ex) {

            ex.printStackTrace();

        } catch (Exception ex) {

            ex.printStackTrace();

        }

The exception thrown by export is:

13782 [main] ERROR com.businessobjects.reports.sdk.JRCCommunicationAdapter  -  detected an exception: Error finding JNDI name (usmlvv1srn811)

  at com.crystaldecisions.reports.queryengine.Connection.t4(SourceFile:3024)

  at com.crystaldecisions.reports.dataengine.dfadapter.DFAdapter.a(SourceFile:697)

  at com.crystaldecisions.reports.dataengine.dfadapter.DFAdapter.for(SourceFile:707)

  at com.crystaldecisions.reports.reportdefinition.ReportHelper.a(SourceFile:198)

  at com.businessobjects.reports.sdk.requesthandler.ReportViewingRequestHandler.long(SourceFile:958)

  at com.businessobjects.reports.sdk.requesthandler.ReportViewingRequestHandler.a(SourceFile:636)

  at com.businessobjects.reports.sdk.requesthandler.ReportViewingRequestHandler.int(SourceFile:673)

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

  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.ReportSource.a(SourceFile:1558)

  at com.crystaldecisions.sdk.occa.report.application.ReportSource.a(SourceFile:337)

  at com.crystaldecisions.sdk.occa.report.application.PrintOutputController.if(SourceFile:223)

  at com.crystaldecisions.sdk.occa.report.application.PrintOutputController.export(SourceFile:147)

  at com.crystaldecisions.sdk.occa.report.application.PrintOutputController.export(SourceFile:128)

  at com.crystaldecisions.sdk.occa.report.application.PrintOutputController.export(SourceFile:111)

  at com.siemens.soarian.sc.oms.business.inet.GenerateReportASImplTest.countExecs(GenerateReportASImplTest.java:129)

  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 org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:47)

  at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)

  at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:44)

  at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)

  at org.springframework.test.context.junit4.statements.RunBeforeTestMethodCallbacks.evaluate(RunBeforeTestMethodCallbacks.java:74)

  at org.springframework.test.context.junit4.statements.RunAfterTestMethodCallbacks.evaluate(RunAfterTestMethodCallbacks.java:83)

  at org.springframework.test.context.junit4.statements.SpringRepeat.evaluate(SpringRepeat.java:72)

  at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:231)

  at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:88)

  at org.junit.runners.ParentRunner$3.run(ParentRunner.java:238)

  at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:63)

  at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:236)

  at org.junit.runners.ParentRunner.access$000(ParentRunner.java:53)

  at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:229)

  at org.springframework.test.context.junit4.statements.RunBeforeTestClassCallbacks.evaluate(RunBeforeTestClassCallbacks.java:61)

  at org.springframework.test.context.junit4.statements.RunAfterTestClassCallbacks.evaluate(RunAfterTestClassCallbacks.java:71)

  at org.junit.runners.ParentRunner.run(ParentRunner.java:309)

  at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:174)

  at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:86)

  at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)

  at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:459)

  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)

Any suggestions?

Many thanks!

Accepted Solutions (0)

Answers (1)

Answers (1)

Former Member
0 Kudos

After further research, I came to lean that JRC will not be able to connect to the database saved in the template since that is using OLE DB (while JRC can connect only using JDBC/JNDI). Thus my code changed to:

                         [...]

            parameterFieldController.setCurrentValue("", "@ptxReportName", "All");

            parameterFieldController.setCurrentValue("", "@HSF_SESSION_USEROID", "6");

            parameterFieldController.setCurrentValue("", "@pchReportUsage", "2");

            switch_tables(reportClientDocument.getDatabaseController());

            // Perform the same operation against all tables in the subreport as well.

            IStrings subreportNames = reportClientDocument.getSubreportController().getSubreportNames();

            // Set the datasource for all the subreports.

            for (int i = 0; i < subreportNames.size(); i++) {

                ISubreportClientDocument subreportClientDoc =

                        reportClientDocument.getSubreportController().getSubreport(subreportNames.getString(i));

                // Switch tables for each subreport in the report using the same connection information. See utility

                // method below.

                switch_tables(subreportClientDoc.getDatabaseController());

            }

          [export code]


   private static void switch_tables(DatabaseController databaseController) throws ReportSDKException {

        // Declare the new connection properties that report's datasource will be switched to.

        // NOTE: These are specific to using JDBC against a particular MS SQL Server database. Be sure to use the

        // DisplayConnectionInfo sample to determine what your own connection properties need to be set to.

        final String TABLE_NAME_QUALIFIER = "dbo.";

        final String DBUSERNAME = "<userid>";

        final String DBPASSWORD = "<password>";

        final String SERVERNAME = "<servername>";

        final String DATABASE_NAME = "<database name>";

        final String CONNECTION_STRING = "Use JDBC=b(true);Connection URL=s(jdbc:microsoft:sqlserver://" + SERVERNAME

                + ");" + "Database Class Name=s(com.microsoft.sqlserver.jdbc.SQLServerDriver);Server=s(" + SERVERNAME

                + ");User ID=s(" + DBUSERNAME + ");Password=;Database=s(" + DATABASE_NAME + ");"

                + "Trusted_Connection=b(false);"

                + "JDBC Connection String=s(!com.microsoft.sqlserver.jdbc.SQLServerDriver!jdbc:microsoft:sqlserver://"

                + SERVERNAME + ";" + "DatabaseName={database};user={userid};password={password}!)";

        final String URI = "!com.microsoft.sqlserver.jdbc.SQLServerDriver!jdbc:microsoft:sqlserver://" + SERVERNAME

                + ";DatabaseName={database};user={userid};password={password}!";

        final String DATABASE_DLL = "crdb_jdbc.dll";

        // Obtain collection of tables from this database controller.

        Tables tables = databaseController.getDatabase().getTables();

        // Set the datasource for all main report tables.

        for (int i = 0; i < tables.size(); i++) {

            ITable table = tables.getTable(i);

            // Keep existing name and alias.

            table.setName(table.getName());

            table.setAlias(table.getAlias());

            // Change properties that are different from the original datasource.

            table.setQualifiedName(TABLE_NAME_QUALIFIER + table.getName());

            // Change connection information properties.

            IConnectionInfo connectionInfo = table.getConnectionInfo();

            // Set new table connection property attributes.

            PropertyBag propertyBag = new PropertyBag();

            // Overwrite any existing properties with updated values.

            propertyBag.put("Trusted_Connection", "false");

            // propertyBag.put("Server Name", SERVERNAME); // Optional property.

            propertyBag.put("Connection String", CONNECTION_STRING);

            propertyBag.put("Database Name", DATABASE_NAME);

            propertyBag.put("Server Type", "JDBC (JNDI)");

            propertyBag.put("URI", URI);

            propertyBag.put("Use JDBC", "true");

            propertyBag.put("Database DLL", DATABASE_DLL);

            connectionInfo.setAttributes(propertyBag);

            // Set database username and password.

            // NOTE: Even if these the username and password properties don't 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("");

            // connectionInfo.setPassword("");

            connectionInfo.setUserName(DBUSERNAME);

            connectionInfo.setPassword(DBPASSWORD);

            connectionInfo.setKind(ConnectionInfoKind.SQL);

            table.setConnectionInfo(connectionInfo);

            // Update old table in the report with the new table.

            databaseController.setTableLocation(table, tables.getTable(i));

        }

    }


And databaseController.setTableLocation() is throwing the following exception...

17335 [main] ERROR com.businessobjects.reports.sdk.JRCCommunicationAdapter  -  detected an exception: Unexpected database connector error

  at com.crystaldecisions.reports.queryengine.Connection.t4(SourceFile:3024)

  at com.crystaldecisions.reports.queryengine.Table.vc(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 com.siemens.soarian.sc.oms.business.inet.GenerateReportASImplTest.switch_tables(GenerateReportASImplTest.java:239)

  at com.siemens.soarian.sc.oms.business.inet.GenerateReportASImplTest.countExecs(GenerateReportASImplTest.java:113)

  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 org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:47)

  at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)

  at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:44)

  at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)

  at org.springframework.test.context.junit4.statements.RunBeforeTestMethodCallbacks.evaluate(RunBeforeTestMethodCallbacks.java:74)

  at org.springframework.test.context.junit4.statements.RunAfterTestMethodCallbacks.evaluate(RunAfterTestMethodCallbacks.java:83)

  at org.springframework.test.context.junit4.statements.SpringRepeat.evaluate(SpringRepeat.java:72)

  at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:231)

  at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:88)

  at org.junit.runners.ParentRunner$3.run(ParentRunner.java:238)

  at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:63)

  at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:236)

  at org.junit.runners.ParentRunner.access$000(ParentRunner.java:53)

  at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:229)

  at org.springframework.test.context.junit4.statements.RunBeforeTestClassCallbacks.evaluate(RunBeforeTestClassCallbacks.java:61)

  at org.springframework.test.context.junit4.statements.RunAfterTestClassCallbacks.evaluate(RunAfterTestClassCallbacks.java:71)

  at org.junit.runners.ParentRunner.run(ParentRunner.java:309)

  at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:174)

  at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:86)

  at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)

  at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:459)

  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)

Thanks!