3

[Clarification] Forgive the lack of clarity in the initial description. Allow me to re-phrase the question.

Does there exist a way to perform runtime compilation using the javax.tools API, usable in OSGi (again stressing runtime), which understands a bundle's dependencies and security constraints?

[update] Please see https://github.com/rotty3000/phidias

It's a well formed OSGi bundle. The readme provides all the details of the very tiny 4 class API (8k module).

Ray
  • 1,324
  • 10
  • 18

4 Answers4

0

In order to get from a set of package imports and exports to a list of bundles which can be used for compilation, you'll need some sort of repository of candidate bundles, and a provisioner to work out which bundles best provide which packages. If you're using 'Require-Bundle' (not a best practice), you'll know the bundle names, but not necessarily the versions, so some provisioning is still required.

For example, in Eclipse PDE, the target platform is used as the basic repository for compilation. You can also do more sophisticated things like using Eclipse's p2 provisioning to provision your target platform, so you can use an external p2 repository as your repository instead of setting one up yourself. For command line builds, Tycho allows Maven builds to use the same sort of mechanisms for resolving the classpath as Eclipse itself uses.

An alternative approach is to list your 'classpath' as Maven dependencies, and let the maven bundle plugin (based on bnd) generate your manifest for you.

If you can't take advantage of existing command line tools because you're compiling programatically (it's not entirely clear from your question what problem you're trying to solve), your best best is probably to take advantage of an existing provisioning technology, like OBR, Eclipse p2, or Apache Ace to work out the bundles which should be on the class path for compilation.

Community
  • 1
  • 1
Holly Cummins
  • 10,767
  • 3
  • 23
  • 25
  • Thank you, however the assumption here was runtime which I admin was not clear in the initial question. – Ray Sep 16 '12 at 02:18
0

This is exactly what we do in bndtools ... If I had a bit of time I would add a compiler to bnd so it could also do this.

Peter Kriens
  • 15,196
  • 1
  • 37
  • 55
  • Again, as stated above, the assumption was runtime. However, this might be your lucky day as I think I have solve the problem. (See my upcoming answer.) – Ray Sep 16 '12 at 02:19
0

I've so far found that the real answer is "No there is not!"

The predominant runtime compilation scenario currently for java is JSP compilation. An investigation of the app servers I've had the occasion to review use one of these methods:

  • invocation of javac (through a system call)
  • use of ecj/jdt
  • uses javax.tools in a non-OSGi aware way

All of these approaches are based on collecting the available classpath by directly introspecting jars or classes in the file system.

None of the current approaches are aware of OSGi characteristics like the dynamic nature of the environment or the underlying restrictions imposed of the framework itself.

Ray
  • 1,324
  • 10
  • 18
  • Since I couldn't find what I was looking for, I've implemented a prototype which is completely OSGi aware. I'm going to see if any of the OSGi based projects would be willing to accept the contribution. – Ray Sep 16 '12 at 02:33
0

Sure you can, you just have to write a custom JavaFileManager which will supply the right classes to compile against to the JavaCompiler.

For example you can write one that gets its classes from an OSGi runtime. If you don't mind having a dependency from your compiler bundle to the libraries you need then it's pretty easy, otherwise you can use the wiring api to look to other bundles as well. (OSGi 4.3+ only). If you intercept which packages it requests while compiling you can generate Package-Import statements so you can generate a bundle.

I made a rough GitHub example a few months back:

https://github.com/flyaruu/test-dynamic-compiler

There were some issues (I couldn't get the Eclipse ecj compiler to work for example, I didn't look into bundle security at all, and due to the dynamic nature of OSGi you have to listen to bundle changes to update your compilation path.), but it works fine.

Frank Lee
  • 2,728
  • 19
  • 30
  • I've created an implementation which is fully dynamic and so you don't have to do any alteration of the classpath by hand or even with extrenuous code before hand. The BundleJavaManager takes care of knowing what is available automatically at runtime using the wiring API. You can also, if you want, or need, pass the traditional classpath if you need to access classes not directly installed in the runtime. (see links to phidias above) – Ray Sep 17 '12 at 01:15