Information Technologies • 1:14:18
Java is one of the most popular ways to create cross-platform applications and is right at home on Mac OS X. Hear Apple's Java engineers talk about the practical aspects of making your Java application shine on the Mac. Learn about the unique tools and techniques for each stage of the Java development cycle on Mac OS X.
Speakers: Matt Drance, Victor Hernandez
Unlisted on Apple Developer site
Transcript
This transcript has potential transcription errors. We are working on an improved version.
Welcome to bring your job applications to Mac OS X Leopard. I'm Matt Drantz and the sharing technology's evangelists cover a bunch of technologies on Mac OS X but Java is among them and some of you might know me as Java DTS over the years. So I've got a long and storied history with Java on Mac OS X going all the way back to 10.0, actually going back to classic. So this is still a topic that's near and dear to my heart. And no there is no caring technology's evangelists.
This is the second step in the Java world tour that we're giving you this week at WWDC. This morning you heard Tom give you kind of the ten thousand foot view of what we're doing with Java on the Mac and what's going on right now, what's coming in Leopard and beyond. For the next hour we're going to talk about the basic fundamental things that you need to know if you're coming to the Mac, if you're just starting to look at Java on the Mac, and even if you're somebody who's already working with Java on the Mac.
You know, it's still a useful review for the things that you really need to just kind of have wired in your brain for you to do your daily work. And tomorrow of course we're going to have all the stuff that allows you to go the extra mile and do some really special things kind of like what you saw in this morning's demos.
So if nothing else, if you fall asleep, if you walk out early, any of the above, what I really want you guys to take home is that Mac OS X really is a great platform for you to do your job of development on. Whether you're a cross platform developer or somebody who's got newer existing work that you need to maintain compatibility in and portability with. Maybe you've just got a massive existing investment in Java that you need to carry forward and the Mac is included in that picture. Or if it just happens to be the language that you're most familiar with and you happen to have a Mac in your lap.
All of those people, all those things apply perfectly and Java's well at home and it has a healthy present and healthy future here. And while you're here we've got a thing we used to say back in two thousand one was come for the job stay for the Cocoa.
We've got a lot of other things available both you know, Mac features, things like Cocoa and dashboard, the stuff like core animation you're seeing here on the platform, as well as plenty of open standards and stuff like PHP, Rubi on Rails. So you know, Java is well at home and we've got plenty of other things to offer. So we hope you look all around the system and continue to be productive with your technology of choice.
So the audience here, who are we talking to? Well so forgive me for generalizing a little bit but you know you saw this, this morning, there's a couple of general audiences and general application spaces in terms of Java development. The first of course is the server command line, headless realm. Whether it's you know, big enterprise deployments or just kind of the unsung hero's sorts of things that you have running in the background during your daily life or your daily work environment.
And then beyond that we start to head towards more user-centric, publicly facing things. Things like applets. Just a small bundle of code that you want to deploy across a network to any number of anonymous clients, you don't care who they are, you don't care what they're running, the stuff should just work. Web Start is another example of that. You know, more modern version of what applets were originally solving for you. And then of course all the way at the other end of the spectrum we have the full blown proper desktop application.
So as it turns out we could probably generalize even a little bit more and just kind of break this up between the client and the server. Whether the things you need to know when you're doing headless server command line base development versus what you need to know when you're doing desktop development.
And despite those two things being in stark contrast to each other, they are similar in the sense that when you're on a certain target platform there are things you want to be mindful of and things that you really need to know going in and moving forward. So that's what we're going to cover today.
We're going to start with the very basics of Java on Mac OS X, the things you absolutely need to know, the things you're not going to get anywhere without. We'll talk about the transition to 64-bit, following up on the news that you heard this morning at the discover Java session.
And then we'll go into the Java desktop experience and kind of what that means to you as a cross platform desktop developer or programmer. And we'll also talk about what you do in terms of the routine of building your code and you know, how you can work in some of these platform sensitivities to your normal routine. So let's start with the basics.
The basics are pretty simple, they're pretty basic. We have the Java VM framework, which you know, is like Tom said this morning: Java's preinstalled on every copy of Mac OS X going all the way back to 10.0. We've got multiple version support inside that framework and there are a number of things you want to know if you're going to go ahead and work with this installation on the Mac. So let's talk about the framework.
Again it's preinstalled on every system, you don't ever have to worry about whether or not there is a Java VM on the system. It's always there. Not only is it there, or is it in place, but the JDK is there as well and it's on the path. You don't need to worry about tweaking the environment or anything like that. You open up terminal, you type Java or Java C, Java H, and it's just there.
So this is really, Java is and always has been an integral part of the OS. And you see here in this screen shot here, you see a bunch of .frameworks. For those of you who are new to the platform or not necessarily familiar with the native things that are going on here, our framework is really just a bundle, it's just a folder with some specific metadata and some folder organization and basically in order to kind of illustrate this fact, we've bundled the entire JDK inside a framework. And this gives us a number of not only pre-installation, but a number of benefits like multiple version support.
And echoing what you heard this morning, 1.5 remains the preferred recommended version on Leopard. So more on these multiple versions. If you were to dive a little deep, and feel free to follow along while I talk here, if you were to dive into the framework inside the finder, you'd see a versions directory. And you see a bunch of numbers here. So you notice that a bunch of these are actually sim links. And the real take away here is that for any given major version we only have a single installation.
So you see here there's a 1.4, a 1.4.1, and those are actually both sim links to 1.4.2 which is usually more often than not the absolute most latest available JDK on the system. So for example in Leopard, if you've gone and downloaded our DP seven for 1.6 at the current time you would have 1.4.2_14, 1.5.0_11 and 1.6.0_01. Similarly you see the abstract 1.5 sim link pointing to what is currently the most current version 1.5 oh.
Now again reiterating from this morning, you need to remember that 1.4 is being deprecated in Leopard. So deprecation means a lot of things to a lot of people. But this is a developer's conference, you guys are developers and you're looking to work with this language with this framework moving forward so really as far as you're concerned, you should act as if 1.4 is already gone. Because it's not going to be around for much longer. It will be there on Leopard as long as Leopard is around, but you should assume that no further. So 1.5 remains the preferred version for multiple architecture support, for multiple OS support, for maximum penetration basically.
So how do you deal with all these multiple JDK versions? Well you can set your IDE preferences. There's a bunch of IDEs out there and most of these tools have been written custom, not custom, but written to work properly on Mac OS X. So you tell it which version you want, the id takes care of it for you. That of course includes Xcode.
You can also use the Java preferences.app. And for those of you who weren't at the session this morning, the Java Preferences application now also controls the command line in Leopard. So it's no longer just for double clickables or for Web Start and applets, it controls every aspect of Java.
Now if you want rapid access to these, do some testing, the main recommendation we have for your guys is to use the Alias command and use it in your terminal profiles on a per user basis. This is really the most flexible and the easiest way to go ahead and do it.
And if you've got make file or shell script, etcetera, it depends on something like a Java home variable, you can go ahead and set that accordingly. And basically that's going to be a direct path into the framework. System library frameworks, JavaVM.framework, versions, whichever version you wish, and then home. And now I'd like to give you a little quick tour of what all this looks like. So go to demo please.
Ah there we are. So let's open up the terminal and like I said, there's no path shenanigan's or anything like that. Everything just works. So I'm going to go ahead and just type Java -version and like I said 1.5 is the preferred and it's 1.5.0_11. So maybe I want to go ahead and do some testing with 1.4.
I'm a little slow on the uptake, I have not downloaded the 1.6 preview yet. But so Java preferences is located in the utilities folder under Java. But I'm just going to go ahead and launch it from Spotlight because I'm lazy. And you can see down here we have Java application runtime settings. Right now J2SE 5.0 and here you would see all of the installed versions. So if I had 1.6 installed you would see JavaSE 6.0 up here.
So I'm just going to go ahead and drag 1.4 two to the top and click save. And sure enough, I type Java -version. Now we have 1.4.2_14. So simple as that. Now let's take a look at these, let's take a look at the framework on the file system for a second just to show you what's going on here.
Again system library frameworks, JavaVM.framework and we have this versions directory. And again this is very similar to the slide you just saw. We've got a lot of sim links pointing to whatever the most current thing is. So if you happen to be doing something that requires 1.4 or 1.5, try to use the most abstract thing like 1.4 and 1.5.
Not, nothing more specific than that. Because these sim links are generally always there and they will always point to the right thing. And from there, you can see that we've just got a replication of all the command line tools for each individual version. So here's the 1.5, I go over to 1.4, it's got the same folder structure, same executables.
So basically all this stuff is in place and this is all usable exactly where it sits. And so where it starts to get interesting now is, especially in an automated testing situation, well maybe I, you know, this is a manual process using this Java preferences application. So what can we do here? Well I can go ahead and just create a profile for my user account, for terminal and I can do, I can use the alias command, I can go alias Java 1.4 equals and I'm hoping all of you have experimented with drag and drop in terminal, but basically I'm just going to go get the Java executable right here, change it, no this is the same login session. So I'll create a new tab real quick.
And now I've got this Java 1.4 executable basically. A little dash there, and right. So now we have you know, for all intensive purposes, an executable using 1.4. Let's go back here, let's do it again for 1.5, commands, Java and of course you do this for Java C, everything else, whatever you want it to do. So quit out of that, another new session, and there we are. So, so in the matter of seconds, we've got multiple version support ready to go, ready to automate using shell scripts, whatever you want.
So very straightforward, very simple and I want to point this out because depending on who you talk to, which mailing list you subscribe to, there's a lot of talk about this current JDK and changing sim links and stuff like that. Please don't do that. The main reason there is not only because you don't own the framework but because changing sim links at the system level affects all users of the system. This is not only easy, it's non-disruptive and it also only affects you. So don't listen to those people. Listen to me. I'll take good care of you. Back to slides please.
So that was a quick whirlwind tour of just you know, getting your bearings on the system. So once we get into the runtime, once we start actually executing code and maybe you're doing some special K stuff or maybe you just, for whatever reason, want to know that you're running on Mac OS X. Very simple stuff using standard J2SE APIs.
This is probably something that many of you have done on this platform or on other ones. But here's the recommended way of doing it. Go ahead and get the os.name system properties, slam it to lower case so you don't have to worry about case sensitivity and check that it begins with Mac OS X. I don't believe we're changing the name of the product anytime soon. So it's a pretty good guess. And this code actually is not Mac specific at all, this is just some simple code that you might be doing to try to figure out which major version you're doing.
So you know I have this big long string that says 1.5.0_11 - something or other. So this is a way to just kind of trim off the first couple of characters there and see which major JDK you're using. And more specific to the Mac is, and I apologize for not pointing this out directly in terminal, but we have a unique version string at the end of what you're used to seeing. So like I said before let's say there's 1.4.2_11.
Or is it twelve, fourteen, where are we now? Fourteen? Alright. So that's the standard JDK version but because we don't operate on the same schedule as Sun we may very well put out two releases in the 1.4.2_14 timeframe. So we add a little string at the end to differentiate our own releases.
And that's something that you can count on if it just so happens that there's something, a feature you've been waiting for, a bug you've been waiting to be fixed and work around, apply a work around on, this is the way to go ahead and do that. Basically sniff out that hyphen at the end and find out the number.
And this number is fairly deterministic so you can go ahead and extrapolate on it. But mainly you would want to check for the exact string just so you know what release you're on. And we have a technical note, it's TN 2110 up on developer.apple.com that has a matrix of all of these version strings dating all the way back to Mac OS X 10.0.
2 1 1 0. So on the topic of native libraries, those of you, maybe you're building JNI code, maybe you're just bringing down some open source stuff, whether it be on the command line or on the desktop, it's the standard story, you would use the Java.library.path property to define where you're libraries are sitting.
And the naming convention here is lib<LoadedName>.JNIlib and the <LoadedName> would be the same string that you pass into your system load library call in your Java code. So very straight forward, the prefix and suffix are unique to Mac OS X. And of course you want to build these libraries as three way universal, meaning PowerPC, and Intel and 64-bit Intel as well. Got a lot of different machines out there now so you need to be mindful of all of them.
Speaking of 64-bit, I'd like to bring Victor Hernandez from the VM team up to talk to you about that transition. Victor?
( Applause )
Well thank you Matt. I'm Victor Hernandez and I'm one of the engineers who brings the virtual machine to you for running on Mac OS X.
So about an hour ago I decided to drink some coffee even though I regularly don't because you can't really trust a VM engineer who works on Java and doesn't drink java. But too there's another reason as well. 64-bit JVMs are going to enable a whole new set of amped up applications and it's really not just the new architecture. But it's a new way of being able to write applications that you never felt you were able to write before. So let's jump into the technology.
You've heard a lot about 64-bit support in Leopard. Most of our machines that we're selling now are able to run 64-bit applications. And Leopard has been updated so that most of the frameworks and almost all of the tools including Java have been updated for 64-bit. We've included a 64-bit JVM ind the J2SE 5.0 implementation in Mac OS X Leopard. And we expect to continue providing 64-bit JVM support in all the future versions of Java.
So what does 64-bit mean to you as a Java developer? Well 64-bit in an application just means that the pointer size has gone from 32-bit up to 64-bit. That's it. What does Java care about that Well the key thing is that Java as a language has never exposed pointers or pointer size. Your application doesn't need to know and actually it's kind of hard to figure it out. And that's really powerful. It's the job of the virtual machine to do this all under the covers.
And your application is able to run on a 64-bit JVM without having to change any Java source and also without having to recompile it all. Which means the transition for you to 64-bit JVM is going to be really, really easy to do and it's just going to be really painless and it's going to be pretty awesome. You're going to see how we're enabling this so that you can actually switch into this without much work at all.
So now that you know that it's really easy to do, what does it actually enable Well there's two main things that it let's you do. First of all, it lets you have a larger Java heap size. In the current 32-bit world, t2hat Java heap has had a maximum limit of 2GB. A lot of you have been telling us that's too little and we're perfectly aware of that.
Let's say this is 2GB. How big is the new Java heap size? Well it's not, I can't even point to the largest amount because it's really, really that much bigger. The key thing to note is that it's definitely more, it can definitely be larger than the amount of actual physical memory you have in your system.
And so you're actually going to be able to take full advantage of all that memory you've been buying for your machine directly from your Java application. There's another really important thing that you're going to get with 64-bit JVM and that's actually performance changes including performance improvements in your application.
Okay so I've said that this isn't just a new architecture, this is actually an architecture that lets you rethink how you've approached your applications. And that's really, really true. Anytime that you've had to change the architecture of your application to say oh no I can't do that because it will use too much memory.
Well undo all of that experience, undo all of that negative learning and just say okay what if I had all that memory what could I do now? The key thing is not only do you have a large Java heap, but also if you've been accessing a lot of memory outside of the Java heap using new IO buffers, those can also be much larger than they were before.
And this allows a lot of new, this allows applications to do a lot of new things. First of all anything processing large data sets can suddenly process even larger data sets. Things like gene sequencing or image files, the files that they're reading off of the disk can now be really big and actually live all in one piece in memory.
And also applications like scientific visualization and simulation. These are applications that generate a ton of data during their runtime. They might start off with a small set of data but then they iterate, they run all these algorithms and it just grows, and grows, and grows and grows. And then it might actually spit out just a small amount of data from the conclusions. Now these applications are enabled. So whether it be that you're writing, you're reading big things off of the disk or you're actually generating a lot of data, both of those styles of applications can now be a lot more powerful.
Also on the enterprise side, have you ever wanted to cache your whole database in memory? Well now it's actually possible. And that's really, really big. You're going to reduce your transaction the latency for each of your transactions and just going to be that much more powerful. I mean, this is just an unlimited set of the things that I can think of. But I'm really excited to see what's going to be coming out of the next generation of applications.
Okay. So I've explained how you can go about, you know, amping up your application. Or if you're current application has memory limits now you can you know, undo those limits. Well great those two situations, it's pretty obvious and it's pretty clear why you would want to move to 64-bit JVM.
But what about the rest of you that are just, my application runs fine in a 32-bit. When am I going to adopt this technology? Well there's one thing that I want you to take away from my talk today and that's the fact that the time is now. There's really no reason not to use this technology as soon as you can. Which is going to be with Mac OS X Leopard. And I'm going to go into a few more motivating slides just to explain the reasons behind that.
So for service I deployments it's really straight forward, for desktop jobs it's the same thing, your application's going to look the same all the frameworks are going to be available to you that you're currently used to using from your pure job application and also it's going to be a little bit faster as you'll see.
Okay. So you need to know about four characteristics of your performance that are going to be changing as you move to 64-bit JVM. d First of all how fast is your application going to be? Secondly is it going to use more memory? Third how much more time is going to be spent in garbage collection? And fourth, is your launch time going to change for your application? Alright first of all, speed.
For a lot of applications the speed of your application is dictated by how fast your hottest methods are. That's the whole design of the hot spot Java virtual machine that we ship with Mac OS X. We take your hottest methods and we compile them down to native machine instructions.
If we do a really good job of that, it's going to be fast. If we don't do that, it's going to be slow. Well the key thing is that we are actually able to generate faster and better implementations of your methods and native instructions on the 64-bit version dof Intel than on the 32-bit version of Intel. Why? Because there's more registers available. More registers means that we can actually cache more of your variables in the code we generate instead of having to write your variable to memory and read it back.
This is going to be faster and we've already seen improvements that show that this is definitely the case with the SciMark, benchmark. The SciMark Benchmark doesn't spend much time in IO, isn't spending a lot of time or any time reading and writing from sockets. It's really just raw computation and just hot methods.
As you can see on all parts of the benchmark, we're already doing much better when running with the 64-bit Java virtual machine in Leopard. And this is just the beginning. I mean, currently the number's 39%. 9 I'm hoping that you guys are possibly salivating right now like oh cool I can get all that extra performance for free.
Alright, the second thing you need to know about when it comes to the different performance characteristics for your application with the 64-bit VM is memdory. Your application is going to use more memory. That's because every reference to one of your job objects you have is twice as large. It was like this now it's twice as big.
That's just the reality of 64-bits. But that's actually, the way you're currently approaching memory usage in the 32-bit world, 2 is exactly what you just need to continue doing in the 64-bit world. Don't use any more memory than you have to. Measure different Java heap sizes, make sure you're not encountering out of memory errors, and that's it. Make sure that you're not causing other applications on the system to page out or your own application.
There is a really easy way to make your own application to page out. If you actually ask for a Java heap size that's larger than the actual amount of physical memory you have, you're going to end up paging a lot because we scan that whole heap during garbage collection. And you should stay away from that. Possibly even have dynamic code that detects how much memory a particular deployment has so that it modifies the heap size accordingly.
And there's two things I also need to point out with memory usage on the 64-bit. First of all even though you can have a larger heap you can still end up running into out of memory error for the same reason as before. A leak. A leak is still going to fill up the whole heap. It just might take a bit longer. Also a lot of the applications, especially applications that aren't under your control, that are Java apps, have hard coded values for the different heap size parameters.
We've seen this under Eclipse, we've seen this with Idea, basically if you just move it to 64-bit JVM it will hit an out of memory because it doesn't fit in that space and you actually just need to increase it to something slightly bigger. So keep that in mind when you're trying out third party applications under the new 64-bit JVM which you're going to be doing because you're going to see how easy it is to do.
Alright the third topic that I want to talk about is garbage collection. If you're already using a larger Java heap it's actually going to take longer to scan all of that. That is if you continue using the current GC algorithm. But that's no reason to fret because we've been shipping since Java 1.4 different garbage collection algorithms that actually are to and specifically for this scenario.
All of the 64-bit Intel machines have multiple cores. Why don't we use the extra processing power to do some asynchronous or parallelized garbage collection. In fact there's a good chance that your pause time might even go down which is really, really awesome. The parallel GC algorithm basically parallelizes the synchronize GC algorithm and then there's also the concurrent mark sweep where you basically have a processor that's running during your application and then when it actually has to do some syncronist garbage collection it's actually reduced the amount of the work.
So it ends up being a lot fast as far as the pause time is concerned. So just take a look at these algorithms, measure with the application and you're going to see that you're not actually going to end up seeing much larger GC pauses for a reasonable sized job of heaps.
Alright and then the fourth issue is launch time. You're in a really interesting position because you can be an early adopter of the 64-bit technology of at one Leopard. In fact not only could your application be the first 64-bit app out there it could also be the first one that a user launches on the system.
Well that's really awesome and something to be proud of. There is a cost though of course. If you're the first app, you're going to be the first one to load in all of the 64-bit versions of the frameworks into memory. And that is going to reduce your launch time.
No reason to fret because there's going to be some quick adoption on the 64-bit technology and as more and more apps, basically as one more app before your app is run, you're not going to see that cost at all. And it's just going to get that much better.
Okay so now that you know like why you want to go about using the 64-bit VM you need to know how to do that. Well we're supporting it in J2SE 5.0 and Leopard, we're also supporting in the Java SE 6 preview and it runs on all of the 64-bit enabled Intel Mac computers.
And there's different rules on how to go about doing it from the command line in your application bundles and also in Web Start. So let's go into these. It's really easy, really, really easy. Command line you add one new parameter to the command line -d64. That's absolutely it.
Cool. Next application bundle, not much harder at all. It's got a little caveat that I've got to explain though. You basically add a new key to your info.plist JVMArchs. And what this key, it's value, what it says, is my application supports these architectures. If you're pure Java, right off the bat you can support them all.
If you have native code, you have to list the ones that you've actually built your libraries universal for. And the key thing here is that the order matters. So if you want to specify that if there is 64-bit available on an Intel machine, you actually do want to run in 64-bit. d You put x86_64 in front of i386 otherwise you reverse that.
And that's application bundles. The third one is Web Start, as easy as the command line. You just need to make sure -d64 gets passed to the Java VM created by Web Start and you do that in the J2SE version field of the JNLP file. Once again not very hard.
There might be more work for you if you have native libraries. First of all you have to make sure that your source can be ported over to 64-bits. You can learn more about that porting process at other 64-bit sessions here at WWDC. The key thing is that just like in previous years the transition from PowerPC to Intel meant that you had a 2-way universal binary. Now you're going to have a 3-way universal one and you just need to add one architecture to your make files, x86_64. And hopefully that won't be too hard to do either.
Okay so that's really all you need to know about it. I hope I've really motivated you to use the 64-bit VM because it is really going to be a painless process and we really hope that Java is one of the places where it gets adopted as soon as possible. So thank you. Back to Matt.
( Applause )
Thank you Victor. So that was the guts view, everything underneath. Let's talk a little bit about Java on the desktop. The thing to keep in mind is when you're deploying cross platform portable desktop applications yes you can write Java code and compile it and have it execute just about anywhere, write once run anywhere, that's what we've always said.
But when you get into a desktop experience there really is more to it than that and it's important that everybody realizes it. Today's operating systems, there are more of them than ever, there are more successful ones than ever and they've branched off in a bunch of different directions.
And users are more sophisticated and unfortunately pickier than they've ever been. And that jar file alone, that executable code is not necessarily enough to just kind of get you up to snuff, that one jar file is not going to really look right in place here and here and here and here.
So these are things that you know obviously you've saved yourself some time by writing a ton of core logic that's going to work everywhere. But if you really want to be successful alongside all of these other things it's going to be up to you to pay attention, not just on the Mac but in other places as well. What is it going to take to have users not, the goal basically is to have users not know what you've done.
Now somebody like my dad doesn't know what Java is he's not going to know whether something is written in Java but he may very well know that there's something not quite right with what he's looking at. So I can talk to you, I can't talk about the other ones but I can tell you what Mac users expect.
First of all they expect a self-contained relocated, relocatable application bundle. A double-clickable like you saw this morning with the Maple and Cineshot demos. They expect very easy installation. We're going to talk about that and you know, how easy it is for you to give that to them. And they, if nothing else, they expect a native menu bar. And we've gone out of our way over the years to make this as easy as possible for you to do.
So let's start with the first point. By now I'm sure you've seen the keynote, you've seen your build of Leopard, here's the new cover flow view of the finder. Now the thing to take home here is that just browsing around the hard drive is becoming immersive, more visual, more personal experience. So just think long and hard, if you've got something that you're thinking of deploying, is it really going to work out here? I've got iTunes, I've moved down to mail, and then I've just got this jar file hanging out here.
Does this jar file run on Mac OS X? Absolutely. Does this jar file look good right between mail and photo booth? Not exactly. So what can we do about that? Well fortunately it's very, very easy. Looking like you belong on Mac OS X is actually not that hard and it certainly is not a portability issue.
Creating one of these bundles is super simple. They're basically self contained folders that can be moved anywhere without affecting the execution of the application. They're relocatable and they're really easy for you to create. Even in an automated fashion. And there are a lot of people who get this. You saw Cineshot and Maple this morning who are doing really wonderful stuff. But even the tools.
I mean if there's anybody who can get away with kind of not going the extra mile to fit in it's developer tools, right? My audience is a bunch of developers they can go ahead and read, they can go to the wikies, whatever. But even these guys, even the Eclipses and NetBeans and the Ideas, they get it, they understand what it takes to just really at least look like you've downloaded the right thing. And so I'd like to thank them for doing that as well.
So let's talk about bundles and what, you know, what's the deal with these bundles. We'll talk about if you have a finished product that you're just bringing over to the platform, you don't need to make any code changes, the best way to do that. We'll go into kind of under the covers and see what these bundles are made of and what's specific to Java applications.
Then we'll talk about adapting your daily or regular build routine to kind of do this in a very simple fashion because we want you to do it, we want it to be easy for you. And then we'll talk about how you can go ahead and deploy those and get them into the hands of your users the best way, the way that they expect.
So to start, bundling a finished product. I've got my jar or jars in my resources, you know, I've got a shell script most likely, how do I make a bundle out of this? Well we have a great tool called Jar Bundler, it makes this very easy. You basically just drop everything into the resources tab.
We set your class path, we create the folder structure, we set all the relevant properties, you can add other things in like whatever you would normally specify in the command line, or in the environment, and we've even got a great tool called Icon Composer which can get you a little desktop icon in just a couple of seconds. And I'd like to show you that right now.
Okay. So I'd like to show you a little random app that I pulled down from SourceForge. It's called jscicalc and you know, I'm a developer so this is not too scary to me, but again my dad is not going to be a big fan of this. So I call my dad and I tell him okay you've got to type all this stuff in terminal.
Not the best idea, but let's go ahead and see what they've done. As it turns out they've gone ahead and at least put a manifest file in here so it's not going to be too bad, too hard to at least run it. Oh darn. What's happened here? Unsupported class version.
So this looks like it was built for one five and I happen to be running 1.4. I'm going have to hack the sim link again or change the preferences. Well no because we already did all that alias stuff in the previous demo. I can just go ahead and select Java 1.5.
And now it's running, beautiful. So here we are. And the first thing you notice is actually this looks pretty good. You know it's pure job application, we've got all the aqua look and feel pre-installed and one thing you should notice right away is we've actually got an application menu up here and at the moment it's using the fully qualified main class name for the application name.
We'll take care of that in a second. So we're getting there. The thing at least runs. But what we'd really like to do is give this a better desktop presence. All these other files here, we don't actually need. So I'm going to go ahead and launch Jar Bundler.
And very simple app, I'll go over here to the class path and files tab, drag this jar in, you see it when ahead and set the class path for me already? And the main class, I saw it up in the menu bar but you know, let's assume that I don't necessarily know what the main class is. Let's go ahead and just give the jar file over here too and it actually went ahead and scanned the entire jar to find classes with the main definition in it. Got a little quirk here, I need to actually put a dot in here.
And you can see that we do provide you with a generic job application icon but you know, we would want something a little more personal, personable. Let's see, there's actually a bunch of screenshots in here. So let's see what they've given us here, 256, multiple resolution, that unfortunately is not a screenshot from Mac OS X. It's totally unacceptable.
Let's go ahead and try to just get a good quick screen shot of our own here. For those of you who are new to the platform or perhaps not as much of a geek as others, command+shift+4 will let you go ahead and drag a region of the screen to take a screenshot. But if you actually hit the space bar, you can get a perfectly cropped screenshot of any given window, including the shadow. So quite nice, perfect. We're all ready to go now. I'll quit out of this again, hide this window.
So once we get this icon, it needs to be in the Mac OS X .icons format. So I'll open up Icon Composer, drag our new picture in and we go ahead and it went ahead and scaled down to all the sizes that we're going to need. Let me save this. calc.icons Great, we'll drag that in. Alright. And basically I click create application. And save it on the desktop, call it jscicalc.
It looks like we've got a little refresh issue and I was looking at this before. But basically it does work I can go ahead and launch it and there we are. So now we've got a double clickable application which should have an icon that we can see but not at the moment. You can see it here on the dock.
So there we go. If I wasn't talking so much this would've taken less than sixty seconds. Another thing to mention is you notice that now the name is proper up in the menu bar. I've gone ahead and because I specified that name that while we were creating the application bundle, Jar Bundler went ahead and did what was necessary to make that happen at runtime.
And that's pretty much it for this demo. Can we go back to slides please? So that's the kind of quick one off situation if you've got some stuff that's already built and you want to throw things all over the stage, Jar Bundler's the way to go. Very simple very straightforward.
So what's inside this bundle? What did we actually just create? So let's talk about the bundle structure, all the resources that are in there, the info plists as we call it for short, information property list is the officially sanctioned definition of the term. And the application stub which is the little piece of executable magic that makes this thing double-clickable.
So first of all the anatomy, what is this? We just saw this bundle get created on the desktop so if I right-click on this or control-click on it and I click show package contents it actually brings me right inside and it turns out this is just a folder.
It's just all that stuff that we dragged into Jar Bundler just gets thrown into a folder with a .app extension and then Mac OS X knows what to do with it. I'm of course paraphrasing a little bit but I'm about to go into more detail. So you start with this contents directory, you go in there and you start to see a bunch of other things. The first thing you see is the resources directory. Now again this is not Java specific this is standard Mac OS X 101 bundling stuff. If you open a Cocoa application you're going to see the same thing.
Inside the resources directory we have that icons file that we just created with Icon Composer but you don't know that because we just dragged it on top of jar bundler and then we also have this Java directory. Obviously being called Java this is some Java specific stuff. So what's in here? Well in this case a very simple application. It's just a jar file. But other things like images that you're going ahead and loading using the tool kit, JNI libraries, all that stuff is going to go here in the Java resources directory.
So again that's Contents/Resources/Java off the top of the bundle, JNI libs, jar files and also raw class directories if that's how you've been deploying things. You can throw those right in there, they're on the class path as well as the library path which is how the JNI libs can just be thrown in. So really that's another thing that bundling gets you. If you happen to be using a lot of JNI libraries, now you don't even need to worry about Java.library.path. Just throw it in the bundle and you're done.
So one level up at contents resources this is now again the generic Mac OS X stuff. Your icon file lives there as you saw, resolution independent images, this is very relevant in Leopard and we're going to be talking about that tomorrow. We've made that really very easy for you to adopt as Tom said this morning, we're going to go into detail tomorrow as to just how to take advantage of that.
As well as nib files. If you want to go ahead and get fancy and start adding some real Cocoa, loadable Cocoa UI in your application, maybe you just load it into a nib and do what's necessary to do that communication between the Cocoa and Java environments. You can just drop your nib in contents resources and then load it using your Cocoa code later. And we'll be taking a glance at that as well tomorrow in the advanced session.
Okay. So we've buried down into the Java area. Let's go back up to the contents directory. Next thing you see is this information property list file, info plist for short. You're going to hear people toss this around a lot. Victor already mentioned it in terms of specifying your preferred architectures for 32, 64.
So what is this plist file? Well it has a lot of typical properties for any Mac OS X operation, like the unique bundle identifier which is used by anything from parental controls to installers to document identification. The display name, in other words the name that appears up there in the application and you notice that, that changed between running it as a jar and running it as a bundle.
That was, that information, that name was stored in the info plist file as well as document types. You remember Pritique this morning double-clicked on a Maple document and that opened up right away in Maple. So there's some Java code that you need to write to make that work on the runtime side but on the finder side on the system side, it's as simple as just adding the document types in you info plist file. I've also got Java information there. All the standard stuff you would normally use outside of a bundle like class path, main argument system properties, and the preferred version.
And we typically recommend you use the + or * modifiers when you're specifying. The key is called JVM version and let's say you do a 1.4 or a 1.4+, a 1.4* and basically that gets you some insurance in case when we say deprecated something, or altogether remove it, this ensures that whatever version you've requested you'll just kind of automatically be moved forward to the next version. Perfect example is 1.3 which is no longer on Leopard. Somebody, any bundle out there that has 1.3+ as its preferred JVM version in the bundle is not going to have any problems. We're just going to use whatever is the latest on the system.
So more concrete examples of what this plist means and how it translates to what you would normally do in Java. So up here you see I've got a class path variable and I've got a main class and an argument to the main method. All this stuff lives down in the Java dictionary in the plist file. So you can see we have a class path, property, we've got main class, as well as any arguments. And most of these things are strings but you notice the arguments is done in array.
And for those of you who haven't used property list editor, you can go ahead and just very visually just click new sibling and have these new entries. This is actually an XML file underneath, you're free to edit yourself. But property list editor is a nice abstract way of managing this. You'll notice also the JVM version key that's here that's specified 1.4+.
So another example would be replacing system properties, the kind of stuff that you would put in a -d at the command line. So this stuff, we also have a properties dictionary, and this is a dictionary because it's going to support multiple versions. Who knows how many -d arguments you've got there on the command line. So in this case we go ahead and just take the key and the value and map them up into the dictionary.
So non standard VM options, the -x type stuff that you tend to use a lot in the command line. Also we have a VM option string and you'll notice this is not a dictionary like the system properties this is a string, and that's just a Java thing that's a hotspot thing, those non standard properties, the -x, those are all read in and interpreted as a single string by the VM. So we only provide that as a string. So that's the plist file. And it's actually if you're using something like Jar Bundler it's actually more information than you need to know. You actually never even necessarily have to open this file.
So there's one more thing and it's the Mac OS directory. This is where the real executable is stored and again this is something that every bundle, whatever language or framework it's using is going to have. And inside that Mac OS bundle there's a little piece of executable code and in the case of Java we call that the Java application stub.
So what does the stub do? Like I said it's a little piece of executable, it's a little executable that launches the VM, in enables some of the launch time event handlers for things like document handling as well as alerting your code that the application is finished launching, it's similar to opening documents. The finder also has the ability to pass off a document that you want to be printed. All of these things are managed by the stub.
It starts its life in the framework, inside the contents resources directory of the JavaVM.framework and there's only one copy of it so basically every Java release we do we update the stub. But the stub itself is universal across JVM versions. Now because it's copied, because your deployed application is going to carry around a copy of this stub everywhere it goes, we strongly suggest updating the stub.
We do a lot of work to just kind of make it as small as possible, as efficient as possible, add little bells and whistles from time to time. So whenever you get the chance go ahead and update your stub with whatever came from the latest Java release. Now I want to highlight that last word release.
The DVD that you receive this Monday is not a release it is a Beta. So please do not distribute a finished shrink wrapped application using executables from that Beta. And it seems like common sense but you'd be surprised how many people actually do it. So I felt the need to call that out. Thank you for cooperating.
So we talked about the easy case or the one off case but that's really not how we operate. We go ahead and we do nightly builds maybe weekly builds and we don't want to just get up and go to the, go to our computer and manual use Jar Bundler every time. So how can we do this in an automated fashion. Well for starters our Xcode IDE of course does application bundling very easily.
And if you're going, if you're using Ant and it's very highly likely that you're using Ant if you're using one of those IDEs that you saw listed before, this is a great option because Ant is extensible, it's automatable and like I said it's transferrable to all of these IDEs the most popular ones.
So we've got all the pieces we need so what do we do? Well what's great about the new Xcode in Leopard is that we've re-tasked all of our Java application templates to use Ant. So when you're building, when you start a Java application in Xcode, a Java project in Xcode it's really just an Ant project. And you're going to see that in a second.
And we've got a package subtask. We've got an Ant-based task now that creates the application bundle for you and that's something you can go ahead and just use and reappropriate anywhere. So if you happen to not even be building on Mac OS X there's an option for you. And I would like to show you that right now.
Get this calculator out of the way. So first thing I need is a PC and they're kind of hard to come by in this building so I'm going to call on our friends from Parallels of course to save me some time and trouble. Of course this Is a demo so I've got something all ready. I've got this Java project here I'm going to just go right to DOS and go to the desktop.
I'll go ahead in here and let's see what this looks like over in Explorer. So right, Ant-based project, very simple stuff. Let's run it. Oh it looks pretty good that font there. I thought the command prompt would be small. So right. Typical Java application, nothing special, it's running on Windows. Fantastic.
But what does this actually getting us? What's being built? Well there's really nothing in here other than some build stuff, there's a jar in here and we've already been through that routine right? This is not good enough anymore. So what are we going to do? I'm building on Windows I don't have a Mac in front of me. Let's go over to Xcode. Let's just use a Mac for a couple of minutes if you can manage. I'll start a new project, and lets create a new Java application and I will call it, put it in temp, I'll call it test.
So the first thing you notice, looking at all the files in here, is this is very clearly an Ant-based project. So all I've done is file new and I've got an Ant project in front of me right? So and you know, we're not even going to build and run this all we're going to do is pay attention to the things that are specific to the Macs, specific to the bundle.
We've got this resources_Mac OS X directory, again this is part of the template. This is not a precooked demo. We've got our plist file, we've got our icons file, those were those two things in that anatomy, in those anatomy slides that we needed. There's one other thing we need and that's the stub. So let's go get it.
System/library/frameworks/JavaVM.framework/resources /Mac OS. Mac OS. There we are. Now I'm just going to actually drag, actually, no I need to view this in finder. I'm just going to go head and drag the stub in here. So now we've got everything we need and the idea here is that we're just going to move this over in a moment. So let's see what's going on in the build out XML file.
Like I said there's a package subtask here so let's go down here to package, let's see what's going on. And right here is your Ant task, this is what does the packaging for you. So it's basically ready to go. There's one thing we need to do here which is get rid of this Unix executable since we're not going to be building on Unix of course. Let me copy this. And because Parallels is so awesome, I can just start moving this stuff over. Actually I'm going to, excuse me, let's go get this folder first.
Start by copying over the resources Mac OS X folder, copy, back over here and there's our resources Mac OS X. Open this guy with WordPad, I've got this on the paste board, did I just, yes I did. I just pasted it twice. Okay we'll go down to once. So we've got a bunch of properties here like application.resources.Javaapplication.Mac OS. Obviously these are specific to our Xcode project. Let's go get those as well. Resources Mac OS, come on, okay.
WordPad. Let's go up to the top here and I could've prebaked this but basically I just want to show you guys that there's no trickery here and that it's very straightforward. So and the other thing we want to do is you might notice that there's a hard link to the framework for the stub right now.
So let's go ahead and change that to resources/Mac OS X. And that should be all that we need to do. Oh actually I need to change, of course I need to include the file name, and let's see here. Let's try our new package task. Build successful. Yeah well, we'll see.
Let's see, let's go in the disk directory and test that app. And like I said, if you didn't believe me before, windows is backing me up. This is really just a folder. Obviously Windows doesn't know what do with that, let's go ahead and zip it. Suck it over here. There we go we've got our application it's got an icon, and wow it runs.
( applause )
So even if you're not using the Mac to build and deploy and obviously we would like you to. But if that's the case we understand. There's really no reason to not be doing this to not give yourself that proper desktop image, that proper desktop presence. I mean this is no brainer stuff. And we've done it in just a few minutes. And at this point once you've got it into Ant you can do it every night. Back to slides please.
So a little about deployment. The typical distribution mechanism for double clickable applications on Mac OS X is a disk image. You can think of it as an ISO if you're from the windows world. And this is one thing that will require having a Mac on your hands because we do have a command line tool called hdiutil that will allow you to create a disk image. If you don't have a Mac on your hands, you don't have one that's automatable, you can go ahead and just create a tar ball. A tar plus gzip or standard zip like I just did as you saw me dragging out of Parallels.
If nothing else, what we really expect, or what our users really expect is to just be able to drag with a thing. That's the whole point of making these application bundles is it's one file on the system that has everything that's needed to run the application which is really not too much to ask.
And it just works. Now this is a good example, this MarsEdit package. This is a disk image and when the image is mounted you'll see this nice, they've done a little extra and they've put a custom background in the actual window itself and they've also included an alias, a sim link to the applications folder, which is a known, you know, deterministic place. So this is actually a sim link to /applications and it works on every system of course. So the user doesn't even have to open a new window to perform the drag install, they just move it a couple pixels to the right.
And if you're a move complicated application like Maple, you saw this morning they've got a lot of sample code they've got a lot of sample projects, a lot of supporting files that don't necessarily make sense to go into the bundle. You can use an installer, we of course would like you to use our installer, our PackageMaker tool creates installation bundles. And you can see the Maple guys as Pritique pointed out this morning actually did create a Mac OS X installer package.
So the final thing is the screen menu bar and I'm making a big deal out of it but it really isn't a big deal it's kind of a no brainer. It's very easy to adopt it's a system property. Apple.laf.useScreenMenuBar. It's a system property so it has no affect on other platforms.
Set it early on whether it be in your main method, preferably as a -d in the command line or of course in the Java properties dictionary of your plist and basically these swing J menu bars that normally in a cross platform sense appear inside the window go right up to the top just where we would expect them to be.
And of course as a last resort for whatever reason, you can go ahead and set that in code using System.setProperty. If you're going to go that route, you want to do that, like I said, very early like right at the top of your main method. But if nothing else before the AWT is loaded.
Because we only check for this property once. So before you call tool kit, get default tool kit before you instantiate a J frame, anything like that you want to make sure this property is set and doing the system property and the command line and the p list is a good way to do that.
So we're going to go into this in a little more detail tomorrow. But we have a couple of extension APIs that allow you to take advantage of this, this application menu that you've been seeing in all these demos. Now obviously I haven't written any code to do that. That menu just appears. That's one of the things we provide to you just to make it that much easier to look like you belong on the system. You get that menu for free. And we allow you to do simple things like set properties to customize the name there.
Now there's a bunch of actionable things in there thought in particular the about menu, there's a preferences item, and most importantly there's a quit item. And that's the one I really want to highlight today. Because every application has a quit event. Including yours. As soon as you launch a Java application on Mac OS X and load the AWT you're going to get an application menu with a quit menu item. A functional quit menu item.
Now all of us have tear down code like you saw Maple this morning, are you sure you want to quit? Do you want to save this stuff? Most of us have logic that handles that stuff immediately. And it basically comes down to hooking whatever logic you've already written into these APIs we provide for you. It's very straightforward.
So implementing these quit handlers. First you want to import the com.apple.eawt package and you want to write a simple listener that implements the application let's say listener interface or alternately implements the, excuse me, extends the application adapter class if there's only one method you actually want to override. So in this case we're overriding handle quit which receives an application event that's another one of our EAWT classes and really this class should not be a whole lot of code.
Like I said, if you've written an application on Windows or Linux and you've got your are you sure logic already, you just pass off to that once you receive the event. And the event itself has a set handle method which basically tells the system yes go ahead we're ready to quit or alternatively, no the user cancelled. And it's basically that simple. In most cases it doesn't need to be more than two lines of code.
I always forget about those builds. And again, registering this application, very easy. Go ahead and you have your main method again, similar to the screen menu bar this is something you want to do really early, because you never know when the user's just going to get twitchy and hit command+Q. So you want to have this handler in place very early on.
You instantiate your listener, add it to the application class as an application listener. You can add more than one of these but for the most part you only ever need one. And go ahead and implement the methods of your choice. So I'd like to show you that right now.
( applause )
So I've got a couple of demos here of some of you are already familiar with the OS X adapter sample. I'm just going to go ahead and run it I'm not even going to bother with the building at the moment.
So standard Java application, not so standard actually it doesn't do a whole lot. The point of the sample is to show you how to implement the application menu items. So we've got our about, we've got a custom about dialog. And you know, most of you guys probably have your info dialogue that you've already written again. So this is just a matter of implementing this method and passing it off to the code you've already written.
Screen menu bar is on top. This is something I haven't mentioned by the way and I don't know if anybody else has, but you see this search field we have now in Leopard. I think the name for this had been spotlight for help, I don't know if that's the name of it anymore.
But this just works in Java so if I go ahead and type open, it's actually searching my J menu items even though I haven't written a single line of code or even set a system property to do that. It all just works. I hit enter and I get my, do I? No I don't. I should be getting my open dialogue any moment now. I wonder if this is Spaces having fun with me. Maybe not.
So again, I also have the preferences menu item here standard preferences dialogue and maybe not. But more importantly let's get on to the quit menu item. And this is a standard J option pane and this icon we get for free because it's of a certain alert type and we just say are you sure? And you say no. And we didn't quit.
You say yes, we do quit. Now without the application handler that we , excuse me the application listener that we would've written nothing would've happened here at all. So let me show you what this looks like. Again, we're going to extend the application adapter class, we've got a bunch of stuff here, handle about and you can see these are really short methods right? Presumably this main app class which is our main application, has all the logic. We're just passing off to that, setting the events as handled as necessary, similarly handle quit. If you want to delay or cancel the quit set handle this false and that will reject the quit and allow you to opt into quitting yourself.
So that's great and actually this sample goes a step further and it actually loads this class using reflection. So that basically you don't have to mess around with your distribution you can go head and ship that OS X adapter class and it will only ever be loaded or even referenced on Mac OS X. So you can go ahead and still distribute one code base, have it run everywhere.
And I know what you're thinking, I still have a source file in here that's referencing com.apple.eawt. I just showed you how to use Ant on Windows to build something and now I'm telling you to use apple specific APIs when you're building. So that was OS X adapter 1.0. Let me show you 2.0.
It's another project. I went ahead and I built it in Leopard using ant. So the whole picture's starting to come together. But the adapter is a lot more interesting than it used to be. Obviously you can see the reflect here. I don't want to get too dirty into the details this is something you can download from the attendee's site but basically what this new sample does is it uses a proxy object to go ahead and just dynamically create an object that responds to the handle quit, handle about and handle preferences menu items as necessary.
So basically what that means is there's no static reference anywhere in the code to com.apple.eawt. So you can even build this, not only run this, but now build it anywhere without any kind of stub files or dummy implementations or anything like that.
( applause )
So I've actually added some functionality to the app too. So we've got something that opens here. And in case you were wondering why would we want to do something like open image files, well of course, oh darn. I didn't change my document associations. The sample of course also does the document association that we alluded to earlier. But I'm clearly using the wrong version of it. And Scott will go into more detail on that on Friday. Again it's just a matter of changing some plist keys and implementing the handle open file method.
And as you might imagine this thing goes ahead and builds on windows as well. So let's see what we can do about that. Let's go to my computer, where do I want to go, we'll make it easy we'll go to the desktop. That's 1.0, we want 2.0. Let's copy this guy over here.
( keyboard clicks )
- No, no, no. OS X adapter. Sure. And let's see. And of course we can't run the double
- clickable application so let's go ahead and do the, oh excuse me, the run jar command. As you can see it builds and ran, so there's no trickery, no magic or anything like that.
Another thing worth noting is you know we've got the open dialogue here we've got the menu bar down here, we've got an options menu in the file, excuse me, an options menu item in the file menu. We'll go ahead and select the background color which doesn't show up until an image is actually loaded. We've got a help menu here that has our about information. Now this stuff is down in the menu bar.
Let's go back to the Mac version. Excuse me, I should probably launch, oh there we are, there's our quit handler. Perfect. You notice that the file menu does not have the options in there and the help does not have the about and that's because I'm just conditionally in the code checking whether or not we're on Mac OS X and I am or am not going to include that menu item based on where the platform is. The same logic is there, there's no code, you know when I go ahead and open the preferences here, it goes ahead and brings up the same dialog you see over here on Windows.
So this stuff is very simple and once you look at the code you realize it's not that much work to just kind of be mindful of this. So if you're go in here and do this work in the first place, make sure you do it right and go the distance. That's pretty much it. We can go back to slides.
So the things to remember when we're talking about the desktop. First of all I said it in the beginning, today's users really expect more. You ask somebody to download something and run a shell script or double-click some file that's not particularly personal, not recognizable, I can nearly guarantee you that the average Mac user is not going to receive that particularly well.
You really want to pay attention to the platform and I say the platform, the work Mac does not appear anywhere in this slide. It's not just Mac OS X, it's basically every desktop environment you intend to deploy to. Make sure you think about, look at some of the other apps whether they're written in Java or not. Look at the other apps that are on the platform and see why they're successful.
See what it is that makes users want to use this app instead of the other one and cater to that. You can do it without sacrificing portability and without messing up your daily routine. And obviously we'd like you to go even further than that and do some really interesting things. And for that, if I whet your appetite sufficiently we're going to have a lot of interesting stuff on Friday regarding client properties and JNI integration that you can do in a still do in a portable fashion. And that session is tomorrow, Friday at 3:30.
For more information you can contact me but hopefully I've given you enough. We also have the Java-dev mailing list, those of you who are not on it, you really need to get on this list. This is a fantastic mainly community driven mailing list that's hosted by Apple, it's monitored by the engineers that you're going to see up on stage and in the lab but we have a tremendous number of non-Apple gurus basically. Not just in Java but Java on the Mac. And it's a wonderful technical resource.
And of course there's tons of stuff on developer.apple.com. Not only in the public site but on the WWDC attendee site as well. As you can guess that OS X adapter 2.0 sample is, requires Xcode 3.0 because it's using the Ant based templates but it's really not hard to just take all of that standardized stuff out of the project and move it over to something else.
We have one more lab tomorrow at 10:30am so if you didn't catch us today and you've got some more questions, whether it be from this morning or from this afternoon, please go ahead and stop by and hang out with us a little bit. So in summary, it really is just the same Java you're used to whether been on the Mac or on somewhere else.
We'd like to think it's even better, it's a pre-installed JDK with a switchable command line, an easy switchable command line, we've got a 64-bit implementation that is already ready to go. We've got easy application bundling, we've done a lot of work over the years to just make it as simple as possible with as minimal effort to have you look great alongside all these other applications that were built using native tools and platform specific code.
We've got built in support for Ant now so you can take a lot of the stuff we were talking about and move it right over to other tools or even other platforms when you're building your projects. And we've got some simple APIs that will let you incorporate all the logic that you've already written into Mac OS X specific areas like the application menu.