James Cook

Greenhorn
+ Follow
since Jun 13, 2002
Merit badge: grant badges
For More
Cows and Likes
Cows
Total received
In last 30 days
0
Forums and Threads

Recent posts by James Cook

Hi All,
I got notified about my pass at the end of September, and have been busy researching into what is required for the J2EE Architect's Certification since, so rather busy for posting my results into here.
Nevertheless it's fair to say, Flight Booking Systems will never be the same!
Thanks to everyone here, particularly Michael Ernest who answered some interesting questions I posed about how the RMI Registry and the RMI Daemon work together.
Thanks to all those too, who gave advice on books etc. to read for the Architect's Certification. I shall be following these up over the next few months.
This is definitely the best independent Java site there is.
Cheers all,
James
Sun Certified Java 2 Platform Developer
22 years ago
Make sure you have a new RMISecurityManager set up or you will only be able to load local classes on your classpath.
Net.socketpermission needs to be at least listen, accept, connect, giving the name of the DNS to which you are accessing
e.g. put into a file called, say mypolicy.txt
grant
{
permission java.net.SocketPermission "localhost:1024-", "listen,accept,connect";
};
where the 1024- means port 1024 or higher (unprivileged ones, in other words). If you don't specify a port, it applies to all ports.
You also need to specify the security policy filename you are using as a System property to the program e.g.
java -Djava.security.policy=file:///C:/jre/lib/security/mypolicy.txt program_name
Hope these pointers help.
Cheers, James.
Sun Certified Java 2 Developer.
22 years ago
Hello All,
Now that I have successfully obtained Java 2 Developer Certification (with 89%, so I was quite pleased about it), I am intending to go for the J2EE Enterprise Architect Certification and wondered if you all could recommend a good set of books to study for it with. All suggestions gratefully considered!
Thanks,
James
Sun Certified Java 2 Developer.
The session ID idea is not so good if the user's web browser crashes whilst editing. This is because the session is persisted to the database and could still be registered until it expires (this is normally programmed for when the browser exits, but may not be the case if the browser has terminated abnormally). Also you need to ensure the webserver does not issue a new session if the user comes off the page and back onto it whilst updating.
Optimistic locking (i.e. update counters etc.) is a much better approach for non-realtime updating. It suffers from the disadvantage if there is a lot of frequent editing, that another user could have updated the record before you have managed to commit the changes. This then requires you to reread the record (to pick up the new update counter) and re-enter the change. Random counters are not reliable since the generator may pick a number which has already been used. Incrementing the counter by 1 each time is much better and also gives free statistics on how often the record has been updated. Note that add operations always put a new entry on with update counter = 0, and that the check is ONLY done on update. In this way, you do not have to create lock systems (with potential dead locks). However, this does not work very well for realtime apps, because in this case you want the changes to be cumulative (e.g. booking airline seats), and constantly re-reading the record is counterproductive. In this case you want a lock for editing, but you should try to optimise it (depending on your needs) so that the lock is only taken out for the duration of the update and not whilst the user is thinking about what data to change.
22 years ago
JSP
Having just submitted my project successfuly today, I think I can answer these.
your object and hostname are being accessed from your static main() method. This is not allowed: static methods can ONLY access class variables (i.e. fellow statics), becuase there is no this.
When you pass parameters, for them to be recognized by RMI at all, they must fall into one of the following 2 categories:-
a) they must be remote objects, or if not,
b) they must be serializable (i.e. implement the Serializable Marker Interface).
Any parameters passed or retrieved which don't satisfy either of these criteria will fail.
The remote objects get passed by "reference" i.e. the receiver receives a stub which communicates with the actual object on the other side of the wire, whereas the serializable ones get passed by "value" i.e. they're serialized at the sending end and deserialized at the receiving end which is thus a copy.
Hope these comments help.
22 years ago
If you are not going to use callback notification - and I can see why because this will flash up a message at a random interval of time according to when the server has successfully completed your operation, which might not be when you want to display it in the Client, then the way to do it, I think is to have the Server throw an Exception if the operation fails.
then, you wrap the client code (inside the button event handler) in a try block, something like this:-
try
{
call serverMethod();
JOptionPane.showMessageDialog("Operation completed successfully", "", JOptionPane.INFORMATION_MESSAGE); // check the syntax for me!!!
// or you could print to the client's console here instead
}
catch(ServerMethodFailureException a)
{
// display some error either in a JOptionPane, or on the console
}
hope this helps.
22 years ago
When you want to get rmi working in a test environment, it's a good idea to follow Sun's advice in the RMI tutorials i.e. set up a policy file which consists of the following
grant
{
permission java.net.AllPermission;
};
not sure if I've got the syntax absolutely spot-on from off of the top of my head, but use the policytool.exe and that will give you the right syntax etc.
The effect of this is to turn OFF ALL security issues and allows you to concentrate on getting the RMI bits working without having security issues getting not only in your hair, but also in your eyes, teeth, ears and nose etc. Remember the security system is in place to stop hackers and it does a pretty good job. But it also treats innocent grafters like yourself as the most heinous criminals of all and will thwart every character of your code it can.
When you have RMI working the way you want it, you can start applying permission restrictions until it stops working anymore and then you know you've gone far enough!!
If you want to shortcut this process, you can, but you need to gen up on the Security system a great deal before you will get it working for you, rather than the other way round.
22 years ago
Goodness, yes you're quite right!
Forte Version 3 had all the RMI support you needed but Forte Version 4 has dropped the lot.
I'm afraid you've no option but to either run RMI from the command line (not difficult, but a bit of a pain! :-) ), change back to Forte Version 3 (if you have a copy), or pay lots of bucks and upgrade to the Enterprise edition (mega ouch!!!)
Since RMI is strictly part of the Standard SDK, I think this is a major mistake. Oh dear!
22 years ago
Yes I can understand that the Registry is listening for stubs and that RMID is waiting for requests to activate Activatables.
What I am asking is: why does the Tutorial advise you to start RMIRegistry and then RMID, when RMID has its own Registry?
I have an Activatable server that does NOT use a *separate* RMIRegistry program at all. It merely uses the RMI Registry contained internally inside RMID. Needless to say, it works absolutely fine, activating stubs and doing Naming.lookup()'s etc without any bother. In other words, it registers the activatable class using code like this
LocateRegistry.getRegistry(rmid_port).rebind(...
where rmid_port=1098, the port on which RMID runs on by default (and RMID is running on this port). Thus I don't need to run RMIRegistry at all, whether it be on default port 1099 or some other (but not 1098).
The separate RMIRegistry program does not even see the light of day!
However, if I kill off RMID, any client that has an activatable object connection gets that object restarted when RMID is re-started, but any client that has to do a Naming.lookup fails because the internal RMI Registry inside RMID has been created anew.
So, my theory is, that the tutorial asks you to start RMIRegistry, so that RMID can be killed off whenever you like and restarted and everything still works, including Naming.lookup, BECAUSE you have registered the Activatable on the RMIRegistry, and NOT with the RMI registry inside RMID, and therefore that the RMI Registry is still running and intact.
If this theory is true, then a client does a Naming.lookup which hits the RMIRegistry program on port 1099, NOT the RMID program which is listening on port 1098. So the question becomes "How does the separate RMIRegistry program (a) know that RMID is running, (and the port it is listening to) and (b) communicate with RMID to let it know that a request to activate an object has been made, in view of the fact that the record of the remote object in the registry has been recorded in a different program from the one running the Activator."
I hope this is clearer now to you. I am busy compiling the HTML help files for my program and I need to get this concept clearly across to the users, so any help would be appreciated.
22 years ago
Have you ensured your RMIRegistry has been started with NO CLASSPATH?
The error suggests that the RMIRegistry is finding your stubs/skels on its classpath.
If it does, it *does not bother* sending the java.rmi.server.codebase System Property in the marshal stream...
I found that codebase can point to any drive, but that the java.security.policy must point to a file on the same disk as the Java SDK or JRE is installed on...
22 years ago
An interesting one for you all.
The Java Activation Tutorial mentions starting RMID (using default port 1098) followed by starting the RMIRegistry (on default port 1099) and then registering the Activatable object in the normal manner with the Activator in RMID and the object with the RMIRegistry. This is because the Naming.rebind() call uses the default port for binding to the Registry (port 1099) and that is where the RMIRegistry is sitting, listening for Registry calls.
Now RMID has its own registry, so if you (a) call Registry.locateRegistry(1098), you will talk to the RMI Registry in RMID - even if the RMIRegistry is busy running at the same time on port 1099.
So, if you bind an Activatable object with the RMIRegistry on port 1099, how does RMID get informed to activate the object?
Surely the only way to Register an Activatable is by using RMID's registry on port 1098?
If you specify a different port to RMID with
-port nnnn, then, again, I think you would Registry.locateRegistry(nnnn) for the Naming.rebind(), and then talk to the RMID registry on this new port.
If this is the case, what on earth is the point in starting up a completely separate RMIRegistry (on port 1099)? Surely it's just ignored.
If it is ignored, why does the tutorial ask that you start up RMIRegistry after starting up RMID..
!$%^!
Must be something I'm missing here...
22 years ago