Saiku链接地址
官网:https://community.meteorite.bi/
GitHub:https://github.com/OSBI/saiku
文档:https://saiku-documentation.readthedocs.io/en/latest/#open-source
本文中所使用的saiku版本为 3.x 版本
安装教程
一 使用git下载项目
git clone git://github.com/OSBI/saiku.git
【如果下载速度太感人,可以查看 git clone下载速度慢解决办法 】
二 修改maven依赖【重】
saiku自带的maven仓库下载地址可能会出现各种问题,比如503等
以下是我修改后的maven仓库地址【方便起见只贴了修改的地方】
- saiku/pom.xml
<distributionManagement>
<!--
<repository>
<id>utility</id>
<name>utility-releases</name>
<url>http://repo.meteorite.bi/repository/alabs-release-local/</url>
</repository>
<snapshotRepository>
<id>utility</id>
<name>utility-snapshots</name>
<url>http://repo.meteorite.bi/repository/alabs-snapshot-local/</url>
</snapshotRepository>
-->
<repository>
<id>gitlab-maven</id>
<url>https://gitlab.com/api/v4/projects/14840263/packages/maven</url>
</repository>
<snapshotRepository>
<id>gitlab-maven</id>
<url>https://gitlab.com/api/v4/projects/14840263/packages/maven</url>
</snapshotRepository>
</distributionManagement>
<pluginRepositories>
<!--
<pluginRepository>
<id>Analytical Labs Plugin Repo</id>
<name>Analytical Labs Repo-releases</name>
<url>http://repo.meteorite.bi/repository/alabs-release-local/</url>
</pluginRepository>
-->
<pluginRepository>
<id>pentaho-third-party</id>
<url>http://nexus.pentaho.org/content/repositories/proxy-public-3rd-party-release/</url>
</pluginRepository>
</pluginRepositories>
<repositories>
<!--
<repository>
<id>Analytical Labs Repo</id>
<name>Analytical Labs Repo-releases</name>
<url>http://repo.meteorite.bi/repository/alabs-release-local/</url>
</repository>
<repository>
<id>Analytical Labs snapshots</id>
<name>Analytical Labs Repo-releases</name>
<url>http://repo.meteorite.bi/repository/alabs-snapshot-local/</url>
</repository>
-->
<!-- 这里找到了四个有效的地址 -->
<repository>
<id>gitlab-maven</id>
<url>https://gitlab.com/api/v4/projects/14840263/packages/maven</url>
</repository>
<repository>
<id>saiku-group</id>
<url>https://nexus.nuiton.org/nexus/content/repositories/saiku-group/</url>
</repository>
<repository>
<id>pentaho-pentaho-third-party</id>
<url>http://nexus.pentaho.org/content/repositories/proxy-pentaho-public-release-group/</url>
</repository>
<repository>
<id>pentaho-public-third-party</id>
<url>http://nexus.pentaho.org/content/repositories/proxy-public-3rd-party-release/</url>
</repository>
<!-- 下面接省下的.... -->
</repositories>
<plugins>
<!-- 建议注释掉检查(我这边是注释掉了)
<plugin>
<groupId>org.owasp</groupId>
<artifactId>dependency-check-maven</artifactId>
<version>3.3.2</version>
<executions>
<execution>
<goals>
<goal>check</goal>
</goals>
</execution>
</executions>
</plugin> -->
<!-- 下面接省下的.... -->
</plugins>
- saiku\saiku-ui\pom.xml
<repositories>
<!--
<repository>
<id>jsdoctk1</id>
<url>http://jsdoctk-plugin.googlecode.com/svn/repo</url>
</repository>
-->
<repository>
<id>saiku-group</id>
<url>https://nexus.nuiton.org/nexus/content/repositories/saiku-group/</url>
</repository>
</repositories>
<pluginRepositories>
<!--
<pluginRepository>
<id>jsdoctk2</id>
<url>http://jsdoctk-plugin.googlecode.com/svn/repo</url>
</pluginRepository>
<pluginRepository>
<name>oss.sonatype.org</name>
<id>oss.sonatype.org</id>
<url>http://oss.sonatype.org/content/groups/public</url>
</pluginRepository>
-->
<pluginRepository>
<id>saiku-group2</id>
<url>https://nexus.nuiton.org/nexus/content/repositories/saiku-group/</url>
</pluginRepository>
</pluginRepositories>
- saiku\saiku-bi-platform-plugin-p7\pom.xml
<repositories>
<!--
<repository>
<id>Analytical Labs Repo</id>
<name>Analytical Labs Repo-releases</name>
<url>http://repo.meteorite.bi/repository/alabs-release-local/</url>
</repository>
<repository>
<id>Analytical Labs snapshots</id>
<name>Analytical Labs Repo-releases</name>
<url>http://repo.meteorite.bi/repository/alabs-snapshot-local</url>
</repository>
-->
<repository>
<id>gitlab-maven</id>
<url>https://gitlab.com/api/v4/projects/14840263/packages/maven</url>
</repository>
<repository>
<id>saiku-group</id>
<url>https://nexus.nuiton.org/nexus/content/repositories/saiku-group/</url>
</repository>
<repository>
<id>pentaho-pentaho-third-party</id>
<url>http://nexus.pentaho.org/content/repositories/proxy-pentaho-public-release-group/</url>
</repository>
<repository>
<id>pentaho-public-third-party</id>
<url>http://nexus.pentaho.org/content/repositories/proxy-public-3rd-party-release/</url>
</repository>
<!-- 下面接省下的.... -->
</repositories>
- saiku\saiku-core\saiku-olap-util\src\main\java\mondrian\olap4j\SaikuMondrianHelper.java
public static String getMeasureGroup(Measure measure){
if(isMondrian(measure)){
MondrianOlap4jMeasure m = (MondrianOlap4jMeasure) measure;
/** 注释掉这里 */
/** try {
return ((RolapBaseCubeMeasure) m.member).getMeasureGroup().getName();
}
catch(Exception e){
return "";
}
catch(Error e2){
return "";
}
*/
}
return null;
}
- saiku\saiku-core\saiku-olap-util\src\main\java\mondrian\rolap\DimensionLookup.java
public static boolean getHanger(RolapCubeDimension dim){
/** 这里改成true即可 */
return true;
}
三 下载maven依赖
// 在根目录下执行
mvn clean install -DskipTests
静静等待即可。
【如果提示mvn命令不存在,则需要先配置maven环境变量】
【如果改完上面的maven还报错,可以留言给我】
四 去除License验证信息【可选】
去除License验证信息需要修改以下几处源码
- saiku\saiku-core\saiku-web\src\main\java\org\saiku\web\rest\resources\License.java
/**
* Get the saiku
* @summary Get the Saiku License installed on the current server
* @return A response containing a license object.
*/
@GET
@Produces({ "application/json" })
public Response getLicense() {
// 直接返回正确结果
// try {
// return Response.ok().entity(licenseUtils.getLicense()).build();
// } catch (IOException | RepositoryException | ClassNotFoundException e) {
// e.printStackTrace();
// }
return Response.serverError().build();
}
- saiku\saiku-core\saiku-web\src\main\java\org\saiku\web\service\SessionService.java
修改login,去掉验证代码
/* (non-Javadoc)
* @see org.saiku.web.service.ISessionService#login(javax.servlet.http.HttpServletRequest, java.lang.String, java.lang.String)
*/
public Map<String, Object> login(HttpServletRequest req, String username, String password ) throws LicenseException {
// Object sl = null;
// String notice = null;
HttpSession session = ((HttpServletRequest)req).getSession(true);
session.getId();
sessionRepo.setSession(session);
// try {
// sl = l.getLicense();
// } catch (Exception e) {
// log.debug("Could not process license", e);
// throw new LicenseException("Error fetching license. Get a free license from http://licensing.meteorite.bi. You can upload it at /upload.html");
// }
// if (sl != null) {
// try {
// l.validateLicense();
// } catch (RepositoryException | IOException | ClassNotFoundException e) {
// log.debug("Repository Exception, couldn't get license", e);
// throw new LicenseException("Error fetching license. Please check your logs.");
// }
if (authenticationManager != null) {
authenticate(req, username, password);
}
if (SecurityContextHolder.getContext() != null
&& SecurityContextHolder.getContext().getAuthentication() != null) {
Authentication auth = SecurityContextHolder.getContext().getAuthentication();
if (authorisationPredicate.isAuthorised(auth)) {
Object p = auth.getPrincipal();
createSession(auth, username, password);
return sessionHolder.get(p);
} else {
log.info(username + " failed authorisation. Rejecting login");
throw new RuntimeException("Authorisation failed for: " + username);
}
}
return new HashMap<>();
}
- saiku\saiku-ui\js\saiku\models\Session.js
需要更改process_session和check_session方法
check_session: function() {
// This authentication cookie is used only by Orbis authentication strategy
var authCookie = this.getCookie(Settings.ORBIS_AUTH.cookieName);
if (Settings.ORBIS_AUTH.hazelcast_enabled && authCookie && !this.atemptedToLoginByCookie) {
this.sessionid = 1;
this.username = authCookie;
this.password = authCookie;
this.atemptedToLoginByCookie = true;
// In this case we inject the proper license attributes
var ONE_YEAR = 31556952000;
/**
Settings.LICENSE = {
licenseType: 'Orbis',
expiration: Date.now() + ONE_YEAR
}
*/
this.login(authCookie, authCookie);
} else {
if (this.sessionid === null || this.username === null || this.password === null) {
var that = this;
this.clear();
this.fetch({ success: this.process_session, error: this.brute_force });
} else {
if (!this.atemptedToLoginByCookie) {
this.username = encodeURIComponent(options.username);
}
this.load_session();
}
}
},
process_session: function(model, response) {
if ((response === null || response.sessionid == null)) {
// Open form and retrieve credentials
Saiku.ui.unblock();
if (Settings.DEMO) {
this.form = new DemoLoginForm({ session: this });
} else {
this.form = new LoginForm({ session: this });
}
this.form.render().open();
} else {
this.sessionid = response.sessionid;
this.roles = response.roles;
this.isAdmin = Settings.ORBIS_AUTH.hazelcast_enabled || response.isadmin;
this.username = encodeURIComponent(response.username);
this.language = response.language;
if (typeof this.language != "undefined" && this.language != Saiku.i18n.locale) {
Saiku.i18n.locale = this.language;
Saiku.i18n.automatic_i18n();
}
/**
var license =new License();
license.fetch_license('api/license/', function(opt) {
if (opt.status === 'success') {
Settings.LICENSE = opt.data.toJSON();
}
if(Saiku.session.isAdmin) {
var quota = new LicenseQuota();
quota.fetch_quota('api/license/quota', function (opt) {
if (opt.status === 'success') {
Settings.LICENSEQUOTA = opt.data.toJSON();
}
});
}
});
*/
this.load_session();
}
return this;
},
- saiku\saiku-ui\js\saiku\views\Upgrade.js
去除升级提示,注释掉所有render的内容
render: function() {
/*
var self = this;
var license = new License();
if(Settings.BIPLUGIN5){
if(Saiku.session.get("notice") != undefined && Saiku.session.get("notice")!=null && Saiku.session.get("notice")!=""){
$(this.el).append("<div><div id='uphead' class='upgradeheader'>Notice:"+Saiku.session.get("notice")+"</div>");
}
if (Settings.LICENSE.licenseType != undefined && (Settings.LICENSE.licenseType != "trial" && Settings.LICENSE.licenseType != "Open Source License")) {
return this;
}
if (Settings.LICENSE != undefined && Settings.LICENSE.licenseType === "trial") {
var yourEpoch = parseFloat(Settings.LICENSE.expiration);
var yourDate = new Date(yourEpoch);
self.remainingdays = self.daydiff(new Date(), yourDate);
$(this.el).append("<div><div id='uphead' class='upgradeheader'>You are using a Saiku Enterprise" +
" Trial license, you have "+ self.remainingdays+" days remaining. <a href='http://www.meteorite.bi/saiku-pricing'>Buy licenses online.</a></div>");
return self;
}
else {
$(this.el).append("<div><div id='uphead' class='upgradeheader'>You are using Saiku Community" +
" Edition, please consider upgrading to <a target='_blank' href='http://meteorite.bi'>Saiku Enterprise</a>, or entering a <a href='http://meteorite.bi/products/saiku/sponsorship'>sponsorship agreement with us</a> to support development. " +
"<a href='http://meteorite.bi/products/saiku/community'>Or contribute by joining our community and helping other users!</a></div></div>");
return self;
}
}
else {
if(Saiku.session.get("notice") != undefined && Saiku.session.get("notice")!=null && Saiku.session.get("notice")!=""){
$(this.el).append("<div><div id='uphead' class='upgradeheader'>Notice:"+Saiku.session.get("notice")+"</div>");
}
if (Settings.LICENSE.licenseType != undefined && (Settings.LICENSE.licenseType != "trial" &&
Settings.LICENSE.licenseType != "Open Source License")) {
return this;
}
if (Settings.LICENSE.licenseType === "trial") {
var yourEpoch = parseFloat(Settings.LICENSE.expiration);
var yourDate = new Date(yourEpoch);
self.remainingdays = self.daydiff(new Date(), yourDate);
$(this.el).append("<div><div id='uphead' class='upgradeheader'>You are using a Saiku Enterprise" +
" Trial license, you have "+ self.remainingdays+" days remaining. <a href='http://www.meteorite.bi/saiku-pricing'>Buy licenses online.</a></div>");
return self;
}
else {
$(this.el).append("<div><div id='uphead' class='upgradeheader'>You are using Saiku Community" +
" Edition, please consider upgrading to <a target='_blank' href='http://meteorite.bi'>Saiku Enterprise</a>, or entering a <a href='http://meteorite.bi/products/saiku/sponsorship'>sponsorship agreement with us</a> to support development. " +
"<a href='http://meteorite.bi/products/saiku/community'>Or contribute by joining our community and helping other users!</a></div></div>");
return self;
}
}
*/
},
去除之后重新打包即可
问题及解决方案
一、启动报错 Cannot set SAX feature because outdated XML parser in classpath: http://javax.xml.XMLConstants/feature/secure-processing
问题原因
Saiku 自带的xerces,与jdk8中的JAX-B不兼容
解决方式
- 降级,从jdk1.8 降级到 jdk1.7
- 为java添加系统变量。编辑 saiku\saiku-server\target\dist\saiku-server\start-saiku.bat,在CATALINA_OPTS 后面加上如下内容
-Dorg.xml.sax.parser="com.sun.org.apache.xerces.internal.parsers.SAXParser" -Djavax.xml.parsers.DocumentBuilderFactory="com.sun.org.apache.xerces.internal.jaxp.DocumentBuilderFactoryImpl" -Djavax.xml.parsers.SAXParserFactory="com.sun.org.apache.xerces.internal.jaxp.SAXParserFactoryImpl"
如果不想打包就更改的话,可以直接设置
System.setProperty("org.xml.sax.driver", "com.sun.org.apache.xerces.internal.parsers.SAXParser");
System.setProperty("javax.xml.parsers.DocumentBuilderFactory","com.sun.org.apache.xerces.internal.jaxp.DocumentBuilderFactoryImpl");
System.setProperty("javax.xml.parsers.SAXParserFactory","com.sun.org.apache.xerces.internal.jaxp.SAXParserFactoryImpl");
或者在maven的tomcat插件里加上
<javax.xml.parsers.DocumentBuilderFactory>com.sun.org.apache.xerces.internal.jaxp.DocumentBuilderFactoryImpl</javax.xml.parsers.DocumentBuilderFactory>
<org.xml.sax.parser>com.sun.org.apache.xerces.internal.parsers.SAXParser</org.xml.sax.parser>
<javax.xml.parsers.SAXParserFactory>com.sun.org.apache.xerces.internal.jaxp.SAXParserFactoryImpl</javax.xml.parsers.SAXParserFactory>