I’ve posted about Scar before, so I’ll just give a quick summary. I hate Ant, XML programming is an abomination. I hate Maven, though I like the idea of an artifact repo but only for large projects with many dependencies. I want to build my own stuff without any nonsense. If Java could be used to build Java projects, naturally every Java programmer wouldn’t have any trouble. Scar is a collection of utilities that make it easier to do build related tasks using Java code.
http://code.google.com/p/scar/
That out of the way, I recently reorganized Scar. Here are the parts:
- The Scar class has static utility methods. They usually take some strings that point to files or directories and do something useful, like zip, unzip, compile source files, etc.
- The Paths class comes from my wildcard project. It uses globs (asterisks) or regex to collect file paths. The globs are very efficient, eg they don’t traverse into directories that can’t potentially match the glob pattern. This makes collecting paths to compile, zip, etc very easy.
- The Project class is intended to be a project descriptor. It is loaded from a YAML document and has a project directory. It has utility methods to get paths relative to the project directory and get data out of the YAML in various formats, such as strings, floats, and Paths relative to the project directory. Nothing is assumed about how you’ll use the Project class, it is only a data container with utility methods. You don’t have to even use it at all.
- The Build class takes a Project instance and does Java build tasks on it. It uses conventions for the data in the Project, eg it expects the YAML to have “name” for projcet name, “source” to list Java source files, “dependencies” to list paths to dependency projects, etc. It can compile and JAR a project and all dependent projects just by reading the Project file. You don’t have to use this at all, you can just make use of Scar utility methods and go your own route to build your project.
Previously, the Scar class had a bunch of stuff that is now in the Build class. Now, the Scar class isn’t cluttered with that optional stuff, and all the utilities like compiling, LZMAing, etc can be used by people who don’t want to bother with the Build stuff.
So, what are some examples for common tasks already!? I’m getting there! First, it is easy enough to get a directory that contains your application as a bunch of JARs. In Eclipse you can right click, export, and click runnable JAR. Now that you have that, here is how you can run your app for JWS, just create a new class with a main method and this code:
String keystore = "keystore";
String alias = "alias";
String password = "password";
String company = "Company";
String title = "Title";
String inputDir = "C:/example/jars";
String outputDir = "C:/example/jws";
Scar.keystore(keystore, alias, password, company, title);
Scar.jws(inputDir, outputDir, true, keystore, alias, password);
Scar.jnlp(outputDir, "com.example.MainClass", "name-of-jar-with-mainclass.jar",
"http://example.com/applet/run.jnlp", company, title, "splash.jpg");
This generates a keystore file (if it doesn’t exist), generates a JNLP file, and signs all your JARs to work with JWS. Put your JARs and the JNLP file on the internet and you are done!
Specifically, for each JAR it removes any previous signing, does pack200 and unpack200 to normalize the JAR, signs it with your keystore, does pack200, and then GZIP. It skips the last two steps for JARs containing “native”. When generating the JNLP, it puts JARs containing “native” in the appropriate native section, based on if they contain “win”, “mac”, “linux”, or “solaris”.
Here’s another example, this time to package an LWJGL applet:
Scar.keystore(keystore, alias, password, company, title);
Scar.lwjglApplet(inputDir, outputDir, keystore, alias, password);
Scar.lwjglAppletHtml(outputDir, "com.example.MainClass");
This generates a keystore file (if it doesn’t exist), generates an HTML file, and signs all your JARs to work as an LWJGL applet. Put your JARs and the HTML file on the internet and you are done!
Specifically, for each JAR it removes any previous signing, does pack200 and unpack200 to normalize the JAR, signs it with your keystore, does pack200, and then LZMA. It skips the LZMA and packing for the LWJGL JARs “lwjgl_util_applet.jar” and “lzma.jar”. It skips the pack200 for JARs containing “native”. When generating the HTML, it puts JARs containing “native” in the appropriate native section, based on if they contain “win”, “mac”, “linux”, or “solaris”.
Scar can do other useful stuff, like “one JAR” or FTP your files, but I think the above is particularily relevant to JGO. If you give it a try, please run Scar from source as I just refactored some things tonight and haven’t released an up to date JAR. If someone could do some testing that would be great.