Using Java in BIRT reports

12. November, 2010
BIRT Project

Image via Wikipedia

If you need to add complex operations to BIRT reports, you have several options. One that is often overlooked is to write the operation in Java and then use the Java code in the report. This is more simple than you’d think.

Instead of creating a “Report” project, create a Java project for your reports. Now you can put the Java code in the same project or a different project and add that second project to the list of dependencies of your report project. Note that this only works if the report project is of type “Java”.

When you edit your code, you just need to save and run your report (using the various ways to run the preview).

You can even debug the code. There is just one thing you need to be aware of: In the debug configuration, you can specify if you want to debug Java, JavaScript of both. JavaScript is the default. In this mode, Java breakpoints have no effect.


Building patches for Eclipse

10. November, 2010

Frustrated by mysterious error messages from PDE? Overwhelmed by Buckminster?

If you need to apply a simple patch to a plug-in for Eclipse, there is a more simple way. Follow this recipe:

  1. Download the source for the plug-in
  2. Create a new project
  3. Add all plug-ins in the eclipse/plugins folder to the build path. Use the variable eclipse_home. This is most simple if you use an ANT build script. If you want to waste time, try to figure out which plugins you need and only add those.
  4. Extract the few Java source files that you need to modify and copy them into your project.
  5. Copy the JARs of plugins you want to patch into your project.
  6. Fix the bugs.
  7. Use a bit of ANT magic to replace the Java classes in the JARs you copied in step #5 with the fixed versions. The trick here is that most Eclipse JARs are signed. You’ll need to remove the cryptographic keys in order to be able to load the JARs. See below for a piece of code that does the trick.
  8. Add a rule to your build.xml to copy the fixed JARs back into the plugins folder of Eclipse.
  9. Exit Eclipse (or start another instance) to test your fixes.

Here is the source to strip the SHA1-Digest keys from a MANIFEST.MF file:

// Needs commons-io 1.4
public class FilterManifest {

    public static void main( String[] args ) {
        try {
            FilterManifest tool = new FilterManifest();
            tool.run( args );
        } catch( Exception e ) {
            e.printStackTrace();
            System.exit( 1 );
        }
    }

    private void run( String[] args ) throws Exception {
        File manifestFile = new File( args[0] );
        Manifest manifest = readManifest( manifestFile );

        manifest.getEntries().clear();

        File backup = new File( manifestFile.getAbsolutePath() + ".bak" );
        if(! manifestFile.renameTo( backup ) ) {
            throw new RuntimeException( "Can't backup file" );
        }

        save( manifest, manifestFile );
    }

    private void save( Manifest manifest, File manifestFile ) throws IOException {
        FileOutputStream stream = new FileOutputStream( manifestFile );
        try {
            manifest.write( stream );
        } finally {
            IOUtils.closeQuietly( stream );
        }
    }

    private Manifest readManifest( File manifestFile ) throws IOException {
        FileInputStream stream = new FileInputStream( manifestFile );
        try {
            return new Manifest( stream );
        } finally {
            IOUtils.closeQuietly( stream );
        }
    }

}

To use this code, use this ANT code:

    <target name="fix-org.eclipse.birt.engine" depends="init">
        <unjar src="plugins/org.eclipse.birt.report.engine_2.6.1.v20100915.jar" dest="tmp">
            <patternset>
                <include name="META-INF/MANIFEST.MF"/>
            </patternset>
        </unjar>
        <java classname="tools.FilterManifest">
            <arg file="tmp/META-INF/MANIFEST.MF"/>
            
            <classpath>
                <pathelement location="target-eclipse/classes" />
                <pathelement location="target/classes" />
                <pathelement location="${m2_repo}/commons-io/commons-io/1.4/commons-io-1.4.jar" />
            </classpath>
        </java>
        <jar destfile="tmp/org.eclipse.birt.report.engine_2.6.1.v20100915.jar"
            compress="true" update="true" duplicate="preserve" index="true"
            manifest="tmp/META-INF/MANIFEST.MF"
        >
            <fileset dir="target-eclipse/classes">
                <include name="org/eclipse/birt/report/engine/**/*" />
            </fileset>
            <zipfileset src="plugins/org.eclipse.birt.report.engine_2.6.1.v20100915.jar">
                <exclude name="META-INF/*"/>
            </zipfileset>
        </jar>
    </target>

The two <pathelement> elements are necessary to make the code work from Eclipse and command line Maven (I’m using different target directories for Eclipse and Maven).

The complex <jar> target allows to copy everything from the existing plugin JAR but the crypto info.


Eclipse Modeling Day

29. October, 2010
Figure 4-3: Data Modelling Today

Image via Wikipedia

Yesterday was Eclipse Modeling Day here in Zürich. There were a couple of talks from people who were using modeling for projects and talks from project leaders of modeling projects like EMF and CDO.

Eclipse Modeling Platform for Enterprise Modeling

If you’ve used the Eclipse modeling projects, you’ll know the pain: Where to start? Which project is worth to spend time with? Caveats? Things like that. It seems that’s not a superficial problem. Eclipse Modeling is a big, unsolved jigsaw puzzle. The new project “Eclipse Modeling Platform” sets out to close the major gaps in the next two years. On the road map are things like authentication, large scale models, comparing models, etc.

For me, the list of topics looked more like an MBA’s wish-list than something that will make life easier for software developers. Their standpoint was that the funders call the shots. My standpoint is that the we need tools to help us solve the basic issues like good editors for (meta-)models and a useful debugging framework for code generators.

Interesting projects: Sphinx and Papyrus.

User Story: Models as First Class Citizens in the Enterprise

Since many people didn’t seem to be aware that modeling can do, Robert Blust (UBS AG) showed an example. Like most banks, the UBS has tons of legacy code. And tons of rules. Rules like: Any application A must access data of another application B via a well-defined interface. Their product would collect a couple of gigabytes of data from old COBOL code and use that to determine dependencies (like the DB tables it uses).

The next step would be to define which tables belong to which application and the end result is an application which can show and track you rule violations. Or which can show a Java developer which tables he must care for if he has to replace an old COBOL application.

There was the question of authentication: Who can see what of the model? This is going to be some work to solve in a way that it’s still manageable. For example, a part of the model could be accessible via a roles-based model. A software developer should be able to see all the data which is relevant to his project. But what about bug reports? Should a reporter be allowed to see all of them? What about the security related ones?

If we go to fraud tracking, individual instances in the model might be visible to just a very few people. So authentication is something which needs to scale extremely well. It must be as coarse of fine-grained as needed, sometimes the whole range in a single model.

Eclipse Modeling Framework for Data Modeling

Ed Merks introduced EMF. Not much new here for me. I tried to talk to him during the coffee break but he was occupied by Benjamin Ginsberg. Benjamin was interested to get a first rough view on modeling. Apparently, I made some impression on him, because he came back later to see me.

Textual Modeling with Xtext

Sven Efftinge showed some magic using Xtext: He had his meta-model open in two editors, a textual and a graphical one. When he changed something in the graphical view, it would show up in the text editor after save. Nice. I couldn’t ask him how much code it took to implement this.

Under the hood, Xtext uses Guice for dependency injection.

Graphical Modeling with Graphiti

Michael Wenz from SAP showcased Graphiti. It’s a graphical editor framework for models like GMF but I guess there is a reason why SAP invented the wheel again. Several people at the event mentioned GMF unfavorably. I’m not sure why that is but I remember that EMF generated huge, non-reusable blobs of Java code when I asked it to generate an editor for my models. Ed wasn’t exactly excited when I asked to change that.

Graphiti itself looks really promising. The current 0.8 is pretty stable and has a graphical editor for JPA models which allow to define relations between instances via drag-and-drop. No more wondering which side is the “opposite.” It also creates all the fields, gives them the right types, etc. From the back of the room, it looked like a great time-saver.

User Story: The Usage of Models in an Embedded Automotive IDE

A guy from Bosch showed some real-life problems with modeling, especially with performance. They have huge models. Since they didn’t look at CDO, their editors had to load the whole model into RAM. Since Java can only allocate 1.5GB of RAM on a 32-bit hardware, they are at the limit of what they can handle (some projects have 400MB sources).

It’s a good example how an existing technology could have made their lives easier if they only knew about it. Or maybe EMF is too simple a solution (as in “A scientific theory should be as simple as possible, but no simpler.” — AlbertEinstein).

Modeling Repository with CDO

Eike Stepper was glad, though. It gave him a perfect opportunity to present CDO which solves exactly this problem. CDO connects a client to a repository server. Any change to the model in the client is sent to the server, applied and then confirmed for all connected clients. So things like scalability, remote access and multi-client support come for free.

Over the years, CDO has collected a big number of connection modes like replication and an off-line mode. They even solve problems like processing lists with millions of elements. Promising.

One problem Eike mentioned are the default EMF editors. Not reusable, not exactly user-friendly. Since that didn’t change for the last four years, it’s probably something the modeling community doesn’t deem “important.” For some people, XML is apparently good enough.

Project Dawn is trying to improve the situation.

User Story: Successful Use of MDSD in the Energy Industry

RWE (one of the largest European energy companies) showed how they used model driven software development (MDSD) to create software to automatically handle all the use cases of their energy network. He stressed the fact that without strict rules and their application, MDSD will fail just like any other methodology. Do I hear moaning out of the agile corner? 😉

Anyway. My impression was that these guys don’t come up with stup…great new ideas every five minutes and expect that they are already implemented. Delivering electricity isn’t something that you entrust just on anybody. These people are careful to start with. So I see it that there are in fact industries where strict rules work. Anyway, MDSD is another arrow in the quiver. Use it wisely.

User Story: Nord/LB – Modeling of Banking Applications with Xtext and GMF

The last speaker was from Nord/LB, a German bank. He dropped a couple of remarks about GMF. Seems like he hit some of the gaps mentioned earlier.

Their solution included several DSLs which allowed them to describe the model, the UIs, the page flow in the web browser, etc. Having seen Enthought Traits, I’m wondering which approach is better: Keep everything in a separate model (well, Xtext can track cross-references between models just like the Java editor can) or put all the information in a single place.

If you keep everything in a single place (i.e. every part of the model also knows what to tell the UI framework when it wants to generate the editors), that makes the description of the model quite big and confusing. The information you want to see is drowned in a dozen lines. If you keep the information separate, you must store that in your memory when you switch editors.

I guess the solution is to create an editor which can display that part of the information which you need right now.

The Reception

After the talks, I had a long talk with Eike Stepper and Ed Merks. One of my main issues is that models are pretty static. You can’t add properties and methods to it at runtime. At least not to Ecore-based models. Or maybe you could but you shouldn’t. Which seems odd to me. We have plug-in based architectures like Eclipse. We have XML which stands for Extensible Markup Language. Why does modeling have to start in the stone age again without support for model life-cycle, migration, evolution?

When I presented my use case to Eike, he said “never heard that before.” So either the modeling community is going for the long hanging fruit or my use cases are exceptional. All I’m asking is a model which I can attribute with additional information at runtime. Oh, yes, I could use EMF annotations for this. Which EMF default editor supports that? Hm. So if my users want to extend the EClass “Person” with a middle name? Something that HyperCard could do, hands down, in 1987?

 


Hidden JUnit features: @Rules

8. October, 2010

@Rules seem a better solution than @RunWith to do some special work before/after a test. The release notes mention a couple of ideas:

  • Notification on tests
  • Setting up or tearing down resources, especially when they are used in multiple test classes
  • Special checks performed after every test, possibly causing a test to fail.
  • Making information about the test available inside the test

Related articles:


Logging JDBC with slf4j

7. October, 2010

 

This chart represents several constituent comp...

Image via Wikipedia

 

If you use slf4j in your project and need to log JDBC events, then have a look at log4jdbc. It has all the usual features: Timing statements, showing all arguments, mapping SQL to connections. It can even log stack traces if you need to know where a JDBC call was made. Sample output:

16:32:56.162 [INFO ] jdbc.connection - 1. Connection opened  java.sql.DriverManager.getConnection(DriverManager.java:525)
16:32:56.168 [DEBUG] jdbc.connection - open connections:  1 (1)
16:32:56.169 [DEBUG] jdbc.audit - 1. Connection.new Connection returned   java.sql.DriverManager.getConnection(DriverManager.java:525)
16:32:56.284 [DEBUG] jdbc.audit - 1. PreparedStatement.new PreparedStatement returned   com.avanon.basic.db.XPreparedStatement.prepare(XPreparedStatement.java:84)
16:32:56.292 [DEBUG] jdbc.audit - 1. Connection.prepareStatement(SELECT *
FROM V_RCSA_40_4_CTRL_RATING) returned net.sf.log4jdbc.PreparedStatementSpy@423606  com.avanon.basic.db.XPreparedStatement.prepare(XPreparedStatement.java:84)
16:32:56.162 [INFO ] jdbc.connection - 1. Connection opened  java.sql.DriverManager.getConnection(DriverManager.java:525)
16:32:56.168 [DEBUG] jdbc.connection - open connections:  1 (1)
16:32:56.169 [DEBUG] jdbc.audit - 1. Connection.new Connection returned   java.sql.DriverManager.getConnection(DriverManager.java:525)
16:32:56.284 [DEBUG] jdbc.audit - 1. PreparedStatement.new PreparedStatement returned   com.avanon.basic.db.XPreparedStatement.prepare(XPreparedStatement.java:84)
16:32:56.292 [DEBUG] jdbc.audit - 1. Connection.prepareStatement(SELECT *FROM V_RCSA_40_4_CTRL_RATING) returned net.sf.log4jdbc.PreparedStatementSpy@423606  com.avanon.basic.db.XPreparedStatement.prepare(XPreparedStatement.java:84)
16:32:56.342 [DEBUG] jdbc.audit - 1. PreparedStatement.clearParameters() returned   com.avanon.basic.db.SetParameters.clear(SetParameters.java:144)
16:32:56.343 [DEBUG] jdbc.sqlonly -  com.avanon.basic.db.XPreparedStatement.executeQuery(XPreparedStatement.java:71)
1. SELECT * FROM V_RCSA_40_4_CTRL_RATING
16:32:56.350 [INFO ] jdbc.sqltiming - SELECT * FROM V_RCSA_40_4_CTRL_RATING  {executed in 7 msec}
16:32:56.356 [DEBUG] jdbc.audit - 1. PreparedStatement.executeQuery() returned net.sf.log4jdbc.ResultSetSpy@2c5444  com.avanon.basic.db.XPreparedStatement.executeQuery(XPreparedStatement.java:71)
16:32:56.412 [DEBUG] jdbc.audit - 1. PreparedStatement.close() returned   com.avanon.basic.db.DBUtil.close(DBUtil.java:114)
16:32:56.418 [INFO ] jdbc.connection - 1. Connection closed  com.avanon.basic.db.DBUtil.close(DBUtil.java:129)
16:32:56.418 [DEBUG] jdbc.connection - open connections:  none

The strange “1.” is the connection number.

Alternatively, check out jdbcdslog.


Error creating array in JavaScript

6. October, 2010

If you see this error in JavaScript (for example in a BIRT report):

org.mozilla.javascript.EvaluatorException: error instantiating (): class java.sql.Array is interface or abstract

then don’t include the package java.sql (as in importPackage(Packages.java.sql);) because if you do, new Array() will find the SQL class first and it will fail.


Extremely complex queries in BIRT reports

30. September, 2010

Sometimes, SQL just isn’t enough. What do you do when you just can’t get the SQL to run in under an hour while a little piece of Java code does the same query in a few seconds? Put the result into a report table and then run the report against that table.


Google Relaunches Instantiations Developer Tools

29. September, 2010
Google Web Toolkit

Image via Wikipedia

From the website:

In early August, Google acquired Instantiations, a company known for its focus on Eclipse Java developer tools, including GWT Designer. We’re happy to announce today that we’re relaunching the following former Instantiations products under the Google name and making them available to all developers at no charge:

  • GWT Designer
    Powerful Eclipse-based development tools that enable Java developers to quickly create Ajax user interfaces using Google Web Toolkit (GWT)
  • CodePro AnalytiX
    Comprehensive automated software code quality and security analysis tools to improve software quality, reliability, and maintainability
  • WindowBuilder Pro
    Java graphical user interface designer for Swing, SWT, GWT, RCP, and XWT UI frameworks
  • WindowTester Pro
    Test GUI interactions within Java client rich applications for the SWT and Swing UI frameworks

I played a bit with CodePro. The tools look promising even through there were some glitches, namely:

  1. The JUnit editor looks cool but the table with the current unit results often hangs.
  2. It was more complicated than I liked to generate test cases
  3. I couldn’t get the code coverage tool to work
  4. The dependency works but didn’t play with it long enough to say for sure how useful it is
  5. The code analysis shows a lot of numbers but the workflow is clumsy. For example, it says that something has a cyclomatic complexity of 16 but I couldn’t find out what and where.

Thoughts on documentation

28. September, 2010

Software developers believe that documentation is just another way to say code is buggy. The reasoning is like this: If the code was easy to understand and/or did what you expected, then why document it?

While this is true at the level of a code line, there should be some documentation explaining your overall view of the world.

Next, we have end user documentation. End users have no idea how software works, they just know they have to get some work done. Stat. For them, good documentation can be the difference between a nice day and weeks of overtime.

In “The Value of Documentation in Open Source“,  Chris Aniszczyk explains why this is especially important for Open Source.  Good points.

Related articles:


When inheritance is not enough

16. September, 2010

Ever had the problem that inheritance just wasn’t enough? For example in this case:

package core;
public class Main {
    public static void main(String[] args) {
        sayHello();
    }
    private static void sayHello() {
        System.out.println("Hello World!");
    }
}

Say you need to override sayHello(). What are your options?

You could edit the source. But if you only have the bytecode?

You could decompile the bytecode. But what if you need the same change in several places?

Eventually, you’ll have to use copy more or less code around because Java just doesn’t offer enough ways to combine code. The solution? Object Teams. See this article for a solution of the problem above.

What is Object Teams?

In a nutshell, a team is a group of players which have roles. Usually, the roles are distributed by way of the strengths of your players. Slow and sturdy ones will be defense. Quick and agile players will attack. The calm ones will do tactics.

OT/J (the Java implementation of Object Teams) does just that: You define teams and roles and then apply those to existing Java code. Let’s take the Observer pattern (you know that design patterns are workarounds for flaws in the language’s design, yes?).

The problem with this pattern is that you can’t apply it retroactively. You must modify the involved classes to support the pattern even if they couldn’t care less. That leads to a lot of problems. Classes which don’t need it must still allocate resources for it. It clutters the API. You can’t add it to classes which don’t support it. If a class only allows you to observe some behavior, you can’t change that.

OT/J fixes all that. The OTExample Observer shows three classes which could make use of the Observer pattern but don’t. Instead, the pattern is retrofitted in all the places where it’s necessary. This allows for many optimizations. For example, you can create a single store for all your observers (instead of one per instance). The API isn’t cluttered. You can observe almost any change.


%d bloggers like this: