Configure player

Close

WWDC Index does not host video files

If you have access to video files, you can configure a URL pattern to be used in a video player.

URL pattern

preview

Use any of these variables in your URL pattern, the pattern is stored in your browsers' local storage.

$id
ID of session: wwdc2002-707
$eventId
ID of event: wwdc2002
$eventContentId
ID of session without event part: 707
$eventShortId
Shortened ID of event: wwdc02
$year
Year of session: 2002
$extension
Extension of original filename: mov
$filenameAlmostEvery
Filename from "(Almost) Every..." gist: ...

WWDC02 • Session 707

WebObjects Java Client

WebObjects • 1:09:38

This session discusses distribution layer features of three-tier Java Client applications, such as business logic partitioning, security, remote method invocations, and WebStart.

Speakers: Andreas Wendker, Norbert Schatz

Unlisted on Apple Developer site

Transcript

This transcript was generated using Whisper, it has known transcription errors. We are working on an improved version.

Okay, welcome. I'd like to start our next session. And it is my pleasure to introduce Andreas Wenkker. So good afternoon, everybody, and welcome to the last WebObjects session for the day. My name is Andreas Wendker, and I'm one of the managers in the WebObjects engineering team. And in this session, I would basically like to continue what we started in the previous session and add some more details to the information about Java Client.

So let me just start by summarizing quickly what Java Client is. So Java Client is a very, very powerful technology to create distributed desktop applications. And right now, Java Client is based on a three-tier architecture. So that means that for your application, you have to maintain three different pieces. You have the client application, you have a WebObjects application that's in the middle, and you have a database.

The client is based on Swing. It's pure Java. It's platform independent, which is great. The communication between the client and the server is usually HTTP. What that really means for you is that you get the connectivity of an HTML-based application, but you have an opportunity to add a much richer user interface.

What we announced several times earlier this week is that going forward, we're looking at adding two-tier support to Java Client. Tony has asked me to just spend a couple minutes on that. I don't have slides for that, so I just improvised a little bit. I hope it's helpful anyway for you. The four topics I wanted to cover originally was how you can get the most out of Interface Builder.

I wanted to talk about options when you deploy your client. I wanted to talk about some details of the distribution layer, how it really works. And then most importantly, I guess, how you can make these applications secure. Because you can probably imagine that with all three-tier systems, which have rich clients, that you open the door for a lot of remote method invocations on your server. And knowing how to make it secure is quite important. Before I go into these topics, I will just talk quickly about the two-tier support.

What we do in Java Client is that we have a full EUF environment on the client side. So we have an EU control layer where your business logic lives, we have an interface layer, and we have a database access layer, or something like that. The one that you're usually used to use on the server side is EU access. That's the object-relational mapping layer that goes and generates the SQL for you, talks to the database, and then maps the raw data from the database into business objects.

And on the client side, in Java Client, we use a layer that is actually very similar from the API perspective. But instead of talking to a database, it goes and talks to the WebObjects application server, and then fetches the objects through the application server. So that's the three-tier system. And the problem with that is, I think it's a great technology, and it's very useful if you care about security.

So if you have a fairly distributed environment, you have potentially end users that are outside your own company, then the three-tier system gives you all the necessary hooks to make the application still secure. Because the application server in the middle is the one that controls the access to the database.

And none of the clients can access the database directly. So it's a very secure layer, or architecture. But the downside of it is that there's obviously this additional communication you have to go through. And so you might see some performance... The Java Client is incredibly fast. It's the fastest three-tier architecture I've ever seen.

But still, having this additional layer in the middle might be problematic. So going two-tier will allow you to write applications that have faster response times. And also the second item or issue we will address with two-tier is that your administration gets much simpler. Instead of having to write a single layer, you can write a whole new layer.

So it's a very, very simple process. Instead of having to maintain three pieces, now you just have to worry about two pieces. You just write one set of business logic, not two sets, those kind of things. So I'd like to give a quick demo, so if you could switch to the demo one machine. Okay.

Basically what I thought doing is create two projects for you. One with the three-tier system and one with the two-tier system. And I'll show you that they, from the client perspective, really look the same. And then maybe go through the differences in the project. So let me start by creating a direct-to-Java client application, which is the old three-tier setup. And I'll just give it a name.

These are the usual WebObjects questions. I will add our Java real estate framework that we use throughout the conference here. This is a fairly usual WebOptics application. It has an application class, it has a session class, it has a direct action class, just the normal template. I'll talk about that later.

It's building the project right now, and then it will start the client. This is the client setting up right now. And that's the application it generates, and I think you've seen that in the session before, or otherwise last year. So let me now go ahead and create another project, which is a direct-to-swing application. Also, this is the two-tier setup.

[Transcript missing]

I need to find my frameworks here. Is this error tree? One second. I refined it. So I'll just add the model directly. And then again, if you ask me whether I want to build and launch the project now, we'll do that. And then we'll start the application.

And this is what you get. So from the client perspective here, the applications really behave exactly the same. So you can perform your searches the normal way. Everything is the same. You can open this, look at some details for listing. I can do the same with the two-tier client.

Andreas Wenkert, and you will see it really behaves identically from the user perspective. So what we really do is we really just switch one part of the architecture. We just switch the distribution layer, which usually goes and talks to the WebObjects application server to get the data. We swap it out to use uAccess that talks directly to the database. And everything else is actually the same. So including the root system, which we use for direct-to-Java Client, and that's why these applications really just look the same way.

You can use interface files, Nib files, if you don't want to use direct-to-Java Client, you can do all that in both architectures. The same Nib file will actually work for a two-tier application and a three-tier application. Even something like having a setup where you have a local database and you have another database somewhere running in your company, and you want to talk to the local database if you're not in the network, but you want to talk to the large company-wide database if you're in the network.

Something like that is certainly possible that you basically just check at startup time, am I connected right now or not, and then you just choose either EU distribution or EU access. So this is all possible, and from the level up, EU control, EU interface, EU application, EU generation, all these layers, the functionality will really be the same. Your code will work in both architectures.

So that's basically everything I wanted to say about the two-tier stuff. Can I just see kind of a show of hands whether that's approximately what you guys expected, or do you want me to talk more about that right now, or shall we just wait for question and answers? Yes, okay.

Right. So the question was, we have two different project types here, and the question is whether we can basically make this a runtime check, whether it's two-tier, three-tier. Yes, technology-wise, that would work. Project builder-wise, we would probably not support that out of the box. So you would have to do a little bit of setup by hand, because I don't think it's going to be very common. But technology-wise, that should work. Okay, so I suggest that then if you go back to the slides, I would just continue with my presentation and then maybe we can cover a little more at the end in the Q&A section. So I have to turn this around.

Now, Besity talked about that. So now I have to play around a little bit. Sorry. So I wanted to start out by explaining some more details, or by talking a little more about interface builder. So the two ways you can generate user interfaces for Java Client are direct-to-Java Client and interface files. Direct-to-Java Client is rule-based, code-free. We recommend this as the default way, or as your starting point, at least, for the development process, because it just saves you a lot of time. It's much easier. You make progress much faster.

We understand that the default applications won't give you the polished application that you want to deploy to your customers, so we have a bunch of customization techniques. One of these customization techniques is using Interface Builder and creating interface files by hand. If you don't like the root system at all, you can also just create an application just using Interface Builder and not using any of the dynamic UI generation.

But a question that we hear quite common is, why in the world are you guys using Interface Builder? Because it doesn't do swing, right? Interface Builder is a tool that you can use to create Cocoa applications and maybe Carbon applications, but it's not generating swing libfiles. The answer to that is actually not easy.

The answer is that, unfortunately, to automate the user interfaces and to do all the work that EOF is doing for you, we need very rich connections. The connections are called associations, and they are really multi-aspect connections. For one widget, it's not just a point, an outlet to something else.

There are multiple aspects to it, what kind of value you want to show, and which condition you want to show. So, for example, if you have a project that's running on a Java project, and you want to show it to a user, you can show it to a user, and then you can show it to a user.

you want to enable or disable that widget, what kind of colors you want to use, whether you want to highlight it with a certain color, the text, something like that. And InterfaceBuilder, unfortunately, is still the only tool available to us that allows to create these rich connections. There's really no other GUI editor in the Java world that allows us to do these connections. If you find one, let me know.

Until then, we Interface Builder is actually not a bad choice for us, especially since we can leverage what we do for the Cocoa integration as well. I'd actually like to ask Norbert to come up on stage and quickly give a demonstration of that so that we can see some more details.

So what Norbert will do for us is he will create an application that doesn't use direct-to-Java Client, just an interface file. We have an assistant for that in Project Builder to create a new project. We enter a name. These are the standard questions that we always get. Here we are also at the Java Real Estate Business Logic Framework . And then what's different to the assistant that we saw before is that he had asked for a class name for a so-called interface controller class. I will talk about that in a second.

These are just the same questions. And then here it gets different. So when we create Nib files, Project Builder basically gives us an assistant that helps with the most common cases where we create something like simple tables or master detail interfaces. So what Norbert will do is, I think, choose the listing entity as the master table or master entity, and choose a couple of properties to be displayed in this table, like the listing number, maybe the asking price. The system will ask for some form fields. The first question was about what kind of properties to use for a table, and then we create form fields for us as well.

And then it will ask us for master detail relationship, and then what kind of properties for the detail relationship to display. So we just choose the last name and the first name of all the customers. And that's it. So as you can see, the assistant generated a project with a Nib file. And this is the Nib file it generated, so I'll just make that a little more pretty.

Save that, and then we will, I guess, build the project and run it. So one thing that is interesting about the assistant is that, together with the interface file, it actually generated a Java class, which is a so-called EO Interface Controller subclass. And that's basically a class that is there for your convenience. It makes it very easy. It's a very easy entry point in your source code, how you can load the interface file and then to play around with it. So, nobody's running the application there right now.

So this is the application running, and what we wanted to do is basically overlay that with the file we created in Interface Builder, and then show you how this translation works from Cocoa to Swing that we performed for you. So basically what Norbert is doing there right now is he's showing you the file in Interface Builder on top of the running application, and the file in Interface Builder is Cocoa, and the application in the background is Swing. So as you can see, it overlaps pretty well, and yeah, so that's basically all we wanted to show. Thank you, Norbert. Okay, if you could go back to the slides.

So this interface file translation from Swing to Cocoa, as you saw, works pretty well. But unfortunately, it only works well for the pieces that we expect. It works well for all the standard widgets that we deal with in the EU interface layer, like tables, text fields, buttons, those kind of things.

The Nib first installation doesn't do a very good job when it comes to additional widgets that we don't support by default in EU interface. We just basically ignore those things. And also, Swing and Cocoa don't always match perfectly. So some of the aspects that you can adjust in, some of the parameters you can adjust in Interface Builder don't make it into the Swing version of the interface file. And I wanted to give you a couple of tips that you can use to work with the interface files and get more out of it.

So, what you should know is that there's basically a method on the EU Interface Controller class which is called LoadArchive. And LoadArchive is the method that triggers loading an interface file. The good news for you is that you don't ever have to invoke that. It's done for you, well, there's one case where you might want to. But in the normal case, you don't invoke this method. It's done for you automatically whenever this interface controller is integrated into the application. It's asked to basically show the window on the screen. And if you trigger that, it'll automatically for you.

But the methods that are interesting for you are two additional methods. One is controllerDidLoadArchive, and it's there right now. And in the next release, we are planning to add another method, which is controllerWillLoadArchive. controllerDidLoadArchive, as the name says, is invoked after the libfile loading is completed, and willLoadArchive will be invoked right before.

This is useful for you if you basically want to start an interface builder, create all the common widgets like tables, text fields, buttons, what I just listed, and then basically programmatically complete this Nib file. We find that interface builder, even if it doesn't cover maybe 100% of your user interface needs, it will still be a great starting point for you, as long as we cover it in our Nib file translation.

So with these two methods here, you will be able to then take an interface that is at least close to be 100% of your user interface, and then programmatically customize that. What you would typically do is you would probably search for some objects that you loaded from the Nib file, and then send some methods to it to maybe change colors or certain parameters.

Or sometimes you might place something like a placeholder view, just an empty view inside your interface file to basically mark a position, and then add additional views in there. So if you want to integrate a swing view that somebody wrote that is not covered by our Nib file translation, you just place an empty view somewhere in the Nib file, say this is the position, the size it should be.

Then at runtime, you would load that Nib file, look for this empty view, and place your own view inside. And the two ways that you can use to identify objects are outlets and named objects. So outlets is basically a name that comes from the Cocoa word, and outlet is basically a reference to another object.

So what you would do is typically on your EU interface class, you would create an instance variable, and then you would connect that in Interface Builder, and you would say this is my placeholder view, and then while the interface file is loaded, this reference is filled in, and then in Control-Edit Load Archive, you can add your own views to it. And the other way you have to identify objects is to give it a name. Interface Builder allows you to provide names for some of the objects, not for every object, but typically for all the objects in the file window, like display groups, editing context, the windows itself.

So for those, you can specify a name in the Inspector in Interface Builder, and then we actually provide you a dictionary of all the named objects as an argument to Control-Edit Load Archive. So outlets and giving it a name are ways to identify the objects in the archive.

Another thing that might be interesting to use is that these two methods, or this API, should also allow you to plug in other GUI editors if you really want to. So there are various tools out there for swing that usually do source code generation, so you can use that to place buttons and text fields, all this stuff.

They usually don't offer you to do these connections. You will not be able to create associations in these GUI editors. But if you prefer that over using interface builder and the Nib for translation, use those tools and then use these methods to plug those user interfaces into your controllers and then create the associations by hand. It's really up to you what you want to choose.

So once you've created your application and you want to go into deployment, there are a couple of things you should know. First of all, the only requirement that we have is just J2SE, the standard edition, 1.3.1, and up. If you're one of the lucky users of Mac OS X, then that's the version that's integrated into Mac OS X right now. Otherwise, you're obviously downloaded from Sun. But J2SE is the only requirement that we have.

And there are basically two options for you to deploy right now. One is you create a little desktop application, which means that you create a little start program and put all your classes in a Java file, pre-install it on the client machine, and then the user can start it per double-click. And the other way is to run it as an applet, so then the application is embedded in an HTML page and the user runs it from inside the browser. Let me compare these two options for you quickly.

So the biggest advantage of Applets is really how easy the simplicity of the installation and potentially upgrading process, because there is no such process. When Applets starts up, they always download all the classes they need to this client machine, and then the program is executed there. And when the application is quit or the browser quits, the classes are basically thrown away. And the next time the application starts up, it downloads them again. Which means that if you deploy a new version in the meantime, it will automatically download this latest version for you.

The desktop applications are unfortunately not that easy because you have to create a little startup program. You have to pre-install these classes on the client machine. So in the worst case, if you can't control your user base very well, you might even have to deal with multiple client versions out there. So that's the biggest disadvantage of applications. There's one interesting thing that we introduced in the last release in WebObjects 5.1. We now provide you a class loader.

We're just able to download all the application-specific classes that you write yourself to desktop applications. So what this allows you to do is basically deploy the UF-based system, which

[Transcript missing]

But then, once the application is started up, from the user perspective, the performance of applications is much better than for applets.

First of all, obviously the startup time is much shorter because the classes are already present on the client side. And then you will also find that it runs a little bit faster because there's usually no security manager in place, and browsers don't do their own thing with the applets. So it really runs a little bit faster. It's not a big difference, but probably a couple percent.

More important is that the user experience is just much better than desktop applications, because the desktop applications are really embedded in the normal operating system desktop. So they run as standard-owned processes. You can see the application in the dock on Mac OS X. If need be, you can quit them individually or kill them individually if they hang.

You have access to the services menu. All these things are there, so the user experience is really much better for desktop applications than for applets. Since they run isolated, The stability is also much better. Applets that are, if multiple applets run on the client machine, they all share the same VM inside that browser. And that can obviously have all kinds of negative side effects on both performance and stability.

When it comes to security restrictions, it's not that easy. From your perspective as the developer, you would probably prefer to write desktop applications because there will be no security manager in place, so you don't have to worry about accessing the file system, getting security exceptions, those kind of things. From your perspective, that's nice.

For applets, there might be a lot of problems. Users will probably see, and that's why the app that's got a little dot here, is that users might have a little different perspective on that because they know that for applets, the VM will enforce security for them. They will know that the application can mess around, that their file system delete files, those kind of things. So they might actually prefer running these applications as an applet.

One last thing that's handy for desktop applications is that you have the ability to tune VM parameters individually for each application. While all the applets share all the same settings and you can really control them, you know exactly how you will start the desktop application. So if you have the need for large heap sizes or you give it a lot of images and a lot of memory, you can do that with desktop applications. You will probably have many, many problems with applets.

So we're pretty happy with desktop applications, and as long as you can deal with the installation and upgrading process, we think it's probably the best way for you to deploy it. And applets, we think, are pretty fragile, and in general, we think there's probably a pretty dark future for applets, because, as you all know, Windows XP doesn't support Java anymore, so we don't really expect a lot of applets to be written in the future. So the good news is that our friends at Sun have recognized it as well, and they're actually in the process of providing us with a great replacement for applets, and that replacement is called WebStart.

WebStart is basically a new technology from Cyan which will be part of the JDK 1.4. And it's already available as an optional package for JDK 1.3. If you're actually using Mac OS 10.1 with the latest Java update, WebStart is already integrated into Mac OS X. So that's a good thing. The idea behind WebStart is that you as the developer create a nice entry page in HTML that the user can navigate to in the browser.

And then on this HTML page, there's a special hyperlink that will trigger WebStart. When the user presses this hyperlink, WebStart will download the classes to the client machine, but then it will start the application outside the browser as a standalone process. So it's not going to be embedded in the browser anymore. It's now running outside the browser.

and I think the biggest advantage of WebStart is that it solves the upgrade problem for you. WebStart actually tracks the version numbers or the version of the Java classes that you need on the client side and it will automatically detect the next time the client starts up that there's a new version available for the Java files and then it will download them.

So what WebStart does is it actually caches the Java files, wants to download them on the client machine and then when the client starts up the next time it will go and check with the server quickly whether there's a new version available and if it is it will download the new version but otherwise it will use the cached version. So that's really great. It's very elegant. Can we keep that until Q&A? Great, thank you.

and it gets even better. WebStart really has a nice solution for the security issue. Instead of relying on settings for applets that are for all applets, security settings, the user can grant permissions individually for each application. So basically the applications tell WebStart that they either need access to the file system or not. And then if they do, WebStart will bring up a panel before the application launches. We ask the user, do you want to give permission to this application or not? And that's individual for each application.

And also WebStart requires, if the application wants access to the file system, wants to run outside the sandbox, it will require all the Java files for this application to be signed. And that doesn't really prevent the application from doing something bad on that machine. But what we always say is it gives a better illusion of security. At least people can decide. whether they want to trust the vendors or not.

WebStart also comes with a little manager application. This application basically allows you to see information about the application that has been started before. You keep all that in mind. Then you can start applications right out of the WebStart manager without going back to the HTML page, the entry page. These managers also allow you to create shortcuts. I believe for the next version on Mac OS X, the WebStart manager will allow you to create shortcuts.

You can create shortcuts for the applications that you can then place in the dock. On Windows, the WebStart manager allows you to create shortcuts for the applications. Basically, once the user downloads the application, they can then create little shortcuts, and it feels much better and much simpler to navigate to the application again. They don't have to type in a URL again and those kind of things.

All you have to do if you want to deploy an application through WebStart is you have to create a JNLP file. This JNLP file stores all the information that WebStart needs, so the application name, the version, description for it, who the vendor is, the home page, the entry page for this application, and then a list of all the Java files. So we think WebStart is terrific. And going forward, what we would like to do is we would probably deprecate applet support so it will still be there in the next version, but long term we are planning to remove it.

As an alternative, we will integrate WebStart as a deployment option. We will do that in a way that is very automatic, so that you don't even have to write the JNLP file by hand. We will do that all for you. When your parameters change, your Java files change, we will update the JNLP file automatically for you.

Thanks. We also changed our templates in Project Build a little bit to reflect that now you need an entry page in HTML and then a page that basically configures your client application. What that means is that this deployment matrix changes to something like this. Applets, as I said, will be deprecated, and then WebStart will be a new option. We think that it's really great, especially for the installation upgrade process, and that it handles security very well.

We think WebStart is a really good solution, probably the best compromise. The only downside is still that, at least for the first time, customers need to download the application, so there's a long installation or there's a long startup time the first time. Also, there's still a security manager in place with WebStart, so the application will also perform a little slower than a desktop application without all these things. So I'd like Norbert to come up again on stage, and we'd like to show you our WebStart support.

So we create a new project again, and this time I think we just do a direct-to-Java Client application. Give it a name again.

[Transcript missing]

And then, let's spend a couple seconds here. So there's going to be a new page in the Assistant going forward where you have to enter three values, an application name, a reasonable application name for the client side, who you are, the vendor name, and then a description.

This is going to be the same for Direct-to-Java Client and NIP-Fi-based Java Clients. The application project is compiling right now and the server is starting up. Then it will, like usual, start the desktop application for us again. So this time we will just quit the desktop application right away, and instead we will navigate to the browser. We just paste in the URL.

So it's a fairly simple page. We will rely on you to make that pretty. But basically, there's this hyperlink, and if Norbert clicks on that, then WebStart will fire up. It will download the JNAP file quickly. And then WebStart comes up. So here it's downloading. That was too quick. That's okay. Just quit again and do it one more time.

WebStart starts with the download of the classes, the Java files, and then checking for versions. It's pretty quick right now because we are on the same machine here, but if you're on the Internet, it will take a little longer. But then basically you get the normal application. There's really no difference for the user.

The nice thing about this is you really don't have to worry about deploying as a desktop application or through WebStart. As you saw, both of it is just supported right out of the box, and it's just up to the user to choose the right deployment mechanism. Norbert is right now on Project Builder, and I just wanted to show you quickly that now the new projects have two components. There's the main component, just with the hyperlink. You can make this really pretty and put your own company logo there and all these things.

Norbert goes to the source code. The link is basically bound to a method on the main component. And if you show that, then you will find that there's The static method that we provide to you on the VoJava Client component, which generates the right link, the URL for the link for you.

So this is the way for you to integrate JNLP links into your pages. Pretty straightforward. And then there's the Java Client component, which looks very similar to the ones that we had before. In earlier times, there was the VoJava Client applet. Now there's the VoJava Client component, and they're all the same bindings, like the application class name, what interface files to use. There are a couple of additional bindings, obviously, for WebStart, like the application name, what you entered in ProjectBit and the assistant. Okay. Thank you.

If you go back to the slides. Okay, so for the rest of the session, I want to spend some time on the distribution layer. And the one thing, the one message about the distribution layer is it's fast. For a three-tier system, it's really, really fast. The reason why it's fast is that it uses a copy distribution mechanism. What that means is that when you fetch objects from the server to the client side, the objects are copied to the client, and then they live there on the client side as fully functioning objects in your EOF stack.

So most other technologies create, do something like with stubs. So usually their clients use some kind of placeholder objects that go and talk to the server all the time for every little detail, right? And maybe they do some smart things with caching, but what you would find with these other technologies is that they have a lot of communication going on between client and server.

So in our world, if you really just copy the client, you can actually do a lot of things with the client. So in our world, if you really just copy the client, you can actually do a lot of things with the client. So in our world, if you really just copy the client, you can actually do a lot of things with the client. plot the optics to decline and then the lift and you editing context and you can do all the things that you used to do in the u_s_ validation you know if you say input um...

[Transcript missing]

This is just a little architectural diagram.

The left side here shows the client side. The right side shows the WebObjects application. And again, what I wanted to point out is just the control layer, the EU control layer, which is the layer in EUF that you work with most of the time, the layer that you use for writing your business logic, that exists in identical form on the client and the server side. And you only get different behavior because there's another layer plugged in from underneath. Instead of EU access, which is used on the server side, you use the EU distribution layer. And again, the communication between client and server is usually through HTTP.

There are four object classes in the distribution layer that make this happen. On the client side, there's the so-called UDistributedObjectStore, and then the UDistributionChannel. And UDistributionChannel is actually an abstract class and usually uses a concrete subclass, which is the UHTTP channel. On the server side, there's the so-called VoJavaClientApplet. The name might be a little confusing. This is actually not an applet, it's a Vo component that generates the HTML for an applet.

And as you heard just a minute ago, we will replace that going forward with this so-called VoJavaClientComponent, which basically has the same functionality, it just doesn't generate applets anymore. It's specialized for WebStart now. And the fourth object also on the server side is the UDistributionContext. So I'd like to talk about these four objects for a few minutes. Let's start on the client side with the DistributedObjectStore.

[Transcript missing]

To plug in this EU distribution layer on the client side, we just use a different kind of object store for the parent for the editing context. And that's this EU distributed object store. So it takes the place of the EU database context that you usually use on the server side, and becomes the parent of the editing context on the client side.

To you, that should be pretty transparent. You hardly ever write code, or at least you should hardly ever write code, against objects in the EU access layer directly. The EU access layer deals with SQL for you. You don't have to worry about this. The objects that you deal with are the objects in the EU control layer, and that's most of the EU editing context. So this should be a change that will just happen pretty transparently for you.

The distributed object store then uses an object that's called the EU distribution channel. The EU distribution channel is the object that implements the concrete protocol to communicate between client and server. It basically gets a stream of data, and it's supposed to transfer that to the server side in some form, and then read the result back. And the channel that we ship by default, the concrete subclass, is EU HTTP channel. That's the one that you usually use.

The advantages of this architecture here is that these objects are actually separated. The channel is not integrated in the object store, so that you can plug in a different behavior. You can use your own distribution channel subclass to change the way you communicate with the server. Very common use cases for that are adding security or adding SSL support, basically. You might also choose to do IIOP channels or whatever is in your mind. I guess the most common case is to do SSA.

So this distribution of the channel basically takes data and sends it over to the server side. And on the server side, the object that listens to these remote method invocations is the component, the VoJava Client applet, and later going forward, the VoJava Client component, that you use to configure the client-side parameters. So that's actually the real object listening to the requests.

But it doesn't really do anything with these three requests. It just forwards them to the distribution context. So again, there's an architecture. This is not one object class so that you can plug in different behavior. You can choose to write a subclass of the EU distribution context. The distribution context is the object that really performs the EUF-related work. It's the object that then basically goes to the editing context on the server side and fetches objects and saves, fires faults, those kind of things. So these four classes really make the distribution layer happen.

To make this a little simpler to you, I think the best way to think about the distribution layer is simply that the editing context on the client side behaves like nested editing context to the editing context on the server side. If you think a little bit about object stores, what the distribution layer does, basically it connects the editing context from the client to the editing context on the server side. The editing context on the server side basically behaves like the parent object store to the client side.

One thing that's important with our HTTP channel is that it's an unidirectional connection. It's not a bidirectional connection. What you typically find in a WebObjects application is that once a change comes down from one object store, from one editing context, gets saved to the database, all the other editing contexts in that same application are synchronized with the changes you made. And that's automatic.

But in our model here, that doesn't work because you can't push back changes through HTTP. There has to be a request. It has to be pulled from the client. So what we do in the distribution layer is that we keep track of all the changes, and the next time the client connects, we will synchronize the changes on the server side.

So if you have multiple client applications running through the same application server, and one client makes a change, it will be saved to the database, and the other clients will be synchronized with that state, the next time they connect. And then potentially it might even have to do with optimistic locking errors or so, but they are the normal ways in EUF how you deal with that.

So what do you need to know about security? Obviously, the moment you have clients, rich clients that can go to the server and fetch data and save change to the database, that opens up potentially a lot of security holes. So the most important mechanism for you to make your application secure is what we call business logic partitioning, and I'll talk a lot about that.

The second thing you need to know is that on the server side, there's a delegate to the distribution context that has full control over every remote method invocation. So the delegate to the distribution context is the object that you really use to make the application secure if you care about every individual invocation and if business logic partitioning is not good enough.

The third thing you need to know is that if you want a secure connection, right now you would have to subclass our EU HTTP channel and then use additional packages like JSSE or so from some to create secure sockets. We actually showed a demonstration of that last year, so if you can go back to the DVDs from last year, there's even some source code how to do that. Otherwise, maybe you can come to me afterwards and I can point you to that code. Let's talk about business logic partitioning.

What business logic partitioning means is that you can choose whether you want to use identical business logic implementations on the client side and the server side, or whether you want to use specific implementations on client and server. In greater detail, what you can do is you can choose two different classes to represent your objects on the client and the server side.

And you can limit or restrict the view of the client to a subset of properties. So if there's something like a password field in a user object, you can simply say that this is not supposed to be visible on the client, and the distribution layer will make sure that it's never sent to the client, so it's not visible to the client.

So business logic is very important for security, and it's actually also very important for performance, because, at least what I hear from several of the customers, from several of you guys, is that to create a successful three-tier application, you have to be fairly careful about sending data, or too much data, to the client side. Often you can avoid sending data to the client just because you will never display it there. Often you're just interested in some derived information, something like an average value.

If you wanted, for example, to have a list of departments, and then the average salary of all the employees in that department. So instead of sending all the employee objects to the client side, and then performing the average computation on the client side, it's much better for you to just compute that on the server side, and just send the entry side over, and avoid that you send all these employee objects. And from what I hear from you is actually that that's the key to have a successful implementation in Java Client, that you make sure that you don't send too much data.

If you want the response times to be reasonably low, or small, then you need to make sure that you only send the data to the client that you really need to send. And if you don't display it there, if you don't need it for any computation on the client, keep it on the server side.

Another advantage of doing that, by the way, is that you can use a class if you have a fairly secure algorithm that, for some reason, you don't want to be visible on the client. And keep in mind that with Java, classes can be very easily decompiled, so everybody can look at your implementation. If you don't want that, you can force your client to talk to the server for some of the operations. That way, you don't make your implementation visible on the client side.

So the tool that you use to configure the business logic partitioning is EOModeler. And there's a column that you're all familiar with, which is the class name column. And that's where you specify the class that you want to use to represent an object for a given entity. And there's a little menu in the lower left corner of the table view, the Add Column pop-up menu there. And that allows you to reveal additional columns. And there's one that is not visible by default, but if you do the Java Client, you need to look at it.

It's just called Client-Side Class Name. So here you can specify the class name for the objects on the client side. And as you can see in this example here, for some of the entities, I used the same class name. And for some of them, like the second one, the customer, I'm using classes in different packages. One is the example.serverCustomer, and the other one is the clientCustomer. So here I can choose different classes for client and server. The other thing that you're interested in is the class properties.

If you look at an entity, there's the column that you're all familiar with, which specifies which of these attributes and relationships is really part of your business object. That's what we call a class property. There's a second column you can reveal, which is for the client side. So here you can specify that the client, for example, has no access to the phone number, I believe, and the member date.

And then also if you deal with business logic partitioning, there's some API that's fairly important to you. There are three methods that you care about. There's invoke remote method, there's evade from client update, and prepare values for client. The first method is used on the client side, and the other two methods are used on the server side.

Invoke remote method

[Transcript missing]

There's a fairly important naming convention that we have. And the naming convention is that if the name of the method starts with client-side request, then we consider that a method that is open for unrestricted access. So we consider that a method that can be invoked by any client.

If you don't follow this naming convention, you will actually have to go through some extra code to enable that, because by default, we only allow methods that follow these naming conventions. We don't want to open additional holes in your stack. We don't want to allow clients to invoke any method that you don't intend to open up. So that's why this naming convention is fairly important.

One recommendation if you work with business logic partitioning, you use different classes on the client and the server side, is to not use two classes, but actually three classes. What we recommend is that you create a common superclass in which you implement all the shared functionality, and you define all the methods that have different implementations as abstract methods on this common superclass, and you use two complete subclasses, one for the client, one for the server.

For example, a class secret here, an abstract class, and there's an abstract method definition. On the client side, I could implement that to simply go to the server. So I would just use invoke remote method, and that would basically just move the method execution to the server side. And on the server side, the method secret value would actually return a concrete value, and then there's the client side request method. Let me go back one slide.

As you can see, I follow the naming convention client side request here. So this is a method that's considered open for unrestricted access that just invokes the real method. This might look a little complicated, but it has a big advantage for you. The advantage is that you can write business logic code against the abstract super class, and that business logic code is usable on both the client and the server side. So it really increases the reusability of your business logic. If you use the secret class, you can write some code, and it will execute in the secret. same form of client and server side as long as you write it against the abstract superclass.

So invoking remote methods on EOs is fine, and it's very, very important. But in reality, if you have a desktop application, you will need to talk to the server for reasons that are not related to your business logic, typically loading some resources or maybe performing some user authentication, those kind of things. So we also have an API for that, and this API is on the EODistributedObject store.

So if you remember the picture from before, the EODistributedObject store is the parent object store of the editing context, and the simplest way to find it is to invoke a static method on EU editing context, default parent object store. So that's the best way for you to get to the distributed object store, and there's an API that you can use to perform application logic-specific remote method invocations.

There are two methods that are interesting to you. One is called invokeRemoteMethodWithKeyPath, and the other one is called invokeStatelessRemoteMethodWithKeyPath. Let me go back one slide. So the arguments to the first one are an editing context, a key path that will identify the object on the server side-- I'll talk about that in a second-- a method name, and then the arguments. The method invoke_remote, or invoke_remote method with keypath is a method that can include enterprise objects. So if you have a remote method invocation that is somehow related to your business objects, then you can use this method here on the distributed object store.

[Transcript missing]

We just introduced this method in the last release, by the way, so I don't think a lot of you have seen this. So WebOpt.js 5.1 introduced this method. And the great advantage of it is, by the way, that it's thread-safe, so it's actually ideal for some background tasks.

A common use case of this method is to perform a background ping every five minutes that checks with the server side, are there any changes? And if yes, then you actually fetch them. So this is a fairly cheap method that doesn't have the overhead of the state-full remote method invocation and just there's no enterprise object in the communication.

So let's talk about how the object on the server side is identified. The argument to these methods that identifies the server side object is the key path. It's a key path that's evaluated relative to the distribution context. A typical example is session. You would specify a key path starting with the distribution context on the server side, a key path that goes to the target object on which you want to invoke your remote method. There are two special cases. One is if you personalize the argument, you try to invoke the method on the distribution context itself. That's mostly interesting if you use subclasses of your distribution context.

If you pass an empty string, then for your convenience, if you have a registry on the distribution context, you can plug in additional objects that want to listen to remote method invocations. So that's just a registry, and if the key path is just an empty string, you just go through all the objects in this registry and find the first object in this registry that responds to the method and then perform the remote method invocation on that object. So that's basically just a convenience for you so that you can plug in arbitrary remote method listeners.

It might be hard to register these additional targets because every session uses its own distribution context. So distribution context come and go together with the sessions. So to make that easy for you, we introduced a notification that we sent out. It's called your remote method receiver needed notification.

Basically, in your application, you can register for this notification. and then when you receive it, you receive it for a new distribution context, and then you register your objects as invocation targets. Again, the naming convention client-set request applies to both methods that are on enterprise objects and to the application logic-specific remote method invocations.

This confused me. I think there's something missing now. With all these remote method invocations, again, if they follow the client-side request naming convention, we consider them open for arbitrary access, so they would just go through. If you don't use this naming convention, you have full control over every single invocation, and you have the control over these invocations in the delegate of the distribution context on the server side.

So you register a delegate object, and then there are several methods that we will send this delegate object, and you can control either per method name or for the key path, which method invocations are allowed. You have full access about which fetch specifications the client can execute, which faults the client can fire. So this delegate is really the one instance that you use to control client on a fine-grained level. Business logic partitioning does the first.

It does a very good job as long as it can describe the difference between client and server in the schema, but often you need more fine-grained control. For example, once a user logs in, you might allow access to certain objects, certain fetch specifications. You might want to enhance qualifiers to limit the search results, but those are not schema-based. Those are really data-based, and for those kind of things, you use the delegate on the distribution context.

And there's, again, a notification that you can use to set this delegate for the distribution context, because there will be many, many distribution contexts in your application, one for each client. And this notification is your distribution context instantiated notification, so that's sent out, again, when the distribution context is created.

So I'd like to ask Norbert to come up on stage. And what we'd like to do is show you an example, a couple of details, of an example that we shipped with the last release. Attention WWDC 2002 attendees. Hall 1, including the exhibitor fair and internet cafe, is now closed. Please join us on the concourse for sex. And then again at 6.30 in Hall 2 for the Apple Design Awards, followed at 7.30 by Stumpy Experts. Thank you.

[Transcript missing]

We added an example to the last release, WebObjects 5.1, which we call Discussion Board. It's a Java Client example that shows how to do authentication and to use all these distribution context delegate mechanisms to control security on a fine-grained level. Let us show you the application quickly. It starts with a login panel, and Norbert is logging in as an administrator right now.

He gets a fairly standard Java Client UI. As an administrator, he can perform every single operation that he wants. He can search, open records, etc. The editor menu items, the tools menu called Logout. It goes back to the login panel. Norbert will log in as a normal user, not as an administrator. Then what you will see is that There's a very customized UI, so it's not a direct-to-Java Client UI anymore. So there's a subscriptions window for the discussion board.

You can look at discussion boards individually. And there's also something like a preferences panel. So as you can see, this UI really has nothing to do with direct-to-Java Client standard UIs. So we wanted to just show you a couple of places in the source code that might be interesting for you.

This is all in WebObjects 5.1, so we don't want to show you too many details because you can always go back and look at it there, but just a couple of places. The way this example works is that there's an object on the client side that tracks the user authentication state, and there's an object on the server side that does the same, and those two are obviously in sync. The object on the server side is actually the session object, so that the user authentication is handled for each individual client.

On the client side, the authentication center, that's the object class that controls the authentication state there, if the user logs out or logs in, basically what happens is that the startup sequence is played again and again and again. The startup sequence, in our world here, basically means to get rid of all the windows that were opened before. It will forget all the objects, all the EU enterprise objects that were fetched before, all these things will forget, all the preferences values, all these things. Then, if you start this, and we basically perform the start sequence. since this is a direct-to-JavaClient application.

What happens is that if the user is not authenticated, the server will actually provide a description for the client side that says the windows that are there are the login window and the registration panel. Then once the user logs in, the state is cleared up again, and if you perform the start sequence again, and then the server decides again, depending on the user who logged in, what kind of UI to generate.

So for an administrator, if you just create a direct-to-Java Client UI, and for a normal user, if you create a very customized UI. So as you can see, the server really is the object that controls what happens on the client side. And we actually use all these methods, the distribution context delegate methods, to control the individual remote method invocations. And one thing that we won't show you, but it's there too, is that we also make use of that in the rule system for direct-to-Java Client.

Basically, since the user authentication information is stored in the session, we can use a key path starting from the user authentication information. So starting with the session, something like session.isAdministrator, in the rule system to decide what kind of windows to generate for direct-to-Java Client. Okay, so the one-up method, we wanted to show you four places in the code. The first method is, are there five? Maybe there are five.

So it's called, in the authentication center on the client side, perform launch sequence. That's the method you want to look at. It's doing all the cleanup work, closing all the windows, invalidating all the objects, invalidating all the UI information retrieved for the controller factory, so far. And then, one method invocation that's interesting here is factory. I'll go back. Okay. There's this method, controller factory, open default. I'm going to scroll down a little bit.

It's at the bottom. Activate default controllers. So that's the method that triggers the startup sequence again on the controller factory. So that might be interesting for you. The other method, interesting, is the method that actually sends the user name and the password to the server side. And what we do here is we just do a stateless remote method invocation, and we send the name and the password to the server side. That arrives in the session on the server side.

[Transcript missing]

So, again, I think it's a very useful example. I would recommend looking at that if you're interested in security with Java Client. Thank you, Norbert.

Okay, so the conclusion for this talk, just a quick summary. So the things I'd like you to remember is that the distribution layer is a very, very efficient layer for, you know, it's certainly slower than a two-tier application, but it's doing a very, very good job for a three-tier architecture. The items about security that you should remember are business logic partitioning is your friend. Business logic partitioning is your best mechanism to control what the client can see.

If you need finer-grained control, you use a delegate for the distribution context, and if you want a secure connection, you use a distribution channel subclass. And then going forward, we will deprecate, or we are planning to deprecate applet support in Java Client and replace it with WebStart, and from what I hear from you guys, that's probably what you do anyway today. So I guess I have a couple of usual slides here. The lab is closed now.

But you can go there tomorrow again. The two sessions I would recommend to you if you want to have more information are 7.11 and 7.12. They are about EUF. One is about data modeling part, and one is about how to deal with synchronization in EUF and things like that, advanced enterprise object frameworks. And then you can obviously beat us up in the feedback session. Who to contact? Tony and Bob.

You've probably all seen that. Again, there's a great book about Java Client desktop applications. It was actually written by Brent, who did the demos in the last session. This is a really good entry point for you if you want to know. It mostly talks about UI generation direct to Java Client and Java Client, and also talks a little bit about the distribution layer. There's the information about the documentation. And that's it. Thank you.