- Introduction
- Set up test data with a non-embedded database
- Microsoft Access
- Other database
- Run the web application with a non-embedded database
- Run the web application with the embedded test database
- How to configure Mondrian as an XML/A provider
- Miscellaneous
- mondrian.properties configuration
- Cache setup
- Compatibility issues
- Weblogic 6.1 and Xerces
- Xalan and Tomcat
- Log4j and Tomcat
1. Introduction The core of Mondrian is a JAR that acts as "JDBC for OLAP": providing connections and executing SQL against underlying relational databases. This can be run within a surrounding application. Mondrian comes to you as binaries packaged in a number of ways: As a WAR which includes JPivot, an OLAP web application framework, and example data that can be loaded into your database of choice. As a WAR with JPivot and an embedded Derby database, which requires no additional set up apart from deployment to an application server. Both distributions contain the Mondrian source. All necessary JARs for Mondrian are contained in the WAR /WEB-INF/lib directory. Here is how to install a binary release: Install the Java SDK (1.4.2 or later). Download the latest binary release mondrian-version.zip from SourceForge, and unzip it. For the non-embedded distribution, set up the FoodMart dataset, as described in section 2. Set up and start the web application, as described in section 4 or 5. If you are Mondrian developer, there are additional instructions for accessing the Perforce source-control server and building the code in the Developer's Guide. 2. Set up test data in a non-embedded database The 'FoodMart' test dataset is part of the non-embedded binary distribution. It is shipped in two formats: a Microsoft Access database (demo/access/MondrianFoodMart.mdb) and in a SQL script of insert statements (demo/FoodMartCreateData.sql). Under Windows, using the Access database is easier to set up, because all you need to do define an ODBC data source. If you want to test using a non Access database, or if you are not using Windows, you will need to create your own empty database and load it using the MondrianFoodMartLoader utility. 2.1. Microsoft Access If you are using Windows, Microsoft Access is the easiest database to use for the test dataset. You just need to set up an ODBC datasource for the test dataset. The test dataset needs to be accessed by the unit tests if you are testing with just this database, or loading into another database. Under the 'Administrative Tools' menu, click on the 'Data Sources (ODBC)' menu item to open the ODBC Data Source Administrator. Next, create a System DSN called MondrianFoodMart pointing to MONDRIAN_HOME/demo/access/MondrianFoodMart.mdb. (This allows Mondrian to access this data source using the JDBC connect string "jdbc:odbc:MondrianFoodMart". 2.2. Other database If not using Access, use the MondrianFoodMartLoader utility to create a database, and load data from a SQL script. Syntax MondrianFoodMartLoader [-verbose] [-tables] [-data] [-indexes] -jdbcDrivers=<jdbcDrivers> -outputJdbcURL=<jdbcURL> [ [ [-outputJdbcUser=user] [-outputJdbcPassword=password] [-outputJdbcBatchSize=<batch size>] ] | -outputDirectory=<directory name> ] [ [-inputJdbcURL=<jdbcURL> [-inputJdbcUser=user] [-inputJdbcPassword=password] ] | [-inputFile=<file name>] ] Options | Option | Description | -verbose | Verbose mode. | -tables | Create tables in output JDBC, or generate CREATE TABLE statement file in output directory for all FoodMart tables, as appropriate for the output database type. If not given, the tables are assumed to exist, and will be deleted first. | -data | Load data from input (JDBC, insert statement file) to output (JDBC, insert statement file). Any existing data is deleted first. | -indexes | Create indexes in output JDBC, or generate CREATE INDEX statement file in output directory for all FoodMart tables, as appropriate for the output database type. | -jdbcDrivers=<driver list> | Comma-separated list of JDBC drivers needed to connect to the source and target databases. The JAR files containing these drivers must also be in the classpath (the -cpjava command). argument to the | -outputJdbcURL=<jdbcURL> | JDBC URL for target database | -outputJdbcUser=<user> | User name for target database | -outputJdbcPassword=<password> | Password for target database | -outputDirectory=<directory name> | Optional. Directory where DB creation scripts will be placed. Statements are in a format that will work for the database type indicated by outputJdbcURL. | -outputJdbcBatchSize=<batch size> | Size of batch for JDBC INSERT statement output. Defaults to 50. If set to 1, JDBC batches are not used. | -inputJdbcURL=<jdbcURL> | JDBC URL for source database | -inputJdbcUser=<user> | User name for source database | -inputJdbcPassword=<password> | Password for source database | -inputFile=<file name> | Optional. If no input DB parameters are given, assumes data comes from this file of INSERT statements. | The usual source for the MondrianFoodMartLoader utility is a SQL script ([-inputFile=<file name>]). But you have already loaded the data into one JDBC data source (say Microsoft Access), use the -inputJdbcURL and related options to copy data to another JDBC database. The loader uses standard J2SE JDBC, the relevant JDBC driver JARs, and some classes out of Mondrian that do not rely on additional JARs. It has been tested against Oracle, Postgres, MySQL and Microsoft Access. If you the target is a JDBC database, you must create the necessary database or schema first. This is database-specific. You can safely ignore any log4j warnings: log4j:WARN No appenders could be found for logger (mondrian.rolap.RolapUtil). log4j:WARN Please initialize the log4j system properly. Examples On Linux, create a MySQL schema called 'foodmart', and create FoodMart tables from the test dataset in the SQL scripts: $ mysqladmin create foodmart $ java -cp "/mondrian/lib/mondrian.jar:/mondrian/lib/log4j-1.2.9.jar:/mondrian/lib/eigenbase-xom.jar:/mondrian/lib/eigenbase-resgen.jar:/mondrian/lib/eigenbase-properties.jar:/usr/local/mysql/mysql-connector-java-3.0.16-ga-bin.jar" mondrian.test.loader.MondrianFoodMartLoader -verbose -tables -data -indexes -jdbcDrivers=com.mysql.jdbc.Driver -inputFile=/mondrian/demo/FoodMartCreateData.sql -outputJdbcURL="jdbc:mysql://localhost/foodmart?user=root&password=myAdmin" On Windows, create FoodMart tables for PostgreSQL from the test dataset in the Access database: C:\mondrian> java -cp "C:\mondrian\lib\mondrian.jar;C:\mondrian\lib\log4j-1.2.9.jar;C:\mondrian\lib\eigenbase-xom.jar;C:\mondrian\lib\eigenbase-resgen.jar;C:\mondrian\lib\eigenbase-properties.jar;C:\mondrian\lib\postgres-jdbc.jar" mondrian.test.loader.MondrianFoodMartLoader -verbose -tables -data -indexes -jdbcDrivers="org.postgresql.Driver,sun.jdbc.odbc.JdbcOdbcDriver" -inputJdbcURL="jdbc:odbc:MondrianFoodMart" -outputJdbcURL="jdbc:postgresql://localhost/foodmart" -outputJdbcUser=postgres -outputJdbcPassword=password 3. Deploy and run the web application with a non-embedded database From the unzipped binary release, explode lib/mondrian.war to TOMCAT_HOME/webapps/mondrian Open the mondrian.properties file in <path to tomcat>\webapps\mondrian and customize the mondrian.jdbcDrivers properties for the database you set up from the instructions above. Open the web.xml file in <path to tomcat>\webapps\mondrian\WEB-INF and customize the two connect strings there to the same database parameters for the FoodMart database you installed as per the above instructions, ie. Provider=mondrian;Jdbc=jdbc:odbc:MondrianFoodMart;Catalog=/WEB-INF/queries/FoodMart.xml;JdbcDrivers=sun.jdbc.odbc.JdbcOdbcDriver; becomes: Provider=mondrian;Jdbc=jdbc:mysql://localhost/foodmart?user=foodmart&password=foodmart; Catalog=/WEB-INF/queries/FoodMart.xml;JdbcDrivers=com.mysql.jdbc.Driver; Modify the line: <jp:mondrianQuery id="query01" jdbcDriver="sun.jdbc.odbc.JdbcOdbcDriver" jdbcUrl="jdbc:odbc:MondrianFoodMart" catalogUri="/WEB-INF/queries/FoodMart.xml"> to the same database parameters for the FoodMart database you installed as per the above instructions. ie. for MySQL, something like: <jp:mondrianQuery id="query01" jdbcDriver="com.mysql.jdbc.Driver" jdbcUrl="jdbc:mysql://localhost/foodmart?user=foodmart&password=foodmart"; catalogUri="/WEB-INF/queries/FoodMart.xml"> Hit http://localhost:8080/mondrian. 5. Deploy and run the web application with the embedded test database From the unzipped embedded database binary release, explode lib/mondrian-embedded.war to TOMCAT_HOME/webapps/mondrian-embedded Start up Tomcat Hit http://localhost:8080/mondrian-embedded 6. How to configure Mondrian as an XML/A provider To will setup XMLA service, follow the following steps. 1. Describe the data which data sources exist In WEB-INF directory of your webapp, create a file called datasources.xml, with content like this: <?xml version="1.0"?> <DataSources> <DataSource> <DataSourceName>MondrianFoodMart</DataSourceName> <DataSourceDescription>FoodMart 2000 Data Warehouse From MS Analysis Services</DataSourceDescription> <URL>http://localhost:8080/mondrian/xmla</URL> <DataSourceInfo>Provider=mondrian; Jdbc=jdbc:odbc:MondrianFoodMart; JdbcDrivers=sun.jdbc.odbc.JdbcOdbcDriver; Catalog=/WEB-INF/schema/FoodMart.xml</DataSourceInfo> <ProviderName>Mondrian Perforce HEAD</ProviderName> <ProviderType>MDP</ProviderType> <AuthenticationMode>Unauthenticated</AuthenticationMode> </DataSource> <DataSource> <DataSourceName>PostgreSQLTest</DataSourceName> <DataSourceDescription>Test Data Warehouse On PostgreSQL</DataSourceDescription> <URL>http://localhost:8080/mondrian/xmla</URL> <DataSourceInfo>Provider=mondrian; Jdbc=jdbc:postgresql://localhost/olap; Catalog=/WEB-INF/schema/TestPgsql.xml; JdbcDrivers=org.postgresql.Driver; JdbcUser=pgsql; JdbcPassword=pgsql</DataSourceInfo> <ProviderName>Mondrian Perforce HEAD</ProviderName> <ProviderType>MDP</ProviderType> <AuthenticationMode>Unauthenticated</AuthenticationMode> </DataSource> </DataSources> <ProviderType> and <AuthenticationMode> are ignored because the XML/A implementation currently only supports 'MDP' and 'Unauthenticated'. 2. Configure XmlaServlet in your web.xml For example: <servlet> <servlet-name>MondrianXmlaServlet</servlet-name> <servlet-class>mondrian.xmla.XmlaServlet</servlet-class> <init-param> <param-name>DataSourcesConfig</param-name> <param-value>datasources.xml</param-value> </init-param> </servlet> 6. Miscellaneous 6.1. mondrian.properties Mondrian has a properties file to allow you to configure how it executes. The mondrian.properties file is loaded when the executing Mondrian JAR detects it needs properties, but can also be done explicitly in your code. It looks in several places, in the following order: In the directory where you started your JVM If you want property loading to be explicit in the context of a web application, you can call MondrianProperties.instance().load(servletContext). This will search for a mondrian.properties file in /WEB-INF. JPivot does this and the demonstration web applications have this configuration. These properties are stored as system properties, so they can be set during JVM startup via -D<property>=<value>. The following properties in mondrian.properties effect the operations of Mondrian. There are additional properties that are relevant only during development and testing. | Property | Description | Default value | mondrian.query.limit | Maximum number of simultaneous queries the system will allow. Oracle fails if you try to run more than the 'processes' parameter in init.ora, typically 150. The throughput of Oracle and other databases will probably reduce long before you get to their limit. | 40 | mondrian.trace.level | The amount of tracing displayed. If trace level is above 0, SQL tracing will be enabled and logged as per the out.file below. This is separate from Log4j logging. | 0 | mondrian.debug.out.file | The name of the file to which SQL tracing is to be written. | System.out | mondrian.jdbcDrivers | A list of JDBC drivers to load automatically. Must be a comma-separated list of class names, and the classes must be on the class path. | sun.jdbc.odbc.JdbcOdbcDriver, org.hsqldb.jdbcDriver, oracle.jdbc.OracleDriver, com.mysql.jdbc.Driver | mondrian.result.limit | If set to a value greater than zero, limits the maximum size of a result set. | 0 | mondrian.rolap.LargeDimensionThreshold | Determines when a dimension is considered "large". If a dimension has more than this number of members, use a smart member reader. | 100 | mondrian.rolap.SparseSegmentValueThreshold, mondrian.rolap.SparseSegmentDensityThreshold | Determines whether to choose a sparse or dense representation when storing collections of cell values. When storing collections of cell values, we have to choose between a sparse and a dense representation, based upon the possible and actual number of values. The density = actual / possible. We use a sparse representation if: possible - valueThreshold * actual > densityThreshold At the default values, we use a dense representation for (1000 possible, 0 actual), or (2000 possible, 500 actual), or (3000 possible, 1000 actual). Any fewer actual values, or any more possible values, and we will use a sparse representation. | ValueThreshold: 1000 DensityThreshold: 0.5 | mondrian.rolap.aggregates.Use | Boolean property that controls whether aggregates should be used. If true, then aggregates are used. This property is queried prior to each aggregate query so that changing the value of this property dynamically (not just at startup) is meaningful. Aggregates can be read from the database using the ReadAggregates property but will not be used unless this property is set to true. | false | mondrian.rolap.aggregates.Read | Boolean property which determines whether aggregates should be read. If set to true, then the database is scanned for aggregate tables. Unless the mondrian.rolap.aggregates.Use property is set to true, the aggregates found will not be used. | false | mondrian.rolap.aggregates.ChooseByVolume | Boolean property that controls whether aggregate tables are ordered by their volume or row count. | false | mondrian.rolap.aggregates.rules | String property which can be either a resource in the Mondrian jar or a URL. See aggregate table rules for details. | "/DefaultRules.xml", which is in the mondrian.rolap.aggmatcher package in Mondrian.jar | mondrian.rolap.aggregates.rule.tag | The AggRule element's tag value. Normally, this property is not set by a user.
| default | mondrian.rolap.aggregates.generateSql | Boolean property which controls whether to print the SQL code generated for aggregate tables. If set, then as each aggregate request is processed, both the lost and collapsed dimension create and insert sql code is printed. This is for use in the CmdRunner allowing one to create aggregate table generation sql.
| false | mondrian.rolap.star.disableCaching | Boolean property that controls whether a RolapStar's aggregate data cache is cleared after each query. If true, RolapStar will not cache aggregate data from one query to the next (the cache is cleared after each query). | false | mondrian.olap.triggers.enable | Boolean property that controls whether triggers are executed when Mondrian properties change. This allows objects dependent on Mondrian properties to react, ie. reload, when a given property changes via MondrianProperties.instance().populate(null)MondrianProperties.instance().QueryLimit.set(50) or for example. | true | mondrian.rolap.generate.formatted.sql | Boolean property which controls pretty-print mode. If set to true, the all SqlQuery SQL strings will be generated in the log or output in pretty-print mode, formatted for ease of reading. | false | mondrian.olap.case.sensitive | Boolean property which controls whether the MDX parser resolves uses case-sensitive matching when looking up identifiers. | false | mondrian.expCache.enable | Boolean property which controls whether to use a cache for frequently evaluated expressions. With the cache disabled, an expression like: Rank([Product].CurrentMember, Order([Product].MEMBERS, [Measures].[Unit Sales])) would perform many redundant sorts. | true | mondrian.test.ExpDependencies | Integer property which controls whether to test operators' dependencies, and how much time to spend doing it. If this property is positive, Mondrian allocates an expression evaluator which evaluates each expression several times, and makes sure that the results of the expression are independent of dimensions which the expression claims to be independent of. | 0 | mondrian.rolap.localePropFile | Name of locale property file. Used for the LocalizingDynamicSchemaProcessor. See Internationalization. | null | mondrian.native.crossjoin.enable | If enabled, some NON EMPTY CrossJoin MDX statements will be computed in the database and not within Mondrian/Java | true | mondrian.native.topcount.enable | If enabled, some TopCount MDX statements will be computed in the database and not within Mondrian/Java | false | mondrian.native.filter.enable | If enabled, some Filter() MDX statements will be computed in the database and not within Mondrian/Java | false | mondrian.native.nonempty.enable | If enabled, some NON EMPTY MDX set operations like member.children, level.members and member.descendants will be computed in the database and not within Mondrian/Java | true | 6.2. Cache setup You will need to specify the amount of memory available to the cache using the -Xms Java VM option, for example -Xms256m for 256 megs of ram for the Java VM. 7. Compatibility issues 7.1. Weblogic 6.1 and Xerces Weblogic 6.1 ships with an older, incompatible, version of Xerces. The symptom is the error java.lang.VerifyError: (class: org/eigenbase/xom/wrappers/XercesDOMParser, method: parse signature: (Lorg/xml/sax/InputSource;)Lorg/w3c/dom/Document;) Incompatible object argument for function call at java.lang.Class.forName0(Native Method) at java.lang.Class.forName(Class.java:120) at org.eigenbase.xom.XOMUtil.createDefaultParser(XOMUtil.java:165) at org.eigenbase.resgen.Util.load(Util.java:49) ... The solution is to place xml-apis.jar and xercesImpl.jar before weblogic.jar on your class-path. Generally, Mondrian uses whichever JAXP-compliant XML parser is provided by the system. Unfortunately Weblogic's parser cannot be set to non-validating mode, and Mondrian needs this. Therefore, in a Weblogic environment, Mondrian explicitly uses Xerces. Fyi, this note describes how to change Weblogic's default XML parser. 7.2. JDK, Xalan and Tomcat Mondrian binaries, as shipped, require JDK 1.4.x, Xalan 2.6.0, and Tomcat 5.0.25 or later. Things work better that way. If you are running JDK 1.3.x, you will need some extra JAR files, because JDK 1.3 does not include the an XML parser. Copy xalan.jar and xml-apis.jar to TOMCAT_HOME/common/lib. (or TOMCAT_HOME/common/endorsed, if your version of Tomcat has one). If you get the configuration wrong, a typical error is java.lang.VerifyError: Cannot inherit from final class at java.lang.ClassLoader.defineClass0(Native Method) at java.lang.ClassLoader.defineClass(ClassLoader.java:502) at java.security.SecureClassLoader.defineClass(SecureClassLoader.java:123) at org.apache.catalina.loader.WebappClassLoader.findClassInternal(WebappClassLoader.java:1664) at org.apache.catalina.loader.WebappClassLoader.findClass(WebappClassLoader.java:953) at org.apache.catalina.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1394) at org.apache.catalina.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1274) at java.lang.ClassLoader.loadClassInternal(ClassLoader.java:315) at org.apache.xerces.impl.XMLNSDocumentScannerImpl.createContentDispatcher(Unknown Source) at org.apache.xerces.impl.XMLDocumentFragmentScannerImpl.<init>(XMLDocumentFragmentScannerImpl.java:249) at org.apache.xerces.impl.XMLDocumentScannerImpl.<init>(XMLDocumentScannerImpl.java:245) at org.apache.xerces.impl.XMLNSDocumentScannerImpl.<init>(Unknown Source) at org.apache.xerces.parsers.IntegratedParserConfiguration.createDocumentScanner(Unknown Source) at org.apache.xerces.parsers.DTDConfiguration.<init>(DTDConfiguration.java:367) at org.apache.xerces.parsers.StandardParserConfiguration.<init>(StandardParserConfiguration.java:198) at org.apache.xerces.parsers.IntegratedParserConfiguration.<init>(Unknown Source) at org.apache.xerces.parsers.IntegratedParserConfiguration.<init>(Unknown Source) at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method) This error occurred under JDK 1.3.1, Tomcat 4.1.18, Xalan 2.4.1. The solutions to the error were (a) move to JDK 1.4 and remove xml-apis.jar and xercesImpl.jar from mondrian.war, or (b) revert to Xalan 2.3.1. 7.3. Log4j and Tomcat The Mondrian WARs come packaged with a version of log4j.jar. This may conflict with your app server, such as JBoss, and cause errors in the log about log4j appenders. The fix is to remove the log4j.jar from the Mondrian WAR. |