我们在BIRT报表中使用Esproc已经有一段时间了,一切都运行得很好。我们按照this教程进行了操作,结果一切正常。然而,他们的软件的最新版本包含了一些新的功能,因此,我们现在需要升级运行BIRT的版本。问题是,现在,什么都不起作用了。当我们尝试运行报告时,我们不断得到NullPointerException。这就是我们目前所得到的:
The following report will be sent to Eclipse:
------
STATUS
------
pluginId org.eclipse.jface
pluginVersion 3.12.0.v20160518-1929
code 2
severity 4
message Problems occurred when invoking code from plug-in: "org.eclipse.jface".
fingerprint eb22eddc61b2abbaef12193bb7441fab
Exception:java.lang.NullPointerException: null
at com.esproc.jdbc.Server.getDfxList(Unknown Source:88)
at com.esproc.jdbc.InternalConnection.getMetaData(Unknown Source:314)
at org.eclipse.birt.report.data.oda.jdbc.ui.provider.JdbcMetaDataProvider.isSupportSchema(JdbcMetaDataProvider.java:305)
at org.eclipse.birt.report.data.oda.jdbc.ui.editors.SQLDataSetEditorPage.createDBMetaDataSelectionComposite(SQLDataSetEditorPage.java:405)
at org.eclipse.birt.report.data.oda.jdbc.ui.editors.SQLDataSetEditorPage.createPageControl(SQLDataSetEditorPage.java:334)
at org.eclipse.birt.report.data.oda.jdbc.ui.editors.SQLDataSetEditorPage.createPageCustomControl(SQLDataSetEditorPage.java:307)
at org.eclipse.datatools.connectivity.oda.design.ui.wizards.DataSetWizardPage.createControl(DataSetWizardPage.java:123)
at org.eclipse.datatools.connectivity.oda.design.internal.ui.DataSetEditorPageCore.createContents(DataSetEditorPageCore.java:74)
at org.eclipse.jface.preference.PreferencePage.createControl(PreferencePage.java:241)
at org.eclipse.birt.report.designer.data.ui.dataset.PropertyPageWrapper.createPageControl(PropertyPageWrapper.java:61)
at org.eclipse.birt.report.designer.data.ui.property.PropertyNode.createPageControl(PropertyNode.java:238)
at org.eclipse.birt.report.designer.data.ui.property.AbstractPropertyDialog.showPage(AbstractPropertyDialog.java:577)
at org.eclipse.birt.report.designer.data.ui.property.AbstractPropertyDialog.showSelectionPage(AbstractPropertyDialog.java:482)
at org.eclipse.birt.report.designer.data.ui.dataset.DataSetEditor.showSelectionPage(DataSetEditor.java:913)
at org.eclipse.birt.report.designer.data.ui.property.AbstractPropertyDialog$2$1.run(AbstractPropertyDialog.java:438)
at org.eclipse.swt.custom.BusyIndicator.showWhile(BusyIndicator.java:70)
at org.eclipse.birt.report.designer.data.ui.property.AbstractPropertyDialog$2.selectionChanged(AbstractPropertyDialog.java:433)
at org.eclipse.jface.viewers.Viewer$1.run(Viewer.java:158)
at org.eclipse.core.runtime.SafeRunner.run(SafeRunner.java:42)
at org.eclipse.ui.internal.JFaceUtil$1.run(JFaceUtil.java:50)
at org.eclipse.jface.util.SafeRunnable.run(SafeRunnable.java:173)
at org.eclipse.jface.viewers.Viewer.fireSelectionChanged(Viewer.java:155)
at org.eclipse.jface.viewers.StructuredViewer.updateSelection(StructuredViewer.java:2191)
at org.eclipse.jface.viewers.StructuredViewer.setSelection(StructuredViewer.java:1728)
at org.eclipse.jface.viewers.TreeViewer.setSelection(TreeViewer.java:1077)
at org.eclipse.jface.viewers.Viewer.setSelection(Viewer.java:383)
at org.eclipse.birt.report.designer.data.ui.property.AbstractPropertyDialog.initTreeSelection(AbstractPropertyDialog.java:408)
at org.eclipse.birt.report.designer.data.ui.property.AbstractPropertyDialog.createDialogArea(AbstractPropertyDialog.java:299)
at org.eclipse.birt.report.designer.data.ui.dataset.DataSetEditor.createDialogArea(DataSetEditor.java:124)
at org.eclipse.jface.dialogs.Dialog.createContents(Dialog.java:767)
at org.eclipse.birt.report.designer.data.ui.dataset.DataSetEditor.createContents(DataSetEditor.java:602)
at org.eclipse.jface.window.Window.create(Window.java:426)
at org.eclipse.jface.dialogs.Dialog.create(Dialog.java:1095)
at org.eclipse.birt.report.designer.ui.dialogs.BaseDialog.open(BaseDialog.java:107)
at org.eclipse.birt.report.designer.data.ui.actions.EditDataSetAction.doAction(EditDataSetAction.java:105)
at org.eclipse.birt.report.designer.internal.ui.views.actions.AbstractElementAction.run(AbstractElementAction.java:70)
at org.eclipse.jface.action.Action.runWithEvent(Action.java:473)
at org.eclipse.jface.action.ActionContributionItem.handleWidgetSelection(ActionContributionItem.java:565)
at org.eclipse.jface.action.ActionContributionItem.lambda$4(ActionContributionItem.java:397)
at org.eclipse.swt.widgets.EventTable.sendEvent(EventTable.java:84)
at org.eclipse.swt.widgets.Display.sendEvent(Display.java:4410)
at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1079)
at org.eclipse.swt.widgets.Display.runDeferredEvents(Display.java:4228)
at org.eclipse.swt.widgets.Display.readAndDispatch(Display.java:3816)
at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine$4.run(PartRenderingEngine.java:1121)
at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:336)
at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.run(PartRenderingEngine.java:1022)
at org.eclipse.e4.ui.internal.workbench.E4Workbench.createAndRunUI(E4Workbench.java:150)
at org.eclipse.ui.internal.Workbench$5.run(Workbench.java:687)
at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:336)
at org.eclipse.ui.internal.Workbench.createAndRunWorkbench(Workbench.java:604)
at org.eclipse.ui.PlatformUI.createAndRunWorkbench(PlatformUI.java:148)
at org.eclipse.ui.internal.ide.application.IDEApplication.start(IDEApplication.java:138)
at org.eclipse.equinox.internal.app.EclipseAppHandle.run(EclipseAppHandle.java:196)
at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.runApplication(EclipseAppLauncher.java:134)
at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.start(EclipseAppLauncher.java:104)
at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:388)
at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:243)
at sun.reflect.NativeMethodAccessorImpl.invoke0(null:-2)
at sun.reflect.NativeMethodAccessorImpl.invoke(null:-1)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(null:-1)
at java.lang.reflect.Method.invoke(null:-1)
at org.eclipse.equinox.launcher.Main.invokeFramework(Main.java:673)
at org.eclipse.equinox.launcher.Main.basicRun(Main.java:610)
at org.eclipse.equinox.launcher.Main.run(Main.java:1519)
------
REPORT
------
anonymousId 12355fbc-cb0f-41c4-b330-1d4a60fd5df2
name
email
comment
eclipseBuildId 4.6.0.I20160606-1100
eclipseProduct org.eclipse.epp.package.reporting.product
javaRuntimeVersion 1.8.0_71-b15
osgiWs win32
osgiOs Windows10
osgiOsVersion 10.0.0
osgiArch x86_64
severity UNKNOWN
-------
BUNDLES
-------
name org.eclipse.birt.report.data.oda.jdbc.ui
version 4.6.0.v201606072122
name org.eclipse.birt.report.data.oda.jdbc
version 4.6.0.v201606072122
name org.eclipse.birt
version 4.6.0.v201606072122
name org.eclipse.birt.report.designer.ui
version 4.6.0.v201606072122
name org.eclipse.birt.report.designer.ui.views
version 4.6.0.v201606072122
name org.eclipse.core.databinding.observable
version 1.6.0.v20160511-1747
name org.eclipse.core.databinding
version 1.6.0.v20160412-0910
name org.eclipse.core.runtime
version 3.12.0.v20160606-1342
name org.eclipse.datatools.connectivity.oda.design.ui
version 3.3.0.201603142002
name org.eclipse.datatools.connectivity.oda.design
version 3.4.0.201603142002
name org.eclipse.datatools.connectivity.oda
version 3.5.0.201603142002
name org.eclipse.datatools.connectivity
version 1.13.0.201603142002
name org.eclipse.e4.ui.workbench
version 1.4.0.v20160517-1624
name org.eclipse.e4.ui.workbench.swt
version 0.14.0.v20160523-1900
name org.eclipse.equinox.app
version 1.3.400.v20150715-1528
name org.eclipse.equinox.launcher
version 1.3.200.v20160318-1642
name org.eclipse.jface
version 3.12.0.v20160518-1929
name org.eclipse.swt
version 3.105.0.v20160603-0902
name org.eclipse.ui
version 3.108.0.v20160518-1929
name org.eclipse.ui.ide.application
version 1.1.100.v20160518-1929
name org.eclipse.ui.ide
version 3.12.0.v20160601-1609有人知道这是怎么回事吗?
谢谢
发布于 2016-09-19 21:57:07
好的,所以我能够让事情运行起来,而解决方案并不是我所说的微不足道的。实际上,我不得不修改和重新编译三个BIRT类。如果你不想在谷歌上搜索,你可以很容易地得到源代码here。无论如何,我们的第一个修改是由上面引用的错误消息给我们的。我们需要修改位于org.eclipse.birt.report.data.oda.jdbc.ui_4.6.0.v201606072122.jar包中的JdbcMetaDataProvider.java。我们要找的是isSupportSchema()方法。更具体地说,这段代码:
try
{
return connection.getMetaData( ).supportsSchemasInTableDefinitions( );
}
catch ( SQLException e )
{
try
{
reconnect( );
return connection.getMetaData( ).supportsSchemasInTableDefinitions( );
}
catch ( Exception e1 )
{
try
{
ResultSet rs = connection.getMetaData( ).getSchemas( );
if( rs != null )
return true;
else
return false;
}
catch (SQLException e2)
{
logger.log( Level.WARNING, e.getMessage( ), e1 );
return false;
}
}
}由于不能访问Esproc的代码,我不能确切地说出它为什么这样做,但是connection.getMetaData( ).supportsSchemasInTableDefinitions( );抛出了一个NullPointerException。如果没有"catch“块来处理上述异常,Eclipse将停止其执行并阻止您访问dataset。所以我们需要像这样解决这个问题:
try
{
return connection.getMetaData( ).supportsSchemasInTableDefinitions( );
}
catch ( SQLException e )
{
try
{
reconnect( );
return connection.getMetaData( ).supportsSchemasInTableDefinitions( );
}
catch ( Exception e1 )
{
try
{
ResultSet rs = connection.getMetaData( ).getSchemas( );
if( rs != null )
return true;
else
return false;
}
catch (SQLException e2)
{
logger.log( Level.WARNING, e.getMessage( ), e1 );
return false;
}
}
}
catch (NullPointerException e)
{
return false;
}现在,我们需要修改的下两位代码位于oda-jdbc.jar包中。我们要查找的第一个类是Connection.java类,更具体地说是populateConnectionProp( )方法。
private void populateConnectionProp( ) throws SQLException
{
if( jdbcConn!= null )
{
if( this.autoCommit != null )
jdbcConn.setAutoCommit( this.autoCommit );
else
{
if (DBConfig.getInstance().qualifyPolicy(
jdbcConn.getMetaData().getDriverName(),
DBConfig.SET_COMMIT_TO_FALSE) ) {
this.autoCommit = false;
jdbcConn.setAutoCommit( false );
}
}
if( this.isolationMode!= Constants.TRANSCATION_ISOLATION_DEFAULT)
jdbcConn.setTransactionIsolation( this.isolationMode );
}
}这一次抛出NullPointerException的罪魁祸首是下面这行jdbcConn.getMetaData().getDriverName()。同样,无法访问Esproc的代码,我真的不知道为什么尝试恢复驱动程序的名称不起作用,但不管怎样,我们需要做的实际上是捕获异常,事情就会恢复正常:
private void populateConnectionProp( ) throws SQLException
{
if( jdbcConn!= null )
{
if( this.autoCommit != null )
jdbcConn.setAutoCommit( this.autoCommit );
else
{
try
{
if (DBConfig.getInstance().qualifyPolicy(
jdbcConn.getMetaData().getDriverName(),
DBConfig.SET_COMMIT_TO_FALSE) ) {
this.autoCommit = false;
jdbcConn.setAutoCommit( false );
}
}
catch(NullPointerException e)
{
this.autoCommit = false;
jdbcConn.setAutoCommit( false );
}
}
if( this.isolationMode!= Constants.TRANSCATION_ISOLATION_DEFAULT)
jdbcConn.setTransactionIsolation( this.isolationMode );
}
}我们要寻找的另一个类是CallStatement.java类。在其中,我们必须找到我粘贴到下面的getCallableParamMetaData()方法:
private java.util.List getCallableParamMetaData( )
{
java.util.List paramMetaDataList = new ArrayList( );
try
{
DatabaseMetaData metaData = conn.getMetaData( );
String cataLog = conn.getCatalog( );
String procedureNamePattern = getNamePattern( this.paramUtil.getProcedure( ) );
String schemaPattern = null;
if ( this.paramUtil.getSchema( ) != null )
{
schemaPattern = getNamePattern( this.paramUtil.getSchema( ) );
}
// handles schema.package.storedprocedure for databases such as
// Oracle
if ( !metaData.supportsCatalogsInProcedureCalls( ) )
{
if (this.paramUtil.getPackage( ) != null)
{
cataLog = getNamePattern( this.paramUtil.getPackage( ) );
}
}
java.sql.ResultSet rs = null;
rs = metaData.getProcedureColumns( cataLog,
schemaPattern,
procedureNamePattern,
null );
while ( rs.next( ) )
{
ParameterDefn p = new ParameterDefn( );
p.setParamName( rs.getString( "COLUMN_NAME" ) );
p.setParamInOutType( rs.getInt( "COLUMN_TYPE" ) );
p.setParamType( rs.getInt( "DATA_TYPE" ) );
p.setParamTypeName( rs.getString( "TYPE_NAME" ) );
p.setPrecision( rs.getInt( "PRECISION" ) );
p.setScale( rs.getInt( "SCALE" ) );
p.setIsNullable( rs.getInt( "NULLABLE" ) );
if ( p.getParamType( ) == Types.OTHER )
correctParamType( p );
paramMetaDataList.add( p );
}
rs.close( );
}
catch ( SQLException e )
{
logger.log( Level.SEVERE, "Fail to get SP paramters", e );
}
catch( JDBCException ex)
{
logger.log( Level.SEVERE, "Fail to get SP paramters", ex );
}
return paramMetaDataList;
}基本上,抛出NullPointerException的罪魁祸首就在while ( rs.next( ) )循环的某个地方。因此,我们需要做的就是添加一个catch语句,按照如下方式处理它:
private java.util.List getCallableParamMetaData( )
{
java.util.List paramMetaDataList = new ArrayList( );
try
{
DatabaseMetaData metaData = conn.getMetaData( );
String cataLog = conn.getCatalog( );
String procedureNamePattern = getNamePattern( this.paramUtil.getProcedure( ) );
String schemaPattern = null;
if ( this.paramUtil.getSchema( ) != null )
{
schemaPattern = getNamePattern( this.paramUtil.getSchema( ) );
}
// handles schema.package.storedprocedure for databases such as
// Oracle
if ( !metaData.supportsCatalogsInProcedureCalls( ) )
{
if (this.paramUtil.getPackage( ) != null)
{
cataLog = getNamePattern( this.paramUtil.getPackage( ) );
}
}
java.sql.ResultSet rs = null;
rs = metaData.getProcedureColumns( cataLog,
schemaPattern,
procedureNamePattern,
null );
while ( rs.next( ) )
{
ParameterDefn p = new ParameterDefn( );
p.setParamName( rs.getString( "COLUMN_NAME" ) );
p.setParamInOutType( rs.getInt( "COLUMN_TYPE" ) );
p.setParamType( rs.getInt( "DATA_TYPE" ) );
p.setParamTypeName( rs.getString( "TYPE_NAME" ) );
p.setPrecision( rs.getInt( "PRECISION" ) );
p.setScale( rs.getInt( "SCALE" ) );
p.setIsNullable( rs.getInt( "NULLABLE" ) );
if ( p.getParamType( ) == Types.OTHER )
correctParamType( p );
paramMetaDataList.add( p );
}
rs.close( );
}
catch ( SQLException e )
{
logger.log( Level.SEVERE, "Fail to get SP paramters", e );
}
catch( JDBCException ex)
{
logger.log( Level.SEVERE, "Fail to get SP paramters", ex );
}
catch( NullPointerException ex1)
{
logger.log( Level.SEVERE, "Fail to get SP paramters", ex1 );
}
return paramMetaDataList;
}一旦对文件进行了修改,您实际上需要重新编译源代码。要成功做到这一点,您需要从Eclipse的plugin文件夹中复制几个jars到您试图编译的文件所在的文件夹中。下面的命令中给出了jars,您需要输入该命令来编译源代码。以下是编译每个文件所需输入的内容:
JdbcMetaDataProvider.java
javac -cp ".;
c:/mypath/org.eclipse.birt.report.data.bidi.utils_4.6.0.v201606072122.jar;
c:/mypath/org.eclipse.birt.report.data.oda.jdbc.ui_4.6.0.v201606072122.jar;
c:/mypath/oda-jdbc.jar;
c:/mypath/org.eclipse.datatools.connectivity.oda_3.5.0.201603142002.jar;
c:/mypath/org.eclipse.datatools.connectivity.oda.design_3.4.0.201603142002.jar;
c:/mypath/org.eclipse.datatools.connectivity.oda.design.ui_3.3.0.201603142002.jar;
c:/mypath/org.eclipse.emf.ecore_2.12.0.v20160420-0247.jar;
c:/mypath/org.eclipse.emf.common_2.12.0.v20160420-0247.jar" JdbcMetaDataProvider.java > log.txt 2>&1Connection.java
javac -cp ".;
c:/mypath/org.eclipse.birt.report.data.bidi.utils_4.6.0.v201606072122.jar;
c:/mypath/oda-jdbc.jar;
c:/mypath/org.eclipse.datatools.connectivity.oda_3.5.0.201603142002.jar;
c:/mypath/com.ibm.icu_56.1.0.v201601250100.jar" Connection.java > log.txt 2>&1CallStatement.java
javac -cp ".;
c:/mypath/oda-jdbc.jar;
c:/mypath/org.eclipse.datatools.connectivity.oda_3.5.0.201603142002.jar;
c:/mypath/com.ibm.icu_56.1.0.v201601250100.jar" CallStatement.java > log.txt 2>&1现在,关于上面的两个命令,有几件事需要说明:
1)它们实际上需要一行输入。为了清楚起见,我只是像这样将它们分解,以便每个需要的jar都很容易被发现。
2)这实际上是一个windows命令。如果在Linux上运行该命令,则需要用冒号(:)而不是分号(;)分隔每个jar。
编译成功后,您将得到以下.class文件:
JdbcMetaDataProvider$1TempThread.class
JdbcMetaDataProvider$2TempThread.class
JdbcMetaDataProvider.class
Connection$Constants.class
Connection.class
CallStatement.class需要将这些文件复制回原始jar文件中,以便替换已有的文件。幸运的是,jar文件只不过是一个zip文件,所以在windows中,任何解压软件都可以很容易地为您打开它,并允许您导航到适当的文件夹。
下面是每个jar的相关文件夹:
org\eclipse\birt\report\data\oda\jdbc\ui\provider\
org\eclipse\birt\report\data\oda\jdbc\
org\eclipse\birt\report\data\oda\jdbc\完成后,重新启动Eclipse,一切都应该正常工作。我希望这对将来的某个人有所帮助。
https://stackoverflow.com/questions/39514789
复制相似问题