10. Wrapping Scheme into our IDE (Library Wrappers)

Figure 39. embedding scheme as a library wrapper

embedding scheme as a library wrapper

So we have a working editor for Scheme files now. Now we want to be able to interpret and run that Scheme source code.

To do that we need to embed our favourite Scheme interpreter into our Scheme IDE. There are different Scheme interpreters that run on top of the JVM (JScheme, Kawa, Jaja, Skij and SISC, and possibly many others). I'll talk about the differences between these in a future entry (there's an outdated comparison in this MIT Thesis by Brian D. Carlstrom, with a description on how to embed Scheme into Java, in case you're interested in these topics).

I must admit I haven't used many of those: SISC is good enough for my needs (furthermore, I want to explore SISCweb in the future, to give web continuations a go). So let's see how to embed SISC into our Scheme IDE. Later on I may want to add different Scheme runtimes into the IDE, but let's keep it small at the moment.

To embed an external library into a NetBeans based application we must understand "Library Wrappers". So let's take a look at them first.

10.1. Library Wrappers

Library Wrappers are NetBeans modules that contain an external library.

Since Library Wrappers are NetBeans modules, you have a well defined Public API. As we'll see in a minute, when you define a Library Wrapper, the NetBeans IDE automatically builds a Public API that contains all classes in the library.

And you have versions, too. Your own versions, that you define when building your Library Wrapper. These "Library Wrapper versions" are independent of the library being wrapped (because these versions correspond to the wrapper, and not to the library).

Finally note that Library Wrappers are designed to contain libraries, and not projects. What I mean is that a library is something that rarely changes (projects change more often). That's why Library Wrappers do not work well if you change the library after building them. We'll also see later on how to handle these cases.

10.2. Getting started: wrapping SISC

Figure 40. File/New... Library Wrapper

File/New... Library Wrapper

So let's get started with Library Wrappers. Let's build a Library Wrapper around SISC.

10.2.1. Download SISC

Oh, well. Before building a Library Wrapper we need a library! So let's download SISC first, and extract the contents somewhere in our hard disk.

10.2.2. Create a new Library Wrapper

Figure 41. Selecting the jar files to wrap

Selecting the jar files to wrap

You build a Library Wrapper Module by selecting "File/New..." in the menu, and then selecting the "NetBeans Plug-In Modules" category and the "Library Wrapper Module Project" option (see Figure 40, “File/New... Library Wrapper”).

The next step asks us to select the library we want to wrap. Note that you can select multiple jar files and not just only one (I was confused by this when I first built a Library Wrapper), as can be seen Figure 41, “Selecting the jar files to wrap”).

You can also specify a license for the library. The SISC Scheme interpreter is released both under the Mozilla Public License 1.1 (quite similar to the CDDL) and under the GPL 2.0 license. SISC includes its license in the "COPYING" file, so just click the "Browse..." button and select it.

[Note]Select all jar files in your Library Wrapper

Remember that you can select multiple jar files when building a library wrapper module.

The third step in the wizard allows you to enter the project name and location. Remember to add the module to the Scheme module suite we're building.

Figure 42. Setting the codename

Setting the codename

The fourth and last step in the wizard asks for a code base name for the module. As usual this is a unique name for the module. I follow a convention similar to package names for this name. I enter my domain name (net.antonioshome) and then a name for the application I'm building (scheme) and finally a name for the module (sisc), so I have "net.antonioshome.scheme.sisc" as my code base name.

See Figure 42, “Setting the codename” for details.

10.2.3. Library Public APIs

Now that we have built our Library Wrapper module let's go take a look at it. The very first you may notice is that NetBeans has automagically generated a Public API for our library. You can take a look at this public API by right-clicking on the Library Module and selecting the "Properties" menu item in the popup menu. If you then select the "API Versioning" node you should see something similar to Figure 43, “The Public API of our library”.

The fact is that, NetBeans scans all the jar files in the library and detects the Java packages there, and then marks all of them as public.

Figure 43. The Public API of our library

The Public API of our library

This opens new possibilities to us. We can select a small set of packages in the library, and mark only those as public, so that the rest of modules in our application can only interact with those packages.

We could, for instance, mark the "sisc.boot" package as private, so that no other modules could access the classes under "sisc.boot".

This feature has deep consequences in the maintainability of our applications, allowing us to manage dependencies between libraries and modules in a much more powerful way. That's one of the main reasons why I like the NetBeans Platform as a way to build complex applications: you can impose big restrictions on dependencies, which is of main importance when building applications with different development teams, for instance.

So, to summarize: Library Wrappers allow us to define which parts of a library are public, giving us a powerful tool to handle dependencies in our applications.

10.2.4. Managing change

So what happens if we want to change (or update) the jar files in our library? The NetBeans IDE doesn't currently support this operation (well, after all libraries are not expected to change, right?), so we'll have to do it ourselves (or wait until this issue is solved).

I can think of different ways to have our jar files updated. Let's see them:

The first way is, of course, to delete the Library Wrapper module and rebuild it with the same code base name. This is somewhat tedious, but it's probably the safest way to do it.

Figure 44. Jar file location

Jar file location

If you haven't changed the packages in the jar files you can try to rewrite the old ones. When you build the Library Wrapper, NetBeans stores the jar files under the "releases/modules/ext" directory (see Figure 44, “Jar file location”). Of course you can modify the "build.xml" file to have the files automatically overwritten for you.

Finally you may want to use the versions in your Library Wrapper and create different LibraryWrappers, with different versions each, and make a dependency with your preferred version.

10.2.5. Beloved warnings!

After creating the Library Wrapper for SISC you may want, of course, to build it.

And if you do so you'll notice... warnings! (see Figure 45, “Beloved warnings!”)

Figure 45. Beloved warnings!

Beloved warnings!

How is that possible? How is it possible that we have warnings after just creating our Library Wrapper?

Well, the fact is that NetBeans is doing quite interesting things when building our module. It's "verifying the class linkage". What this actually means is that NetBeans scans the class files of our library and looks for unresolved dependencies with other libraries. This is cool because it allows you to quickly see what other libraries you may need.

In our case, NetBeans is informing us that the SISC libraries (well, exactly the sisc.tests.TestR5RS, sisc.tests.UtilTest and sisc.tests.AllTests) require the JUnit library.

We know that those libraries are only required to build SISC unit tests (but are not required to run SISC), so we may dismiss those warnings.

I think this feature of Library Wrappers is very interesting. The fact is that I find it difficult to handle dependencies myself. You know, people tend to use lots of libraries in their software, and it's difficult to see if you have all the required jar files or not. Having NetBeans make that check for you saves lots of time!

[Note]Beloved warnings

NetBeans scans the class files seeking for unresolved dependencies. This allows you to quickly see if you need some extra libraries or not, and helps you solve those problems quickly.

10.2.6. Native librariers

I haven't yet added native libraries to a NetBeans based application, but it seems this is somewhat tricky. I will have to investigate this thread in the future (well, just in case I ever use a native library! ;-) ).

If you're delivering native libraries with JNLP you may be interested in reading this interesting blog entry by Alan Burlinson about using NetBeans, native libraries, JNLP and the new compression format (pack200) with an Apache server (I also have another entry on using JNLP and pack200 with Apache).

10.2.7. Further reading

The NetBeans Developer FAQ has an interesting entry explaining when to use Library Wrapper (you can also bundle your jars inside your module). This is a good read if you're interested in using Library Wrappers in your applications.

In the next section we'll start invoking SISC and running our first Scheme code. Keep tuned for that, we'll see how to asynchronously invoke things... without SwingWorkers!

blog comments powered by Disqus