Home
Analytics
Set the engineHome to be the current classpath
pJune
Hi,
I have a java application that opens a report and displays it using jframe. This is how I have my engine home set up:
config = new EngineConfig();
config.setEngineHome("C:/birtruntime/birt-runtime-2_6_1/ReportEngine");
I would like to package everything in one jar, and eliminate hard coding the location of the birtruntime. Clients are not going to have this folder in their machines, so I would like to set the engine home to the current classpath (containing all the jars from the ReportEngine/lib folder). How can I set the engine home to be the current classpath? Ideally the client will double click the jar and the report will be displayed.
Thanks in advanced
Find more posts tagged with
Comments
JasonW
Currently the birt home needs to be a hard location. It does not need to be hard coded but needs a fixed file system location as it starts up osgi in given location. In the above example the ReportEngine directory contains a plugins and a configuration directory. Both of these are used in starting up osgi. You can make this configurable but whatever method you use will still require a hard location on the filesystem.
--From the
http://www.eclipse.org/birt/phoenix/deploy/reportEngineAPI.php
page
IPlatformContext - Web Based Plugin Loading
By default BIRT loads plug-ins located in the BIRT_HOME/plugins directory. The plug-ins loaded provide functionality for connecting to data sources, emitters (eg, PDF, WORD, XLS, HTML ...), and chart rendering. BIRT_HOME in the examples on this page is set using the setEngineHome method of the EngineConfig class. BIRT loads these plug-ins using the Java File API.
This method is usually sufficient. If deployed to a web application, the developer can usually call ServletContext.getRealPath to retrieve the real path and set the BIRT_HOME accordingly. This can present a problem when deploying to a war file. Certain application servers will return null when getRealPath is called. This will result in the plug-ins not getting loaded.
The IPlatformContext interface describes the methods needed to load the resources required by the BIRT runtime. Within BIRT there are two implementations of this interface, PlatformFileContext() and PlatformServletContext(). The Platform Context is set using the setEngineContext method of the EngineConfig class. If this method is not called it defaults to PlaformFileContext() and uses the Java File API to load the resources. The PlatformServletContext class uses Resource based operations. So if you are deploying an application to the Web that uses the BIRT API and it is not contained in a war you can use the default and set your engine home to something similar to:
config.setEngineHome( servletContext.getRealPath("/WEB-INF"));
The BIRT Viewer application will load the plug-ins from /WEB-INF/Plugins directory. If you deploy your application in a war, setup your code like:
//this causes the plug-in loader to look in the current directory.
config.setEngineHome("");
//Using the PlatformServletContext will cause the OSGi loader to look for the
//plug-ins in the WEB-INF/Platform directory. If this directory
//does not exist create it.
//Next copy the plug-ins directory from the ReportEngine directory to
//the WEB-INF/Platform/ directory.
IPlatformContext context = new PlatformServletContext( sc );
config.setPlatformContext( context );
Jason
pJune
Thank you for your explanation. However, I am not deploying birt to a web application. Is my only solution to package in the jar the lib and plugins folder?
JasonW
I understand you are not deploying to the web, I just wanted to let you know you can implement your own version of the IPlatformContext interface to setup the home location the way you want. The jars in the reportengine/lib will need to be in your classpath. The configuration and platform directories can be jarred but you will have to extract them to a hard location before the osgi engine can be started. I am posting the implementation of the PlatformServletContext class so you can see how its done in the web. Look at the deploy function, which just extracts the platform to the temp directory.
Jason
/*******************************************************************************
* Copyright (c) 2004 Actuate Corporation. All rights reserved. This program and
* the accompanying materials are made available under the terms of the Eclipse
* Public License v1.0 which accompanies this distribution, and is available at
*
http://www.eclipse.org/legal/epl-v10.html
Contributors: Actuate Corporation -
* initial API and implementation
******************************************************************************/
package org.eclipse.birt.core.framework;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.security.AccessController;
import java.security.PrivilegedAction;
import java.util.Iterator;
import java.util.Set;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.servlet.ServletContext;
/**
* An platform context that is based on resource operations instead of file
* operations. Since in web environment WAR deployment, absolute file path is
* not available, user must use resource operations instead of file operations.
* In this case, user should use this PlatformContext or develop his own
* PlatformContext to make sure no file operations are used.
*/
public class PlatformServletContext implements IPlatformContext
{
static protected Logger log = Logger
.getLogger( PlatformServletContext.class.getName( ) );
private static final String RESOURCE_BASE = "/WEB-INF/platform/"; //$NON-NLS-1$
private ServletContext context = null; // the ServletContext.
private String platform;
protected PlatformConfig platformConfig;
/**
*
@param
context
*
@param
urlLeadingString
*
@deprecated
since 2.1
*/
public PlatformServletContext( ServletContext context, String urlLeadingString )
{
this.context = context;
}
public PlatformServletContext( ServletContext context )
{
this.context = context;
}
public String getPlatform( )
{
if ( platform == null )
{
synchronized ( this )
{
if ( platform == null )
{
AccessController
.doPrivileged( new PrivilegedAction<Object>( ) {
public Object run( )
{
deploy( );
return null;
}
} );
}
}
}
return platform;
}
/**
* deploy the platform resources to file based platform.
*
*/
private void deploy( )
{
assert platform == null;
platform = context.getRealPath( RESOURCE_BASE );
if ( platform == null )
{
File contextTemp = (File) context
.getAttribute( "javax.servlet.context.tempdir" ); //$NON-NLS-1$
File platformFolder = new File( contextTemp, "platform" );
//Weblogic try to remove the platform but it failes,
//so try to copy the platform each time.
//if ( !platformFolder.exists( ) )
{
platformFolder.mkdir( );
copyResources( RESOURCE_BASE, platformFolder.getAbsolutePath( ) );
}
platform = platformFolder.getAbsolutePath( );
}
}
/**
* copy resource to the platform.
* If the resources is a folder, make the same folder into the platform and copy
* all resources into the dest folder.
*
@param
resourcePath resource path.
*
@param
platform platform folder
*/
private void copyResources( String resourcePath, String platform )
{
Set paths = context.getResourcePaths( resourcePath );
if (paths != null)
{
for ( Iterator it = paths.iterator( ); it.hasNext( ); )
{
String path = (String) it.next( );
File newFile = new File( platform, path.substring( RESOURCE_BASE
.length( ) ) );
if ( path.endsWith( "/" ) ) { //$NON-NLS-1$
newFile.mkdir( );
copyResources( path, platform );
}
else
{
InputStream is = null;
OutputStream os = null;
try
{
if ( newFile.createNewFile( ) )
{
is = context.getResourceAsStream( path );
os = new FileOutputStream( newFile );
byte[] buffer = new byte[8192];
int bytesRead = is.read( buffer );
while ( bytesRead != -1 )
{
os.write( buffer, 0, bytesRead );
bytesRead = is.read( buffer );
}
}
}
catch ( IOException e )
{
log.log( Level.WARNING,
"Error copying resources {0} to platform.", e ); //$NON-NLS-1$
}
finally
{
if ( is != null )
{
try
{
is.close( );
}
catch ( Exception exin )
{
log.log( Level.WARNING,
"Error closing resource stream.", exin );//$NON-NLS-1$
}
is = null;
}
if ( os != null )
{
try
{
os.close( );
}
catch ( Exception exout )
{
log
.log(
Level.WARNING,
"Error closing file output stream.", exout );//$NON-NLS-1$
}
os = null;
}
}
}
}
}
}
}
pJune
Thank you very much for your time and explanation. I understood what I need to do
pJune
<blockquote class='ipsBlockquote' data-author="'JasonW'" data-cid="72773" data-time="1296493609" data-date="31 January 2011 - 10:06 AM"><p>
I understand you are not deploying to the web, I just wanted to let you know you can implement your own version of the IPlatformContext interface to setup the home location the way you want. The jars in the reportengine/lib will need to be in your classpath. The configuration and platform directories can be jarred but you will have to extract them to a hard location before the osgi engine can be started. I am posting the implementation of the PlatformServletContext class so you can see how its done in the web. Look at the deploy function, which just extracts the platform to the temp directory.<br />
<br />
Jason<br />
<br />
/*******************************************************************************<br />
* Copyright (c) 2004 Actuate Corporation. All rights reserved. This program and<br />
* the accompanying materials are made available under the terms of the Eclipse<br />
* Public License v1.0 which accompanies this distribution, and is available at<br />
* <a class='bbc_url' href='
http://www.eclipse.org/legal/epl-v10.html'>http://www.eclipse.org/legal/epl-v10.html</a>
; Contributors: Actuate Corporation -<br />
* initial API and implementation<br />
******************************************************************************/<br />
<br />
package org.eclipse.birt.core.framework;<br />
<br />
import java.io.File;<br />
import java.io.FileOutputStream;<br />
import java.io.IOException;<br />
import java.io.InputStream;<br />
import java.io.OutputStream;<br />
import java.security.AccessController;<br />
import java.security.PrivilegedAction;<br />
import java.util.Iterator;<br />
import java.util.Set;<br />
import java.util.logging.Level;<br />
import java.util.logging.Logger;<br />
<br />
import javax.servlet.ServletContext;<br />
<br />
/**<br />
* An platform context that is based on resource operations instead of file<br />
* operations. Since in web environment WAR deployment, absolute file path is<br />
* not available, user must use resource operations instead of file operations.<br />
* In this case, user should use this PlatformContext or develop his own<br />
* PlatformContext to make sure no file operations are used.<br />
*/<br />
public class PlatformServletContext implements IPlatformContext<br />
{<br />
<br />
static protected Logger log = Logger<br />
.getLogger( PlatformServletContext.class.getName( ) );<br />
<br />
private static final String RESOURCE_BASE = "/WEB-INF/platform/"; //$NON-NLS-1$<br />
private ServletContext context = null; // the ServletContext.<br />
private String platform;<br />
protected PlatformConfig platformConfig;<br />
/**<br />
*
@param
context<br />
*
@param
urlLeadingString<br />
*
@deprecated
since 2.1<br />
*/<br />
public PlatformServletContext( ServletContext context, String urlLeadingString )<br />
{<br />
this.context = context;<br />
}<br />
<br />
public PlatformServletContext( ServletContext context )<br />
{<br />
this.context = context;<br />
}<br />
<br />
public String getPlatform( )<br />
{<br />
if ( platform == null )<br />
{<br />
synchronized ( this )<br />
{<br />
if ( platform == null )<br />
{<br />
AccessController<br />
.doPrivileged( new PrivilegedAction<Object>( ) {<br />
<br />
public Object run( )<br />
{<br />
deploy( );<br />
return null;<br />
}<br />
} ); <br />
}<br />
}<br />
}<br />
return platform;<br />
}<br />
<br />
/**<br />
* deploy the platform resources to file based platform. <br />
*<br />
*/<br />
private void deploy( )<br />
{<br />
assert platform == null;<br />
platform = context.getRealPath( RESOURCE_BASE );<br />
if ( platform == null )<br />
{<br />
File contextTemp = (File) context<br />
.getAttribute( "javax.servlet.context.tempdir" ); //$NON-NLS-1$<br />
File platformFolder = new File( contextTemp, "platform" );<br />
//Weblogic try to remove the platform but it failes,<br />
//so try to copy the platform each time.<br />
//if ( !platformFolder.exists( ) )<br />
{<br />
platformFolder.mkdir( );<br />
copyResources( RESOURCE_BASE, platformFolder.getAbsolutePath( ) );<br />
}<br />
platform = platformFolder.getAbsolutePath( );<br />
}<br />
}<br />
<br />
/**<br />
* copy resource to the platform. <br />
* If the resources is a folder, make the same folder into the platform and copy<br />
* all resources into the dest folder.<br />
*
@param
resourcePath resource path.<br />
*
@param
platform platform folder<br />
*/<br />
private void copyResources( String resourcePath, String platform )<br />
{<br />
Set paths = context.getResourcePaths( resourcePath );<br />
if (paths != null)<br />
{<br />
for ( Iterator it = paths.iterator( ); it.hasNext( ); )<br />
{<br />
String path = (String) it.next( );<br />
File newFile = new File( platform, path.substring( RESOURCE_BASE<br />
.length( ) ) );<br />
if ( path.endsWith( "/" ) ) { //$NON-NLS-1$<br />
newFile.mkdir( );<br />
copyResources( path, platform );<br />
}<br />
else<br />
{<br />
InputStream is = null;<br />
OutputStream os = null;<br />
try<br />
{<br />
if ( newFile.createNewFile( ) )<br />
{<br />
is = context.getResourceAsStream( path );<br />
os = new FileOutputStream( newFile );<br />
byte[] buffer = new byte[8192];<br />
int bytesRead = is.read( buffer );<br />
while ( bytesRead != -1 )<br />
{<br />
os.write( buffer, 0, bytesRead );<br />
bytesRead = is.read( buffer );<br />
}<br />
}<br />
}<br />
catch ( IOException e )<br />
{<br />
log.log( Level.WARNING,<br />
"Error copying resources {0} to platform.", e ); //$NON-NLS-1$<br />
}<br />
finally<br />
{<br />
if ( is != null )<br />
{<br />
try<br />
{<br />
is.close( );<br />
}<br />
catch ( Exception exin )<br />
{<br />
log.log( Level.WARNING,<br />
"Error closing resource stream.", exin );//$NON-NLS-1$<br />
}<br />
is = null;<br />
}<br />
<br />
if ( os != null )<br />
{<br />
try<br />
{<br />
os.close( );<br />
}<br />
catch ( Exception exout )<br />
{<br />
log<br />
.log(<br />
Level.WARNING,<br />
"Error closing file output stream.", exout );//$NON-NLS-1$<br />
}<br />
os = null;<br />
}<br />
}<br />
}<br />
}<br />
}<br />
}<br />
}<br /></p></blockquote>
Do you know any good book that helps me using Birt 2.6.1?<br />
Thanks
JasonW
You may want to have a look at these:
http://www.eclipse.org/birt/phoenix/birthelp.php#books
We are currently updating these for BIRT 2.6.
Jason