aspose file tools*
The moose likes Developer Certification (SCJD/OCMJD) and the fly likes a client could  unlock a record that it has not locked? Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login


Win a copy of Spring in Action this week in the Spring forum!
JavaRanch » Java Forums » Certification » Developer Certification (SCJD/OCMJD)
Bookmark "a client could  unlock a record that it has not locked?" Watch "a client could  unlock a record that it has not locked?" New topic
Author

a client could unlock a record that it has not locked?

mark ken
Ranch Hand

Joined: Sep 01, 2004
Posts: 47
Hi guys,
I read many posts in here, I found many people say there should has a situation that a client could unlock a record that it has not locked.
I don't understand this, how a client could unlock a record that it has not locked. I think it's impossible!
because I think the lock and ulock will be called in one method, and it has been synchronized. just like this :
synchronized(lockrecords){
lock(recno);
update(recno);
unlock(recno);
}

can anyone tell me if I'm right, or that situation really could happened
thank you!


SCJP1.2 ,SCJD1.5 , SCBCD1.3 ,SCWCD1.4
Frans Janssen
Ranch Hand

Joined: Dec 29, 2004
Posts: 357
Hi Mark,

For this assignment you must build a client-server system, so you must build the client and the server. Your client will most probably call the methods in the sequence as your describe above. However, you should also consider the situation that another client will call methods on your server. This client may behave differently, could contains bugs or even be a malicious client that wants to abuse your server. These are considerations you should make when developing a real-life application, so I think the server should be made robust against such scenarios.

Frans.


SCJP 1.4, SCJD
mark ken
Ranch Hand

Joined: Sep 01, 2004
Posts: 47
Hello Frans:
thank you for replying my post. But, if we ignore bug&malicious attack etc..
Is there other good reason to explain my question?
I just read some posts say: the rmi server can't guarantee to return unique thread to each client, two different client may share one thread in server side.
Is this the real reason for "a client could unlock a record that it has not locked"?

because when client1 call update(recno), at the same time client2 also called update(recno), because they share the same thread, the value of recno has been changed by client2 during client1's calling. so when client1 try to call unlock(recno), acutally it unlock the record which is belong to client2.

what I'm wondering is : will this really happen? my question is , even they share same thread, how could client2's parameter cover client1's parameter? I know there is a stack to store the parameter for each method call, since they share same thread , they will use same stack,all parameter value should push into this stack. I'm confused by this,who can explain this for me.
thank you!

[ June 15, 2005: Message edited by: mark ken ]
[ June 15, 2005: Message edited by: mark ken ]
Reza Rahman
author
Ranch Hand

Joined: Feb 01, 2005
Posts: 580
    
    5
Mark:

In Java, it is impossible (by contract) for two concurrent threads to have the same object instance. That being said, it is entirely possible that two sequential operations will "run under" the same object instance (to know why and how this happens, take a look at the thread pool implementation by Doug Lea, the creator of util.concurrent - later to be introduced into Java 5).

I'll be happy to explain why this is the case...but you might want to do a little bit more research on this yourself, including writing a very simple program that tries to reuse a Java thread/actually sees how RMI handles concurrent requests .

Reza

[ June 15, 2005: Message edited by: Reza Rahman ]
[ June 15, 2005: Message edited by: Reza Rahman ]

Independent Consultant — Author, EJB 3 in Action — Expert Group Member, Java EE 6 and EJB 3.1
John Smith
Ranch Hand

Joined: Oct 08, 2001
Posts: 2937

I think the lock and ulock will be called in one method, and it has been synchronized. just like this :
synchronized(lockrecords){
lock(recno);
update(recno);
unlock(recno);
}


This solution will work, indeed, but you stand no chance of passing. If you think about your code above, you will realize that the calls to lock() and unlock() are fake -- they don't do anything in terms of thread safety or synchronization. That is, your code might as well look like this:



And it will do exactly the same thing as the code that you suggested. That is, in your solution, the calls to lock() and unlock() are made just for the purpose of making the calls, and don't carry any functional purpose at all. But the requirements are unambiguous: you must make use of lock/unlock to allow multiple clients to book the records concurrently.
Reza Rahman
author
Ranch Hand

Joined: Feb 01, 2005
Posts: 580
    
    5
FYI: I fully agree with John. The "cloaking" synchronization block is very redundant in this case...the lock/unlock sequence should be taking care of synchronization/thread serialization.
mark ken
Ranch Hand

Joined: Sep 01, 2004
Posts: 47
hello,
thank you for all replies.
maybe I didn't describe my question clearly,
according with RMI Specification (
http://java.sun.com/j2se/1.3/docs/guide/rmi/spec/rmi-arch3.html
Thread Usage in Remote Method Invocations
A method dispatched by the RMI runtime to a remote object implementation may or may not execute in a separate thread. The RMI runtime makes no guarantees with respect to mapping remote object invocations to threads. Since remote method invocation on the same remote object may execute concurrently, a remote object implementation needs to make sure its implementation is thread-safe.

acutally I can't understand above statement very well, does that mean rmi server could assign one thread to different client at same time?
is this the reason which make a client could unlock a record that it has not locked?

anyone know this? thanks.
Reza Rahman
author
Ranch Hand

Joined: Feb 01, 2005
Posts: 580
    
    5
Mark:

Yes! I'm glad to see I'm not the only person confused by this poorly written section of the RMI spec that looks like a lawyer wrote it .

If you dissect the statement carefully, you will see that it never suggests that the same thread handles concurrent RMI method calls from the same or two different clients (see above why this is impossible, if you need more clarification, I'll be happy to discuss it with you).

What it is actually saying is that subsequent sequential calls from the same client are not guratanteed to be handled by the same thread (again, I refer you to Doug Lea's thread pool implementation to see why trying to guarantee this would make life insanely difficult for JVM developers).

It is also saying that there might be more than one RMI method call (from the same or two different clients) executing concurrently. Because of Java's threading contract guarantee, all of these concurrent calls will be handled by separate threads. Hence, you must guard for thread safety within your code in not assuming your code will be called sequentially or by the same thread.

Did that help at all? If you still need to discuss why this makes the unlock check important, let me know (hint: it is only important in the two-tier, thick client solution).

Reza
[ June 17, 2005: Message edited by: Reza Rahman ]
John Smith
Ranch Hand

Joined: Oct 08, 2001
Posts: 2937
A method dispatched by the RMI runtime to a remote object implementation may or may not execute in a separate thread. The RMI runtime makes no guarantees with respect to mapping remote object invocations to threads. Since remote method invocation on the same remote object may execute concurrently, a remote object implementation needs to make sure its implementation is thread-safe.

acutally I can't understand above statement very well, does that mean rmi server could assign one thread to different client at same time?
is this the reason which make a client could unlock a record that it has not locked?


What it means is that you can't make any assumptions as to what thread will be used to run a method on a remote object. If your solution attempts to identify the client by the identity of the current thread used to run a method, it may work in one RMI vendor implementation, but not the others. The possible scenario is that Client1 locks record R1 using thread T1. Now, Client1 calls the unlock() method and it is dispatched to thread T2. If your code uses the thread ID to check if it is the same client, record R1 will remain locked forever. Alternatively, Client2 may call unlock() using thread T1, and it will be able to unlock record R1 which was locked by Client1, which will brutaly violate your assignment requirements.

Fortunately, there are other ways to uniquely and reliably identify the client. Thread identity is simply not one of them.
Reza Rahman
author
Ranch Hand

Joined: Feb 01, 2005
Posts: 580
    
    5
Mark:

What John is saying is absolutely true in two-tier architecture in which the client directly makes the lock and unlock invocation. However, it does not hold water if the lock-action-unlock sequence is wrapped within the scope of a single RMI method call (as I think is the case with you) because of the way Threads are guaranateed to work in Java (in a vendor neutral manner), namely that the same instance of a thread cannot be run in pararallel to itself, under any circustances.

Put another way, the start/run sequence cannot be invoked twice on the same thread (check out the Javadoc's start method contract and Thread specifications) and within the scope of a single run method, all method invocations are sequential.

Reza

P.S.: This seems to be a common misconception on this board, so I am glad you finally brought it up...I think there are two additional factors other than the poorly worded spec leading to misundertanding the spec's intent...a tendency to favor the two-tier/RMI factory patterns and paranoia about being "extra safe" - both harmless and well-intentioned, of course...but it binds the rest of us to an assumption that just isn't true other than unsubstantiated claims/inferences repeated in no other place than this board...
[ June 17, 2005: Message edited by: Reza Rahman ]
John Smith
Ranch Hand

Joined: Oct 08, 2001
Posts: 2937
RR: What John is saying is absolutely true in two-tier architecture in which the client directly makes the lock and unlock invocation. However, it does not hold water if the lock-action-unlock sequence is wrapped within the scope of a single RMI method call

The three tier solution was not an option for me. Here is what I had in my requirements:


To connect with your server, you should create a client program. This implementation should include a class that implements the same public methods as the suncertify.db.Data class, although it will need different constructors to allow it to support the network configuration."


What is says to me is that the client should be able to call lock/unlock directly. Don't know if Mark has such a requirement, but if he does, it'll be risky to hide lock/unlock from the client.
Reza Rahman
author
Ranch Hand

Joined: Feb 01, 2005
Posts: 580
    
    5
John:

I do agree completely, I would read your requirement as a strict binding to a thick client solution. Fortunately, I don't think this is the case for many others...

Note, the P.S. above was absolutely not directed at any person/persons in particular; just a general observation I am seeing across many posts over time. Woe be on me if that wasn't clear...

Reza
Andrew Monkhouse
author and jackaroo
Marshal Commander

Joined: Mar 28, 2003
Posts: 11481
    
  94

Hi Mark,

To give you an example of this thread use / reuse in practice, take a look at this extract from The Sun Certified Java Developer Exam with J2SE 5, Second Edition (gee I love shameless plugs ):Although the results of running this will vary from computer to computer (and indeed from run to run), one example of running this is shown in the following diagram:



As can be seen above, both client A and client B use threads 15655788, and thread 16112134.

Note that this code was compiled and run with JDK 5, so there was no need to run rmic. If you are trying to duplicate this with an earlier version of the JDK you will need to run rmic against the Server to generate the stubs.

Originally posted by Reza Rahman:
P.S.: This seems to be a common misconception on this board, so I am glad you finally brought it up...I think there are two additional factors other than the poorly worded spec leading to misundertanding the spec's intent...a tendency to favor the two-tier/RMI factory patterns and paranoia about being "extra safe" - both harmless and well-intentioned, of course...but it binds the rest of us to an assumption that just isn't true other than unsubstantiated claims/inferences repeated in no other place than this board...




Not sure I can agree with that ...

The reasons why some of us believe that a "thin client" is not an acceptable solution to the assignment Sun provides are laid out in the topic "Should lock methods be callable by the client". As that topic shows, it is possible for two people to read the same specification and understand different things about it. Regardless, both thin client and fat client are accepted by the assessors at this time.

If you believe that a thin client solution is not acceptable, and you do not have cookies in your lock signatures, then an RMI factory is an easy solution to the problem.

However I don't think there is any tendancy to push an RMI Factory solution - if candidates have lock cookies then they may not need it. And if they are going for a thin client, then they definately don't need it. So if we go with the assumption that lock cookies appear in 1/2 the assignments, and (according to the topic I linked to earlier) over 1/2 the candidates believe that a thin client solution is acceptable, then you would find that the RMI Factory is only being suggested in less than 1/4 of questions posed about how to handle locking.

However this number may seem low, as those who are using cookies or thin clients may not be asking questions - hence the chances of RMI Factories coming up appears greater.

Likewise RMI Factories comes up more often in situations where candidates are being "extra safe", and handling the cases where a fat client dies without releasing its locks. In those cases, I think most of us prefix possible solutions by stating that we don't believe it is necessary to take that extra step.

But if candidates want to discuss these topics, and these topics naturally lead to a discussion on RMI Factories, then so be it .

Regards, Andrew


The Sun Certified Java Developer Exam with J2SE 5: paper version from Amazon, PDF from Apress, Online reference: Books 24x7 Personal blog
mark ken
Ranch Hand

Joined: Sep 01, 2004
Posts: 47
Hello Reza, John,Andrew,
Thank you for the replies which are really helpful. I think now I understand the statement in rmi Specification.
if lock, unlock method only can be called in one remote method such as book(), lock and unload will always run in one thread, but if client call lock and unlock directly from client side.
such as:
clientA call remoteObj.lock(recno), the rmi server assign thread1 to this call, after a while if clinetA try to call remoteObj.unlock(recno)
rmi server maybe assign thread2 to this call.

back to my original question(a client could unlock a record that it has not locked?), I think above situation (even lock ,unlock run in different thread)will not cause a client unlock a record that it has not locked.
If we always call [lock(), update(), unlock()] in one method, no other can unlock a recoder which is not lock by it. becaue when a client try to call unlock(), it must call lock() first!
so, "a client unlock a record that it has not locked" only could happened when a client call unlock() directly without calling lock() method.
am I right? any comments?
[ June 21, 2005: Message edited by: mark ken ]
John Smith
Ranch Hand

Joined: Oct 08, 2001
Posts: 2937
back to my original question(a client could unlock a record that it has not locked?), I think above situation (even lock ,unlock run in different thread)will not cause a client unlock a record that it has not locked.

The requirement for the unlock() is two-fold:

1. The record must be unlocked after it was modified
2. The record can only be unlocked by the client that locked that record

As Andrew's code demonstrates, the naive RMI implementation coupled with the thread IDs to identify the clients would violate the first requirement left and right. Although it's more difficult to construct a scenario in which the second requirement can be violated (aside from calling unlock() without calling lock() first), it's not still not very comforting, is it?
Andrew Monkhouse
author and jackaroo
Marshal Commander

Joined: Mar 28, 2003
Posts: 11481
    
  94

Hi Mark,

You are right insofar as hiding the lock and unlock calls within a business method on the server will ensure that the thread that locks the record also unlocks it in your server implementation.

But, your instructions may have something similar to the following in the lock method comments:
Locks a record so that it can only be updated or deleted by this client.
If you do have this, then you need some way of ensuring that only the client that locked the record can unlock it, and just assuming that your server code won't unlock a record it did not lock does not meet this criteria - the Data class still does not meet the requirements.

You might be able to meet the requirements by making it explicit (in JavaDoc and in the Design Doc) that you are using thread id as the client identifier, and then coding your booking business method on the server.

Regards, Andrew

[ June 22, 2005: Message edited by: Andrew Monkhouse ]
[ June 22, 2005: Message edited by: Andrew Monkhouse ]
mark ken
Ranch Hand

Joined: Sep 01, 2004
Posts: 47
Hello Andrew:
thank you so much for reminding me this.
----
Locks a record so that it can only be updated or deleted by this client.
--------------------------------------------------------------------------------
above line exactly shows in my instruction, I didn't think much of it before. acuatlly I ignored the word "only" . now I know I have to tracking the client id in my project! thank you again.
 
 
subject: a client could unlock a record that it has not locked?