Skip to content

Commit

Permalink
fixed deadlock bug in Xmla Driver, added unit test to verify fix. Als…
Browse files Browse the repository at this point in the history
…o added generated java files and testclasses directory to svn:ignore.

git-svn-id: https://olap4j.svn.sourceforge.net/svnroot/olap4j/trunk@102 c6a108a4-781c-0410-a6c6-c2d559e19af0
  • Loading branch information
Will Gorman committed Jul 25, 2008
1 parent e1280ce commit bc26a47
Show file tree
Hide file tree
Showing 4 changed files with 88 additions and 13 deletions.
5 changes: 3 additions & 2 deletions src/org/olap4j/driver/xmla/XmlaOlap4jCellSet.java
Original file line number Diff line number Diff line change
Expand Up @@ -362,8 +362,9 @@ private XmlaOlap4jCellSetMetaData createMetaData(Element root)
final Element cubeNameNode =
findChild(cubeNode, MDDATASET_NS, "CubeName");
final String cubeName = gatherText(cubeNameNode);
final XmlaOlap4jCube cube =
this.olap4jStatement.olap4jConnection.olap4jSchema.cubes.get(
final XmlaOlap4jCube cube =
(XmlaOlap4jCube)
this.olap4jStatement.olap4jConnection.getSchema().getCubes().get(
cubeName);
if (cube == null) {
throw olap4jStatement.olap4jConnection.helper.createException(
Expand Down
29 changes: 18 additions & 11 deletions src/org/olap4j/driver/xmla/XmlaOlap4jConnection.java
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ abstract class XmlaOlap4jConnection implements OlapConnection {
/**
* <p>Current schema.
*/
final XmlaOlap4jSchema olap4jSchema;
private XmlaOlap4jSchema olap4jSchema;

private final XmlaOlap4jDatabaseMetaData olap4jDatabaseMetaData;

Expand Down Expand Up @@ -113,6 +113,10 @@ abstract class XmlaOlap4jConnection implements OlapConnection {
* uses the traditional JDBC {@link java.sql.DriverManager}.
* See {@link org.olap4j.driver.xmla.XmlaOlap4jDriver} for more details.
*
* <p>Note that this constructor should make zero non-trivial calls, which
* could cause deadlocks due to java.sql.DriverManager synchronization
* issues.
*
* @pre acceptsURL(url)
*
* @param factory Factory
Expand Down Expand Up @@ -175,12 +179,6 @@ abstract class XmlaOlap4jConnection implements OlapConnection {

this.olap4jDatabaseMetaData =
factory.newDatabaseMetaData(this);
final XmlaOlap4jCatalog catalog =
(XmlaOlap4jCatalog)
this.olap4jDatabaseMetaData.getCatalogObjects().get(
catalogName);
this.olap4jSchema = (XmlaOlap4jSchema) catalog.getSchemas()
.get(0);
}


Expand Down Expand Up @@ -513,7 +511,16 @@ public MdxValidator createMdxValidator(OlapConnection connection) {
};
}

public org.olap4j.metadata.Schema getSchema() throws OlapException {
public synchronized org.olap4j.metadata.Schema getSchema() throws OlapException {
// initializes the olap4jSchema if necessary
if (this.olap4jSchema == null) {
final XmlaOlap4jCatalog catalog =
(XmlaOlap4jCatalog)
this.olap4jDatabaseMetaData.getCatalogObjects().get(
catalogName);
this.olap4jSchema = (XmlaOlap4jSchema) catalog.getSchemas()
.get(0);
}
return olap4jSchema;
}

Expand Down Expand Up @@ -1142,7 +1149,7 @@ public void handle(Element row, Context context, List<XmlaOlap4jNamedSet> list)
}

static class SchemaHandler extends HandlerImpl<XmlaOlap4jSchema> {
public void handle(Element row, Context context, List<XmlaOlap4jSchema> list) {
public void handle(Element row, Context context, List<XmlaOlap4jSchema> list) throws OlapException {
/*
<row>
<CATALOG_NAME>LOCALDB</CATLAOG_NAME>
Expand All @@ -1169,7 +1176,7 @@ public CatalogSchemaHandler(String catalogName) {
this.catalogName = catalogName;
}

public void handle(Element row, Context context, List<XmlaOlap4jSchema> list)
public void handle(Element row, Context context, List<XmlaOlap4jSchema> list) throws OlapException
{
/*
<row>
Expand Down Expand Up @@ -1407,7 +1414,7 @@ public XmlaOlap4jLevel getLevel(Element row) {
return getCube(row).levelsByUname.get(levelUniqueName);
}

public XmlaOlap4jCatalog getCatalog(Element row) {
public XmlaOlap4jCatalog getCatalog(Element row) throws OlapException {
if (olap4jCatalog != null) {
return olap4jCatalog;
}
Expand Down
4 changes: 4 additions & 0 deletions src/org/olap4j/driver/xmla/XmlaOlap4jDatabaseMetaData.java
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,10 @@ abstract class XmlaOlap4jDatabaseMetaData implements OlapDatabaseMetaData {
/**
* Creates an XmlaOlap4jDatabaseMetaData.
*
* <p>Note that this constructor should make zero non-trivial calls, which
* could cause deadlocks due to java.sql.DriverManager synchronization
* issues.
*
* @param olap4jConnection Connection
*/
XmlaOlap4jDatabaseMetaData(
Expand Down
63 changes: 63 additions & 0 deletions testsrc/org/olap4j/XmlaConnectionTest.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
package org.olap4j;

import java.io.IOException;
import java.net.URL;
import java.sql.DriverManager;
import java.util.Properties;
import java.util.concurrent.Future;

import org.olap4j.driver.xmla.XmlaOlap4jDriver;
import org.olap4j.driver.xmla.proxy.XmlaOlap4jProxy;

import junit.framework.TestCase;

public class XmlaConnectionTest extends TestCase {

public static final String DRIVER_CLASS_NAME =
"org.olap4j.driver.xmla.XmlaOlap4jDriver";

static class XmlaOlap4jProxyMock implements XmlaOlap4jProxy {

public byte[] get(URL url, String request) throws IOException {
throw new RuntimeException("Non-Trivial Call!");
}

public String getEncodingCharsetName() {
return "UTF-8";
}

public Future<byte[]> submit(URL url, String request) {
throw new RuntimeException("Non-Trivial Call!");
}

}

/**
* this test verifies that the construction of the necessary
* xmla objects during DriverManager.getConnection() do not make
* calls that could cause deadlocks.
*/
public void testNoNonTrivalCallsOnConnect() throws Exception {
String cookie = XmlaOlap4jDriver.nextCookie();
try {

XmlaOlap4jDriver.PROXY_MAP.put(cookie, new XmlaOlap4jProxyMock());

try {
Class.forName(DRIVER_CLASS_NAME);
} catch (ClassNotFoundException e) {
throw new RuntimeException("oops", e);
}
Properties info = new Properties();
info.setProperty(
XmlaOlap4jDriver.Property.Catalog.name(), "FoodMart");
DriverManager.getConnection(
"jdbc:xmla:Server=http://foo;Catalog=FoodMart;TestProxyCookie=" + cookie,
info);
} catch (Throwable t) {
t.printStackTrace();
fail("Non-Trival Call executed during construction of XmlaOlap4j Connection");
}

}
}

0 comments on commit bc26a47

Please sign in to comment.