News: Phentermine Online With Insurance No Prescription Cheapest Buy Phentermine Buy Phentermine Sat Delivery Cod Phentermine Without A Prescription Saturday Delivery Cheap Phentermine 37 5mg Phentermine Rxdrug Phentermine Order Cod Phentermine 37.5 Mg Tab Phentermine Prices Pharmacy Online Real Phentermine 37.5 Without Prescription Phentermine Overnight Phentermine Didrex Vs Phentermine Buy Phentermine Online No Scrip Cheap Phentermine Extra Cheap Phentermine Danger Phentermine Online Pharmacy Best Price Phentermine Vs Adipex Phentermine Ingestion By Pets

Two of the biggest names in the Internet are Yahoo and Google. Its no longer surprising that competition will exist between these two giants. When Google has launched its AdSense campaign it started dominating the Internet but of course Yahoo will not just let this pass without creating one of their own. If Google has AdSense, Yahoo on its part has created the Yahoo Publisher. But comparing the overall design of the two programs we will see that they are somewhat similar in some respects.

To better understand the two programs it would be best that we discuss them separately.

Google’’s AdSense

Let us start with the infamous AdSense Program. This program is an automated ad service that allows small web owners to display advertisements on their own web pages in return they will receive a portion or a share of the pay-per-click revenue that Google will generate out from the AdSense. This is an additional income for web owners.

Google’’s AdSense in one view may seem to be a simple concept but behind it is a complicated technology that only the smartest and the brightest team of Google can effectively accomplished. The AdSense program is wholly automated and makes use of a crawler that assesses the contents found on a publisher’’s site. After the evaluation is complete Google will then provide the publisher with some Javascript code to embed in their pages.

If ever the Javascript is activated a call is made back to Google to pull some ads out from the AdSense program. The ads generated will be in accordance to the content found on the page. For example if the content of the page deals on wheelchairs then all ads regarding wheelchairs will appear. If you want to gain more from AdSense it would be best to customize the colors as well as the formats to match the theme of your site.

This will make the AdSense appear as if it is an original part of the page. This will lead your site visitors to think that it is a link to one of your site’’s pages and would therefore click on it for additional information that they may require.

Yahoo’’s Publisher

There are several features that set Yahoo’’s Publisher distinct from Google AdSense and these are as follows:

1. You will not see the Google’’s famous tagline?”Ads by Google”

2. The ad blocks used by Yahoo do not touch each other

3. Another obvious distinction is the text inside a block is cut off and ends in an ellipsis.

These are just some of the prominent features that differentiate Yahoo’’s Publisher from Google’’s AdSense. But unlike Yahoo, Google requires its advertisers to refrain from using incomplete phrases and to limit the phrases to a certain number of characters per line.

In using Yahoo’’s Publisher when you click on the ads you are transmitted to the advertiser’’s page but you have to pass through first an Overture server. This Overture Server by the way is Yahoo subsidiary or soon to become Yahoo Search. The main function of this server is to do ad serving.

A month back, I wanted to find out all processes running on my machine from java code for some stupid purpose. What d you do in such a scenario? I tried to write some code and was pretty successful. Java can’t play with system process and hence invoking a runtime is only solution to get all process and here it is:

import java.io.*;

class ListProcess {

public static void main(String[] args) throws IOException {

Runtime runtime = Runtime.getRuntime();

String cmds[] = {”cmd”, “/c”, “tasklist”};

Process proc = runtime.exec(cmds);

InputStream inputstream = proc.getInputStream();

InputStreamReader inputstreamreader = new InputStreamReader(inputstream);

BufferedReader bufferedreader = new BufferedReader(inputstreamreader);

String line;

while ((line = bufferedreader.readLine()) != null) {

System.out.println(line);

}

}
}

Mind you, the code is written exclusively for Windows Machine :) . And one line change in this code will list you only java running process.

String cmds[] = {”cmd”, “/c”, “jps”}; this is nothing but running jps.exe file in bin (jdk6 onwards).

Its not all done. Writing Runtime code is not the real solution as there is little of platform dependencies. So, I have decided to write the code for getting List of Java Process. Again, I have checked by OpenJDK code for jps(search on jps.java file :) ) and I got some hint how to do it and here it goes:

import java.util.*;

import sun.jvmstat.monitor.*;

public class ListJavaProcess {

public static void main(String[] args) throws Exception {

/* Checking for local Host, one can do for remote machine as well */

MonitoredHost local = MonitoredHost.getMonitoredHost(”localhost”);

/* Take all active VM’s on Host, LocalHost here */

Set vmlist = new HashSet(local.activeVms());

for (Object id : vmlist) {

/* 1234 - Specifies the Java Virtual Machine identified by lvmid 1234 on an unnamed host.

This string is transformed into the absolute form //1234, which must be resolved against

a HostIdentifier. */

MonitoredVm vm = local.getMonitoredVm(new VmIdentifier(”//” + id));

/* take care of class file and jar file both */

String processname = MonitoredVmUtil.mainClass(vm, true);

System.out.println(id + ” ——> ” + processname);

}

}
}

I have written good amount of comment as it is all together a sun import rather than java or javax import. This import resides in tools.jar, so even running simple javac and java will not work. So, running the program will go here:

E:Program FilesJavajdk1.6.0_10bin>javac -classpath “E:Program FilesJavajdk1.6.0_10libtools.jar” ListJavaProcess.java

E:Program FilesJavajdk1.6.0_10bin>java -classpath .;”E:Program FilesJavajdk1.6.0_10libtools.jar” ListJavaProcess 3700 ——> ListJavaProcess

Right now only one java process is running. Now in the second code, you can play with some of the java process, but with native process in the above code you can’t do anything except watching it :)

No idea how to do this in JDK 1.5 or backwards(runtime is off course one option). Would love to learn it some other time.

VKC

Sorting is always a tricky game in any programming language and it is responsible for 50-60 percent of the total CPU time for any application. We all have our native language like Hindi, Chinese, Japanese, French and so many. Most of the time world deals with sorting of Alphabets or English words but give a eye on other languages which is growing fast and off course today we are talking about internationalization.

I am showing you a typical sorting of French word and the blunder associated with it. These are some of the common French words:

String[] names = {”fácil”, “facil”, “fast”,”Où”, “êtes-vous”, “spécifique”, “specific”, “ou”};

and here is the typical sorting code:

String[] names = {”fácil”, “facil”, “fast”,”Où”, “êtes-vous”, “spécifique”, “specific”, “ou”};

List list = Arrays.asList(names);

Collections.sort(list);

Iterator itr = list.iterator();

while(itr.hasNext()) {

System.out.print(itr.next()+ ” “);

}

And the result:

Où facil fast fácil ou specific spécifique êtes-vous

which is completely wrong according to French Rules. Because sorting is simply going via UNICODE rules not by French rules.

Now remedy: Java gives us a class called Collator class in java.text Package which takes care of locale while sorting. Here goes the code:

import java.text.*;

import java.util.*;

class CollatorTest {

public static void main(String[] args) {

String[] names = {”fácil”, “facil”, “fast”, “Où”, “êtes-vous”, “spécifique”, “specific”, “ou”};

List list = Arrays.asList(names);

Collections.sort(list);

Iterator itr = list.iterator();

while (itr.hasNext()) {

System.out.print(itr.next() + ” “);

}

Locale[] loc = Collator.getAvailableLocales();

Collator myCollator = Collator.getInstance(new Locale(”fr”));

myCollator.setStrength(Collator.PRIMARY);

Collections.sort(list, myCollator);

itr = list.iterator();

System.out.println(”");

while (itr.hasNext()) {

System.out.print(itr.next() + ” “);

}

myCollator.setStrength(Collator.TERTIARY);

Collections.sort(list, myCollator);

itr = list.iterator();

System.out.println(”");

while (itr.hasNext()) {

System.out.print(itr.next() + ” “);

}

}
}

And here is the result:

Où  facil  fast  fácil  ou  specific  spécifique  êtes-vous

êtes-vous  facil  fácil  fast  Où  ou  specific  spécifique

êtes-vous  facil  fácil  fast  ou  Où  specific  spécifique

which is perfectly valid. There are lot of option in Collator class which we will discuss sometimes later here only. So from now on, sorting other languages is also easy.

Downloading & Installing the JDK

Before you can develop Java applications, you’ll need to download the Java Development Kit (JDK). You may prefer at a later time to use a third party IDE, such as Visual J++ or Borland JBuilder, but it is important to become familiar with the basics of Java first.
Installing the JDK

Sun offers many versions of its JDK, for different Java versions and platforms. You are advised to use the most recent JDK, to gain access to all of the functionality of the latest version of the Java platform. If you don’t already have the JDK installed, then stop off at Sun’s official Java site, http://java.sun.com/.

For an even quicker way to find the latest Java tools, visit the JDK download page, located at http://java.sun.com/jdk/index.html. The most current version at time of writing is the Java 2 SDK v1.3, which contains all the tools you will need for this tutorial.

The installation process is fairly straightforward, but you should consult the documentation if you encounter problems. You’ll need to make sure that the JDK is installed correctly, and that the JDK tools are within your operating system’s path, before proceeding.

In most cases, this involves setting environmental variables. As many first-time Java developers do not have experience in this, we’ll show you how to set these, for the most popular Java development environment — Windows. Macintosh, Unix, and other environments, have their own way of setting environmental variables (for more information consult your operating system documentation).

JavaBeans is a new component architecture for Sun’s Java language. Like the language from which JavaBeans draws its name, it is portable across many platforms; any environment supporting a JDK 1.1 interpreter will be capable of using JavaBeans.
Overview

For Java developers, and amateur applet authors, JavaBeans offers the ability to write applications quickly and easily, by using a palette of components that can be assembled to form a larger application. User-interface components, such as trees, lists, or graphical buttons can make applications come alive, without the need for writing custom components for each and every application. Networking protocols can be encapsulated in a component, allowing developers to simply plug in email and web support into their applications. Literally any component you can imagine can be written as a JavaBean, and then plugged into an application.
Features

* JavaBeans support properties, allowing an application to read and modify their values.
* JavaBeans support events, allowing vendors to create their own unique events.
* JavaBeans support the BeanInfo interface, allowing vendors to specify exactly which properties and methods are available, and icons for beans which can be displayed on a toolbar.
* JavaBeans are highly configurable, and the state of a bean can be saved and restored through ’serialization’.

JavaBeans vs. ActiveX
What is ActiveX?

ActiveX is a competing object technology, developed by Microsoft for its Windows platform. ActiveX objects are similar to the OCX components, and allow vendors to create components that can be used in products such as Visual C++, Visual Basic and Borland Delphi.
How are ActiveX controls created?

ActiveX controls can be created in a variety of languages, such as Visual Basic Control Creation Edition, or Visual C++. The task of creating controls, however, is often more difficult than the simplicity of JavaBeans.
How does Java stack up to ActiveX?

Java stacks up very well indeed! JavaBeans are highly portable, and can run on any platform that has a Java Virtual Machine that is JDK1.1 compliant. ActiveX controls can execute on the Windows platform, and most use Win32 specific calls that would render them unsuitable for automatic porting to other platforms. While ActiveX is now being pushed as an open standard, it will be some time (if ever) before we see truly portable ActiveX controls.

There is also a common misperception amongst developers that JavaBeans can only be used in Java applications, and thus are not integratable with other products, such as Visual Basic and Delphi. This is not so! Any existing JavaBean can be instantly converted into an ActiveX control, through the use of the JavaBeans ActiveX Bridge.

The bridge takes an existing JavaBean, and registers it as an ActiveX control that can be used in any ActiveX compatible application or programming language. Not only is the JavaBean architecture portable across platforms, it’s portable across other languages!
Conclusion

JavaBeans have a significant competitive advantage over ActiveX - JavaBeans can be instantly converted into ActiveX controls via the bridge, but ActiveX controls cannot be easily converted into JavaBeans. JavaBeans also offer the security and robustness that developers have come to know and love, whereas ActiveX controls remain dangerous (despite the innovation of digital signatures), as they have low level access to features of the operating system. JavaBeans used in applets are bound by the same restrictions (file and network access) as their applet hosts, yet ActiveX controls that are signed have a much larger potential to wreak havoc on the system. Coupled with their lack of portability, ActiveX components have a smaller target audience, and there is a perception that they can be dangerous when executed indiscriminately from the web.

For the serious component vendor, or application developer, JavaBeans is an important new technology that must be learnt to stay ahead. ActiveX has its place, for now, but with the introduction of the JavaBeans Bridge, it would be prudent to learn the JavaBeans architecture while it remains in its infancy.

When a programmer writes software, and releases it to the public, he (or she) normally releases a compiled version of the application, that users can run on their own machine. Whether it is a commercial offering, or a free piece of software, the programmer has put a considerable amount of time and effort into producing it. The source code behind software is something private, that the programmer has created. Programmers don’t want people looking for flaws in their software, and they don’t want people to change the title of the software and then redistribute it as someone else’s product. It is for this reason that programmers don’t often release their source code - but few realize that every time you release compiled software, you are also giving people the opportunity to reconstruct the source code!
Software that examines software

Decompilers are programs that analyze compiled code, and from this, reconstruct the original source code. Decompilation and reverse engineering is often prohibited by software license agreements - but this won’t always stop an unscrupulous competitor, or an enthusiastic hacker from analyzing your code. Decompilers are freely available for a variety of languages and platforms, including Java! Read on, and I’ll introduce you to the world of decompilation.
How do they work?

Decompilers work by analyzing the byte code of software, and making educated guesses about the code that created it. Most classes also contain additional debugging information, which can help the decompiler create a more accurate representation of the original source code. This debugging information is invisible to normal users, and many programmers don’t even realize just how much information can be obtained from their classes - but there are ways to protect your code.

Software is available that will strip away debugging information, and even change the names of local and member variables inside your classes. SourceGuard, for example, will rename your variables to meaningless names, which decreases the readability of decompiled source. When you protect your code with applications like SourceGuard, decompilers have less information on which to base their analysis on, and it becomes harder for programmers to understand the code they produce.

// Calculate difference in dates
long numericalDifference = m_Date.getTime()
- currentDate.getTime();

// Divide by 1000 to find number of seconds difference
numericalDifference = numericalDifference / 1000;

// Get seconds
int seconds = (int) numericalDifference % 60;

// Get minutes
numericalDifference = numericalDifference / 60;
int minutes = (int) numericalDifference % 60;

Original source code

l = (this.B.getTime() -
((java.util.Date)(obj)).getTime());
l = (l / 1000);
i4 = (((int)l) % 60);
l = (l / 60);
i3 = (((int)l) % 60);
l = (l / 60);

Source decompiled with Mocha, after SourceGuard protection

The success of decompilation varies upon the amount of protection that software developers use, and the decompiler software that one uses to decompile. Many decompilers fail to decompile correctly, and some will even produce code that won’t compile - particularly when faced with strong protection from a product like SourceGuard which offers a feature called byte-code range modification. BRM prevents most compilers from decompiling methods that have try { } catch blocks, and will produce garbled code with most decompilers.

Preventing decompilation is a valuable feature. Of course, such protection isn’t uncrackable. While there are plenty of free decompilers out there, you really get what you pay for. With free tools, the code that is produced ranges from complex to unusable when protected by a tool that is decompiler resistant. With commercial tools, you can get varying degrees of success, and at least one tool is capable of breaking the byte-code range modification technique of SourceGuard.

SourceAgain, by Ahpah Software Inc, is capable of decompiling BRM protected classes effectively, and produces much more readable code than free software like Mocha or DejaVu. SourceAgain is available in three versions, a standalone decompiler, a professional edition that integrates with Symantec Visual Cafe and Microsoft Visual J++, and a Unix version. For those interested in using decompilers, a trial of SourceAgain is accessible from the web, and it can decompile classes that are accessible from a http:// address.
Uses of decompilers

While decompilers do represent a threat, they also can be of great benefit to programmers. There are many legitimate purposes for decompilers, such as reconstructing lost source code from a binary executable. When an old application needs to be upgraded or modified, and the original source code isn’t available (perhaps the company which commissioned it never received the original source code, or perhaps the source code was lost because it wasn’t considered import enough to backup), reverse engnieering through decompilation can be very useful. Some companies might decompile software of a competitor, to establish the structure of data files to include support for that filetype in their application. Whether or not such actions are legal is a gray area, but including support for competing spreadsheets, word processors, databases, etc is handy for end-users.
Summary

Decompilers aren’t necessarily evil - but they do pose an ethical dilemma for many software developers. You can also protect yourself against decompilation (or at least make the task harder), by using special software that protects your executables from prying eyes. All developers should be aware of the risks of decompilation, and should consider protecting their Java applets and applications against reverse engineering. Decompilers offer great potential for legitimate purposes, but can also be used to steal the source code of competitors, or by hackers to determine weaknesses in the design of software. But just don’t blame the compiler - its the programmer who uses it for intellectual property theft, or the hacker that decompiles the software to find security holes that is at fault!

CORBA, for those who haven’t heard of it before, stands for Common Object Request Broker Architecture. This architecture allows clients to invoke methods of objects running on remote servers. The idea is nothing new - many developers will have come across similar systems such as RPC (remote procedure call), or Java’s own RMI (remote method invocation). The difference between these and CORBA is that CORBA is much more interoperable with other platforms - a C++ object running on a Wintel system can communicate with a Java object on a Unix box. Developers don’t need to know what language a CORBA service is written in, or even where it is physically located. This makes CORBA systems very versatile - one can change the location of a CORBA object, and then re-register with a nameserver. Clients that look up the service can then find its new location, and then continue to make requests. Java makes it easy to integrate support for CORBA into applications and applets, thanks to the introduction of Java IDL in JDK1.2
Interface Definition Language (IDL)

Developers use the Interface Definition Language (IDL) to describe the interface to a CORBA object. An IDL schema can then be used to generate Java code for the client and server that will use the object. The same IDL schema could be used to generate either a client or server in C++, Ada, or any other language that supports CORBA. You don’t write your implementation of a CORBA service in IDL - so you can continue to write in pure Java code if you so wish.

Let’s start by taking a look at a sample IDL schema, to give you an idea what I’m talking about. The following schema shows a very simple CORBA service, which allows clients to get and store the name associated with an email address. For the purposes of this example, we won’t worry about modifying or deleting an existing user.

// Address book system module
module address_book_system
{
// Specify interface to our address book
interface address_book
{
// Unknown user exception
exception unknown_user {};

// User already exists exception
exception user_exists {};

// Lookup name from email address
string name_from_email(in string email)
raises (unknown_user);

// Lookup email from full name
string email_from_name(in string name)
raises (unknown_user);

// Record a new name and email
void record_user(in string name, in string email)
raises user_exists;
};
};

Listing 1-0 AddressBook.idl

We start by declaring a module for our address book system (modules can be mapped to Java packages). Inside the module, we declare our interfaces and the exceptions they can raise. Since its such as simple system, the methods of the interface will only return a string, but we can create more complex return values if needed. As well as returning values, we accept as input two strings for our record_user method. As you can see, IDL really isn’t to hard to pick up.

Once you’ve written your interface using IDL, you can then begin to write client and servers in the language of the choice. We’ll choose Java for now, but there’s no reason why the client or the server couldn’t be written in another language. Provided you have an interface in IDL format, you could write code that interacts with the object it describes.
From IDL to Java

Converting an IDL schema into Java source code is quite straightforward. Sun provides a free tool, idltojava, that creates the source code for you. This tool is currently distributed separately to JDK 1.2, but is freely available for members of the Java Developer Connection.

idltojava -fno-cpp AddressBook.idl

Based on the name of your IDL schema’s module, a package will be generated that contains skeleton source code for your CORBA client and server, as well a second package to cover our two exceptions. The following is a list of the files it creates for us

\address_book_system\

_address_bookStub.java
address_book.java
address_bookHolder.java
address_bookHelper.java
address_bookPackage
_address_bookImplBase.java

address_bookPackage\
unknown_user.java
unknown_userHelper.java
unknown_userHolder.java
user_exists.java
user_existsHelper.java
user_existsHolder.java

As you can see, there are a lot of files! Fortunately, we only need three to implement a complete CORBA client and server. The first file is a servant, which serves the requests made by clients. The second is a server, which will accept requests, and the third is a standalone application which will issue requests.
Implementing a CORBA Servant

Under CORBA, a servant is responsible for handling service requests. When we ran the idltojava tool, an abstract class was created that handles most of the hard work for us. All we need to do is create an AddressBookServant class, that implements the _address_bookImplBase. It will contain the code for our three methods described in the IDL schema.

skip to next section

package address_book_system;
import  address_book_system.address_bookPackage.*;

import  java.util.Hashtable;
import  java.util.Enumeration;
//
//
// AddressBookServant
//
// This servant class is responsible for implementing
// three methods
//
//   * String name_from_email ( String email );
//   * String email_from_name ( String name  );
//   * void   record_user ( String name, String email );
//
//
class AddressBookServant extends _address_bookImplBase
{
private Hashtable name2email;

public AddressBookServant()
{
// Create a new hashtable to store name & email
name2email = new Hashtable();
}

// Get the name of this email user
public String name_from_email ( String email )
throws unknown_user
{
if (name2email.contains(email))
{
// Begin search for that name
for (Enumeration e = name2email.keys();
e.hasMoreElements();)
{
String name = (String) e.nextElement();
String e_mail = (String) name2email.get(name);

// Match on email ?
if (email.compareTo(e_mail) == 0)
{
return name;
}
}
}

// User not found - throw unknown user exception
throw new unknown_user();
}

// Get the email of this person
public String email_from_name ( String name  )
throws unknown_user
{
// If user exists
if (name2email.containsKey(name))
{
// Return email address
return (String) name2email.get(name);
}

// User doesn’t exist
throw new unknown_user();
}

// Add a new user to the system
public void record_user ( String name, String email )
throws user_exists
{
// Is the user already listed
if (name2email.containsKey( name ) ||
name2email.contains( email ) )
{
// If so, throw exception
throw new user_exists();
}

// Add to our hash table
name2email.put (name, email);
}
}

The servant class maintains a list of people’s email addresses, and stores this information inside a Hashtable. When the CORBA server receives a request, it will call upon the name_from_email, email_from_name, and record_user methods of the servant to fulfill the request.
Writing a CORBA server

Writing a CORBA server is pretty straightforward. We need to create an ORB (object-request-broker), and register our servant with it. We’ll also notify a nameserver of our ORB, so that CORBA clients can access our address book. Once we’ve registered, CORBA clients will be able to look for our interface, and send requests through our ORB to the servant object.

skip to next section

package address_book_system;
import org.omg.CORBA.*;
import org.omg.CosNaming.*;
import org.omg.CosNaming.NamingContextPackage.*;

//
//
// AddressBookServer
//
// This server is responsible for creating an object
// request broker (ORB), and registering an AddressBookServant
// with a naming service
//
//
public class AddressBookServer
{
public static void main(String args[])
{
try
{
// Create a new object request broker
ORB orb = ORB.init(args, null);

// Create a new address book …
AddressBookServant servant = new AddressBookServant();

// … and connect it to our orb
orb.connect(servant);

// Object Request Broker Initialised
System.out.println (”Address book ORB initialised”);

// Obtain reference for our nameservice
org.omg.CORBA.Object object =
orb.resolve_initial_references(”NameService”);

// Since we have only an object reference, we must
// cast it to a NamingContext. We use a helper
// class for this purpose
NamingContext namingContext =
NamingContextHelper.narrow(object);

// Add a new naming component for our interface
NameComponent list[] =
{ new NameComponent(”address_book”, “”) };

// Now notify naming service of our new interface
namingContext.rebind(list, servant);

// Wait for clients
for (;;){}
}
catch (Exception e)
{
System.err.println (”ORB Error - ” + e);
e.printStackTrace(System.out);
System.exit(0);
}
}
}

Writing a CORBA client

Now that we have a finished server, we need to write a client to show that the server works. Our client is very simple. It looks up our AddressBook service through a naming service, and then sends requests in response to commands made by the user. The client also traps exceptions thrown by the AddressBook service, in the event that a user’s details doesn’t exist or that a duplicate is being inserted into the system.

skip to next section

package address_book_system;
import address_book_system.address_bookPackage.*;

import org.omg.CORBA.*;
import org.omg.CosNaming.*;
import java.io.*;

//
//
// AddressBookClient
//
// This client demonstrates the AddressBook server and servant.
// A menu is presented to the user, allow he or she to add
// users, and look up their names & email addresses
//
//
public class AddressBookClient
{
public static void main(String args[]) throws IOException
{
try
{
// Create an object request broker
ORB orb = ORB.init(args, null);

// Obtain object reference for name service …
org.omg.CORBA.Object object =
orb.resolve_initial_references(”NameService”);

// … and narrow it to a NameContext
NamingContext namingContext =
NamingContextHelper.narrow(object);

// Create a name component array
NameComponent nc_array[] =
{ new NameComponent(”address_book”,”") };

// Get an address book object reference …
org.omg.CORBA.Object objectReference =
namingContext.resolve(nc_array);

// … and narrow it to get an address book
address_book AddressBook =
address_bookHelper.narrow(objectReference);

// DataInputStream for system.in
DataInputStream din = new DataInputStream
(System.in);

for (;;)
{
try
{
// Print menu
System.out.println (”1- Add user”);
System.out.println (”2- Look up email”);
System.out.println (”3- Look up name”);
System.out.println (”4- Exit”);

System.out.print (”Command :”);

// Read a line from user
String command = din.readLine();

// Convert to number
Integer num = new Integer (command);
int choice = num.intValue();

// Variables we’ll need for service calls
String name;
String email;

switch (choice)
{
case 1:
System.out.print (”Name:”);
name  = din.readLine();
System.out.print (”Email:”);
email = din.readLine();

// Call AddressBook service
AddressBook.record_user(name,email);
break;

case 2:
System.out.println (”Name:”);
name  = din.readLine();

// Call AddressBook service
email = AddressBook.email_from_name(name);
System.out.println (”Email of ” + name + ” is ” + email);
break;

case 3:
System.out.println (”Email:”);
email  = din.readLine();

// Call AddressBook service
name = AddressBook.name_from_email(email);
System.out.println (”Name of ” + email + ” is ” + name);
break;

case 4:
System.exit(0);
}
}
catch (user_exists  already_there)
{
System.out.println (”User already exists - cannot be added to address book”);
}
catch (unknown_user bad_user)
{
System.out.println (”User doesn’t exist”);
}
}
}
catch (Exception e)
{
System.err.println (”CORBA error - ” + e);
}
}
}

Putting it all together

Now that we have a CORBA server and a CORBA client, the next step is to have the client connect to the server. If you’ve already compiled the source code, then you’re ready to begin. Otherwise, download the source code (available as a .ZIP file), and extract it to its own directory.

Next, you need to do the following :

1. Start the nameservice that comes with JDK1.2
2. Start the server
3. Start the client

Start the nameservice that comes with JDK1.2

If your Java installation directory is in the path, you can type the following from your prompt

tnameserv -ORBInitialPort 2000

The port parameter is necessary for Unix users who aren’t logged it as root. Windows users can omit the parameter. If you do specify a port parameter, make sure you do so for the client and server as well.
Start the server

All of the examples are part of the address_book_system package. Some users have reported problems running the examples. Make sure that the current directory is in the classpath, and then go to the directory where you’ve compiled the examples, or where you’ve unzipped them. Next, start the server

java address_book_system.AddressBookServer
-ORBInitialPort 2000
-ORBInitialHost myhost

The port parameter is optional (but needed if you’ve specified a port for your nameservice). You’ll also need to specify the hostname if you run the server on a different machine to the nameservice (omit it if running everything locally).
Start the client

You’ll need to go to the directory where the examples are stored. Make sure that the nameservice and server are already running, and then start the client

java address_book_system.AddressBookClient -ORBInitialPort 2000
-ORBInitialHost myhost

The port parameter is optional (but needed if you’ve specified a port for your nameservice). You’ll also need to specify the hostname if you run the client on a different machine to the nameservice (omit it if running everything locally).
Running the client

The client is capable of invoking all the methods defined in our IDL. It can record new users, look up an email address, and look up a name. While the demonstration is relatively simple, it does show how easy it is to write clients that interact with services on remote systems. This demo is a standalone application, but you could just as easily write an applet that implemented the same functionality.

1- Add user
2- Look up email
3- Look up name
4- Exit
Command :1
Name: David Reilly
Email: dodo@fan.net.au
1- Add user
2- Look up email
3- Look up name
4- Exit
Command :2
Name:
David Reilly
Email of David Reilly is dodo@fan.net.au

Summary

CORBA technology offers developers many benefits over other techniques for distributed computing, but its most compelling is the ease with which developers can create distributed services that are platform independent. Once a service is described by an IDL schema, the developer can choose to implement either client or server (or both) in Java. Being able to use Java is an attractive option, because Java brings platform portability - but its nice to know that one can also connect a C++ module to Java. CORBA allows developers to connect objects together, and developers can still choose the versatility and familiarity of Java.

A further advantage is that CORBA services can be moved throughout the network or intranet. Java 1.2 includes a nameservice, which allows ORBs to register (or bind) their services. This means that services can be moved from system to system as needed, and that clients don’t need to be aware of the physical location of the service. CORBA is a powerful technology for distributed computing, and the introduction of support for CORBA in JDK1.2 offers developers  greater freedom when they create distributed systems.

Overview

Remote Method Invocation (RMI) facilitates object function calls between Java Virtual Machines (JVMs). JVMs can be located on separate computers - yet one JVM can invoke methods belonging to an object stored in another JVM. Methods can even pass objects that a foreign virtual machine has never encountered before, allowing dynamic loading of new classes as required. This is a powerful feature!

Consider the follow scenario :

  • Developer A writes a service that performs some useful function. He regularly updates this service, adding new features and improving existing ones.
  • Developer B wishes to use the service provided by Developer A. However, it’s inconvenient for A to supply B with an update every time.

Java RMI provides a very easy solution! Since RMI can dynamically load new classes, Developer B can let RMI handle updates automatically for him. Developer A places the new classes in a web directory, where RMI can fetch the new updates as they are required.

rmidiagr.gif (6734 bytes)
Figure 1 - Connections made when client uses RMI

Figure 1 shows the connections made by the client when using RMI. Firstly, the client must contact an RMI registry, and request the name of the service. Developer B won’t know the exact location of the RMI service, but he knows enough to contact Developer A’s registry. This will point him in the direction of the service he wants to call..

Developer A’s service changes regularly, so Developer B doesn’t have a copy of the class. Not to worry, because the client automatically fetches the new subclass from a webserver where the two developers share classes. The new class is loaded into memory, and the client is ready to use the new class. This happens transparently for Developer B - no extra code need to be written to fetch the class.

Writing RMI services

Writing your own RMI services can be a little difficult at first, so we’ll start off with an example which isn’t too ambitious. We’ll create a service that can calculate the square of a number, and the power of two numbers (238 for example). Due to the large size of the numbers, we’ll use the java.math.BigInteger class for returning values rather than an integer or a long.

Writing an interface

The first thing we need to do is to agree upon an interface, An interface is a description of the methods we will allow remote clients to invoke. Let’s consider exactly what we’ll need.

  1. A method that accepts as a parameter an integer, squares it, and returns a BigInteger
    public BigInteger square ( int number_to_square );
  2. A method that accepts as a parameter two integers, calculates their power, and returns a BigInteger
    public BigInteger power ( int num1, int num2 );

Once we’ve decided on the methods that will compose our service, we have to create a Java interface. An interface is a method which contains abstract methods; these methods must be implemented by another class. Here’s the source code for our service that calculates powers.

import java.math.BigInteger;
import java.rmi.*;

//
// PowerService Interface
//
// Interface for a RMI service that calculates powers
//
public interface PowerService extends java.rmi.Remote
{
// Calculate the square of a number
public BigInteger square ( int number )
throws RemoteException;

// Calculate the power of a number
public BigInteger power  ( int num1, int num2)
throws RemoteException;
}

Our interface extends java.rmi.Remote, which indicates that this is a remote service. We provide method definitions for our two methods (square and power), and the interface is complete. The next step is to implement the interface, and provide methods for the square and power functions.
Implementing the interface

Implementing the interface is a little more tricky - we actually have to write the square and power methods! Don’t worry if you’re not sure how to calculate squares and powers, this isn’t a math lesson. The real code we need to be concerned about is the constructor and main method.

We have to declare a default constructor, even when we don’t have any initialization code for our service. This is because our default constructor can throw a java.rmi.RemoteException, from its parent constructor in UnicastRemoteObject. Sound confusing? Don’t worry, because our constructor is extremely simple.

public PowerServiceServer () throws RemoteException
{
super();
}

Our implementation of the service also needs to have a main method. The main method will be responsible for creating an instance of our PowerServiceServer, and registering (or binding) the service with the RMI Registry. Our main method will also assign a security manager to the JVM, to prevent any nasty surprises from remotely loaded classes. In this case, a security manager isn’t really needed, but in more complex systems where untrusted clients will be using the service, it is critical.

public static void main ( String args[] ) throws Exception
{
// Assign a security manager, in the event that dynamic
// classes are loaded
if (System.getSecurityManager() == null)
System.setSecurityManager ( new RMISecurityManager() );

// Create an instance of our power service server …
PowerServiceServer svr = new PowerServiceServer();

// … and bind it with the RMI Registry
Naming.bind (”PowerService”, svr);

System.out.println (”Service bound….”);
}

Once the square and power methods are added, our server is complete. Here’s the full source code for the PowerServiceServer.

import java.math.*;
import java.rmi.*;
import java.rmi.server.*;

//
// PowerServiceServer
//
// Server for a RMI service that calculates powers
//
public class PowerServiceServer extends UnicastRemoteObject
implements PowerService
{
public PowerServiceServer () throws RemoteException
{
super();
}

// Calculate the square of a number
public BigInteger square ( int number )
throws RemoteException
{
String numrep = String.valueOf(number);
BigInteger bi = new BigInteger (numrep);

// Square the number
bi.multiply(bi);

return (bi);
}

// Calculate the power of a number
public BigInteger power ( int num1, int num2)
throws RemoteException
{
String numrep = String.valueOf(num1);
BigInteger bi = new BigInteger (numrep);

bi = bi.pow(num2);

return bi;
}

public static void main ( String args[] ) throws Exception
{
// Assign a security manager, in the event that dynamic
// classes are loaded
if (System.getSecurityManager() == null)
System.setSecurityManager ( new RMISecurityManager() );

// Create an instance of our power service server …
PowerServiceServer svr = new PowerServiceServer();

// … and bind it with the RMI Registry
Naming.bind (”PowerService”, svr);

System.out.println (”Service bound….”);
}
}

Writing a RMI client

What good is a service, if you don’t write a client that uses it? Writing clients is the easy part - all a client has to do is call the registry to obtain a reference to the remote object, and call its methods. All the underlying network communication is hidden from view, which makes RMI clients simple.

Our client must first assign a security manager, and then obtain a reference to the service. Note that the client receives an instance of the interface we defined earlier, and not the actual implementation. Some behind-the-scenes work is going on, but this is completely transparent to the client.

// Assign security manager
if (System.getSecurityManager() == null)
{
System.setSecurityManager   (new RMISecurityManager());
}

// Call registry for PowerService
PowerService service = (PowerService) Naming.lookup
(”rmi://” + args[0] + “/PowerService”);

To identify a service, we specify an RMI URL. The URL contains the hostname on which the service is located, and the logical name of the service. This returns a PowerService instance, which can then be used just like a local object reference. We can call the methods just as if we’d created an instance of the remote PowerServiceServer ourselves.

// Call remote method
System.out.println    (”Answer : ” + service.square(value));

// Call remote method
System.out.println    (”Answer : ” + service.power(value,power));

Writing RMI clients is the easiest part of building distributed services. In fact, there’s more code for the user interface menu in the client than there is for the RMI components! To keep things simple, there’s no data validation, so be careful when entering numbers. Here’s the full source code for the RMI client.

import java.rmi.*;
import java.rmi.Naming;
import java.io.*;

//
//
// PowerServiceClient
//
//
public class PowerServiceClient
{
public static void main(String args[]) throws Exception
{
// Check for hostname argument
if (args.length != 1)
{
System.out.println
(”Syntax - PowerServiceClient host”);
System.exit(1);
}

// Assign security manager
if (System.getSecurityManager() == null)
{
System.setSecurityManager
(new RMISecurityManager());
}

// Call registry for PowerService
PowerService service = (PowerService) Naming.lookup
(”rmi://” + args[0] + “/PowerService”);

DataInputStream din = new
DataInputStream (System.in);

for (;;)
{
System.out.println
(”1 - Calculate square”);
System.out.println
(”2 - Calculate power”);
System.out.println
(”3 - Exit”); System.out.println();
System.out.print (”Choice : “);

String line = din.readLine();
Integer choice = new Integer(line);

int value = choice.intValue();

switch (value)
{
case 1:
System.out.print (”Number : “);
line = din.readLine();System.out.println();
choice = new Integer (line);
value  = choice.intValue();

// Call remote method
System.out.println
(”Answer : ” + service.square(value));

break;
case 2:
System.out.print (”Number : “);
line = din.readLine();
choice = new Integer (line);
value  = choice.intValue();

System.out.print (”Power  : “);
line = din.readLine();
choice = new Integer (line);
int power = choice.intValue();

// Call remote method
System.out.println
(”Answer : ” + service.power(value, power));

break;
case 3:
System.exit(0);
default :
System.out.println (”Invalid option”);
break;
}
}
}

}

Running the client and server

Our example was extremely simple. More complex systems, however, might contain interfaces that change, or whose implementation changes. To run this article’s examples, both the client and server will have a copy of the classfiles, but more advanced systems might share the code of the server on a webserver, for downloading as required. If your systems do this, don’t forget to set the system property java.rmi.server.codebase to the webserver directory in which your classes are stored!

You can download all the source and class files together as a single ZIP file. Unpack the files into a directory, and then perform the following steps.

1.
Start the rmiregistry

To start the registry, Windows users should do the following (assuming that your java\bin directory is in the current path):-

start rmiregistry

To start the registry, Unix users should do the following:-

rmiregistry &
2.
Compile the server

Compile the server, and use the rmic tool to create stub files.
3.
Start the server

From the directory in which the classes are located, type the following:-

java PowerServiceServer

4.
Start the client

You can run the client locally, or from a different machine. In either case, you’ll need to specify the hostname of the machine where you are running the server. If you’re running it locally, use localhost as the hostname.

java PowerServiceClient localhost

TIP - If you running the client or server with JDK1.2, then you’ll need to change the security settings. You’ll need to specify a security policy file (a sample is included with the source code and classes) when you run the client and server.

The following changes should be made when running the server

java -Djava.security.policy=java.policy PowerServiceServer

The following changes should be made when running the client

java -Djava.security.policy=java.policy PowerServiceClient localhost
Summary

Java RMI is a useful mechanism for invoking methods of remote objects. Java RMI allows one Java Virtual Machine to invoke methods of another, and to share any Java object type, even if client or server has never come across that object type before.

With the introduction of CORBA support to Java (as of version 1.2), developers now face the question of whether to continue to use remote method invocation (RMI), or make a move to CORBA. The choice is made more difficult if your applications are already written in RMI - considerable effort might have to be made to convert to CORBA. Is it worth the move? This article discusses the pros and cons, and evaluates the potential of these two technologies.

What is Remote Method Invocation?

Remote method invocation allows Java developers to invoke object methods, and have them execute on remote Java Virtual Machines (JVMs). Under RMI, entire objects can be passed and returned as parameters, unlike many remote procedure call based mechanisms which require parameters to be either primitive data types, or structures composed of primitive data types. That means that any Java object can be passed as a parameter - even new objects whose class has never been encountered before by the remote virtual machine.

This is an exciting property, because it means that new code can be sent across a network and dynamically loaded at run-time by foreign virtual machines. Java developers have a greater freedom when designing distributed systems, and the ability to send and receive new classes is an incredible advantage. Developers don’t have to work within a fixed codebase - they can submit new classes to foreign virtual machines and have them perform different tasks. When working with remote services, RMI clients can access new versions of Java services as they are made available - there’s no need to distribute code to all the clients that might wish to connect. While code can be accessed from a local or remote file-system, it can also be accessed via a web server, making distribution easier. RMI also supports a registry, which allows clients to perform lookups for a particular service. The following diagram shows the interaction between different components of an RMI system. Clients that know about a service can look up its location from a registry and access the service. If a new class is required, it can be downloaded from a web server.

rmidiagr.gif (6734 bytes)

Client connects to a registry server, accesses a RMI service, and downloads new code as required from a web server.

Remote method invocation has a lot of potential, from remote processing and load sharing of CPU’s to transport mechanisms for higher level tasks, such as mobile agents which execute on remote machines . Because of the flexibility of remote method invocation, it has become an important tool for Java developers when writing distributed systems. However, there are many legacy systems written in C/C++, Ada, Fortran, Cobol, and other exotic languages. If legacy systems need to interface with your RMI systems, or your RMI systems need to interface with them, problems can occur. RMI is Java specific, and you’ll need to write a bridge between older systems. Additionally, if you or your company plans on using other languages in the future, you may also find yourself in a bind because of RMI’s tie to Java - one day Java itself may become a legacy platform. Writing interfaces to legacy systems isn’t my idea of fun programming!

What is CORBA?

Common Object Request Broker Architecture (CORBA) is a competing distributed systems technology that offers greater portability than remote method invocation. Unlike RMI, CORBA isn’t tied to one language, and as such, can integrate with legacy systems of the past written in older languages, as well as future languages that include support for CORBA. CORBA isn’t tied to a single platform (a property shared by RMI), and shows great potential for use in the future. That said, for Java developers, CORBA offers less flexibility, because it doesn’t allow executable code to be sent to remote systems.

CORBA services are described by an interface, written in the Interface Definition Language (IDL). IDL mappings to most popular languages are available, and mappings can be written for languages written in the future that require CORBA support. CORBA allows objects to make requests of remote objects (invoking methods), and allows data to be passed between two remote systems. Remote method invocation, on the other hand, allows Java objects to be passed and returned as parameters. This allows new classes to be passed across virtual machines for execution (mobile code). CORBA only allows primitive data types, and structures to be passed - not actual code.

Under communication between CORBA clients and CORBA services, method calls are passed to Object Request Brokers (ORBs). These ORBs communicate via the Internet Inter-ORB Protocol (IIOP). IIOP transactions can take place over TCP streams, or via other protocols (such as HTTP), in the event that a client or server is behind a firewall. The following diagram shows a client and a servant communicating.

corba.gif (7788 bytes) corba2.gif (7735 bytes)
CORBA client sends a request through its local ORB to a remote ORB’s servant CORBA servant sends back a response to a remote ORB

RMI vs CORBA

Comparing RMI and CORBA doesn’t reveal an optimum solution - one is not “better” than the other. The properties of these two technologies lend themselves to different situations. A comparison of RMI and CORBA helps to highlight individual strengths and weaknesses, but the applicability of one technology over the other depends largely on the purposes for which it is to be used, the experience of the developers who will design, implement and maintain the distributed system, and whether non-Java systems are intended to access the system now or in the future.

RMI pros and cons

Remote method invocation has significant features that CORBA doesn’t possess - most notably the ability to send new objects (code and data) across a network, and for foreign virtual machines to seamlessly handle the new objects . Remote method invocation has been available since JDK 1.02, and so many developers are familiar with the way this technology works, and organizations may already have systems using RMI. Its chief limitation, however, is that it is limited to Java Virtual Machines, and cannot interface with other languages.

Remote method invocation

Pros Cons
Portable across many platforms Tied only to platforms with Java support
Can introduce new code to foreign JVMs Security threats with remote code execution, and limitations on functionality enforced by security restrictions
Java developers may already have experience with RMI (available since JDK1.02) Learning curve for developers that have no RMI experience is comparable with CORBA
Existing systems may already use RMI - the cost and time to convert to a new technology may be prohibitive Can only operate with Java systems - no support for legacy systems written in C++, Ada, Fortran, Cobol, and others (including future languages).

CORBA pros and cons

CORBA is gaining strong support from developers, because of its ease of use, functionality, and portability across language and platform . CORBA is particularly important in large organizations, where many systems must interact with each other, and legacy systems can’t yet be retired. CORBA provides the connection between one language and platform and another - its only limitation is that a language must have a CORBA implementation written for it. CORBA also appears to have a performance increase over RMI, which makes it an attractive option for systems that are accessed by users who require real-time interaction

Common Object Request Broker Architecture

Pros Cons
Services can be written in many different languages, executed on many different platforms, and accessed by any language with an interface definition language (IDL) mapping. Describing services require the use of an interface definition language (IDL) which must be learned. Implementing or using services require an IDL mapping to your required language - writing one for a language that isn’t supported would take a large amount of work.
With IDL, the interface is clearly separated from implementation, and developers can create different implementations based on the same interface. IDL to language mapping tools create code stubs based on the interface - some tools may not integrate new changes with existing code.
CORBA supports primitive data types, and a wide range of data structures, as parameters CORBA does not support the transfer of objects, or code.
CORBA is ideally suited to use with legacy systems, and to ensure that applications written now will be accessible in the future. The future is uncertain - if CORBA fails to achieve sufficient adoption by industry, then CORBA implementations become the legacy systems.
CORBA is an easy way to link objects and systems together Some training is still required, and CORBA specifications are still in a state of flux.
CORBA systems may offer greater performance Not all classes of applications need real-time performance, and speed may be traded off against ease of use for pure Java systems.

Summary

An examination of these two technologies shows that, while they do overlap in functionality to some degree, they each possess strengths that outshine the other for particular tasks. A careful evaluation of the intended use of RMI or CORBA is required, to determine which technology is the most appropriate. There aren’t any hard and fast rules that can be applied, and there is no clear victor in the battle for the minds and hearts of developers. Time will tell which technology (if any) becomes the more dominant, and in the immediate future both will continue to play a role.

Okay. When I first read about the Java TV API last year, I thought the idea of Java running on set-top boxes was quite amusing. After all, we’ve all had the experience of slow loading applets running inside web-browsers, that amount to little more than eye-candy for the easily amused. Certainly, there are some serious Java applets out there, but they’re few and far between, and with cross-browser compatibility issues, limited in their audience reach.

Then the enormity of it hit me - while the number of computers in households is still small, and the number of Internet users even more so, the number of people with television sets is MASSIVE. This one concept has the potential to introduce the word “Java” to hundreds of millions of people world-wide. Digital TV may be slow to get a foothold, but it’s almost a certainty.  Now imagine all those people running Java applications (or applets) right from their television. High bandwidth HDTV or cable connections could be integrated with interactive Java content, ranging from simple games, stock tickers, and online shopping. The scope of the Java TV API is very big indeed.

The Java TV API is designed to allow Java applications access to the functionality of the television host on which it runs. Through the Java TV API, which will provide access to television programming content (de-multiplexed on-the-fly), content selection (program guides), and control over the television screen appearance. Applications can run on a Java Virtual Machine (JVM) designed for set-top boxes, televisions, and real-time devices. The underlying hardware details are abstracted away, leaving developers free to concentrate on developing interactive content, not porting it from one system to another.

Java TV Overview

Here’s where Java technology comes into its own. Not only is it portable, not only is there an existing code base to work with and familiarity amongst developers, but it will be easy to move applications from one system to another. That means consumers (and cable companies) won’t be left with antiquated systems that can only run a small range of software.

Integrated with the Java TV API will be other related technologies. For example, Java already has support for decoding and processing multimedia content, through the Java Media Framework. New decoders for television content can be added, as well as existing mechanisms such as MPEG. Imagine a high speed cable network that allows audio playback of MP3 music! As new content streaming formats are developed, applets can gain access to decoders as they are added to the JMF. This means that set-top software doesn’t need to be manually updated - new formats can be downloaded on-the-fly.

The Java TV API has the potential to revolutionize the Java landscape. Sure Java made inroads into browsers, and is having increasing success in the server-side market, but imagine the potential of set-top boxes all around the world running Java. That’s a big market for Sun, for cable and television companies, and for software developers.

Next Page »