Saturday, March 31, 2012

Confluence 3.x and com.atlassian.confluence.content.render.xhtml

com.atlassian.confluence.content.render.xhtml is a package from Confluence 4, responsible for rendering new XHTML macro. If you compile your plugin for Confluence 4 and your plugin has <xhtml-macro/>, then you will get an import of com.atlassian.confluence.content.render.xhtml in your MANIFEST.MF. Something like this:

com.atlassian.confluence.content.render.xhtml;version="0.0"

So far, so good. But what happens, if you try to install your plugin in confluence 3.x?


org.osgi.framework.BundleException: Unresolved constraint in bundle com.skype.confluence.skype-bth [72]: Unable to resolve 72.0: missing requirement [72.0] package; (&(package=com.atlassian.confluence.content.render.xhtml)(version>=0.0.0))


The reason is obvious, com.atlassian.confluence.content.render.xhtml is missing in confluence 3.x, but we are asking for it. Even though, we are not going to use it. We might have separate <macro/> definition, that does not need XHTML.

Solution is to tell Felix, that com.atlassian.confluence.content.render.xhtml is optional:



Friday, March 30, 2012

JNDI datasource in confluence plugin

It appears, that Confluence dev documentation completely lacks information, regarding accessing third party databases.

The only example I could find is the source of SQL Plugin. However, it seemed to be too low level and I would prefer to use Spring to handle it. Here comes my solution:



You can see here, that I'm using lazy look up with proxy interface. I had to do it, because otherwise look up happens when plugin is installed or activated and for some reason, JNDI datasource that I defined was not visible to that thread.

Unfortunately, OSGI bundle makes it a bit tricky, as some required classes will be missing and you have to instruct Felix to import them:

Wednesday, February 29, 2012

Populating Oracle v$session in Spring web app

Our project heavily relies on Oracle PL/SQL procedures. Those procedures are used by different applications and database developers always wanted to know two things:

1) Which application is calling the procedure
2) Who is currently logged into the application

After investigating the topic a bit, I've found OracleConnection.setEndToEndMetrics method in oracle JDBC driver. Using this method, you can populate some fields in v$session view, including v$session.client_identifier and v$session.module. In our case, logged in user goes to client_identifier and calling application to module.

There are already some samples of setting client identifier using this method, but I found most of them incomplete. Here comes another one:



You can see here, that we are using AOP to intercept javax.sql.DataSource.getConnection() methods and populate all connections with logged in user from Spring security SecurityContext. Module is just a constant.

Tuesday, December 20, 2011

Are static fields initialized before constructor is called?

I've encountered this while debugging one very strange issue in third party library. Decompiled code made this case even more interesting and not so obvious.

How do you think, what is the output for following program?



Output is:

null
2
1
2

Constructor is called before "staticField" is initialized.