Minimize Part 3: Working with Assemblies

Class Loader's Load Assemblies

As we saw in Part 2 of our example, the primary outputs of the javac compiler are .NET assemblies. We also saw that the launcher was able to load the application's assemblies, along with the .NET runtime, and run the application on .NET. To do this, we have had to include class loaders in Ja.NET SE that are able to recognize and load assembly files with '.class' file extensions. The class loaders behave similiar to standard Java platform classloaders, but load assemblies instead of Java byte code formatted in '.class' files. Both the bootstrap and system class loaders in SE are able to read assemblies and define classes based on an assemblies' contents. If you're interested in learning more on how Ja.NET SE deals with assemblies, check out the Ja.NET SE and .NET assemblies write up.

Now, having one class per assembly is not always the most optimal way to package and run applications on .NET. One class per assembly does work fine when working with a smaller application with a small number of classes, but when you begin creating larger applications or libraries with many classes, you will most likely want to package them into a single unit; an assembly file. Doing this, is in many ways,  similar to packaging Java classes into a single .jar file using the jar utility on a standard Java platform. To do this with Ja.NET SE, we have provided a tool called bam, the Build Assembly Module tool.

Build Assembly Module (bam)

There are two ways you can use the bam tool to produce assemblies. The first is by invoking the tool directly on the command line. You do this by simply running 'bam.exe' at the command prompt.  The second way is by running it in combination with the Java compiler. To do this, you add the '-bam ' option to the invocation of the javac compiler.  

For example, if you wanted to use the command line tool to combine the 'MyProgram.class' and the 'HelloWorld.class' created by the javac compiler into a single assembly named 'MyProgram.dll', you would first compile the example and then simply enter 'bam cf MyProgram.dll MyProgram.class HelloWorld.class’.

C:\>REM Combine '.class' files into one assembly MyProgram.dll
C:\>javac MyProgram.java
C:\>bam cf MyProgram.dll MyProgram.class HelloWorld.class

If you wanted to do the same thing, but instead do it during the compilation step, you would simply invoke javac on the command line as you did before, but this time add the ‘-bam:MyProgram.dll’ option (e.g., 'javac -bam:MyProgram.dll MyProgram.java'.

C:\>REM Compile source into one assembly MyProgram.dll
C:\>javac -bam:MyProgram.dll MyProgram.java

In either case, you will have created a new merged assembly named 'MyProgram.dll' in your current directory, and it will contain both the 'MyProgram' and 'HelloWorld' classes.

After you have combined the classes into a single assembly, you can still run the application using the Java launcher much the way you did before. The main difference is that you would now include MyProgram.dll on the classpath of the launcher in a way similiar to how you would include a .jar file (e.g., 'java -cp MyProgram.dll MyProgram') . When you do this, the system class loader will search the MyProgram.dll assembly when it looks for the classes it needs.

C:\>REM Provide assembly on the class path
C:\>java -cp MyProgram.dll MyProgram

Additional Documentation

If you would like to learn more about the Ja.NET SE tools, such as the full list of available options for the javac compiler, the java launcher, or the bam tool, or if you would like a better understanding of how assemblies are used in Ja.NET, take a look at our tools documentation page. It will provide you with additional examples and more information than is provided here.

Next, let's look at how easy it is to incorporate Java into a C# based application.