I was reading through Java RMI book by Esmond Pitt where I came across :-
"If an exported object is serializable,it is still passed by reference.The fact that the object is exported takes precedence over the fact that it is serializable"
Could anyone elaborate and expound the reason.
Well, at one level, they had to choose one or the other, I suppose. (I wasn't in that meeting :)
But if I have an exported remote object, it needs to serialize to its stub (that is, it needs to be passed by reference) otherwise, you'd never be able to use it as a server-like object.
Did that make sense? If you allowed it to be serialized, it might as well not be a remote object, as any time you attempted to pass it over a network, you would fail to send the stub (which is what you need if you want to make it remotely accessible) and would simply send a serialized copy. Ergo, it's not a remote object any more.
Of course, you might be asking "why can't I choose dynamically each time this happens". Well, in that case, how on earth would you manage the process without causing some horrible coupling between unrelated parts of your software?
That's my guess :)
Being exported must take precedence for serialization purposes over being serializable. Otherwise RMI wouldn't work. It would just become a mobile-agent protocol.
UnicastRemoteObject, for example, implements Serializable by virtue of extending RemoteObject, which is serializable. If your remote objects extend UnicastRemoteObject, as most do, they are auto-exported on construction, and automatically replaced by their stubs during serialization, as the section you're quoting from in my book describes.
If it didn't do that, in preference to serializing as itself, it wouldn't be a UnicastRemoteObject, it would be more of a mobile agent, as described in another chapter of the book.
It follows that if you want it serialized, you have to unexport it first.
I think I also mentioned in the book that some versions of Java will then export it at the receiver on arrival, so it becomes a callback. I was never able to make much sense of this feature. The receiver could always have exported it himself if that's what he wanted: I don't see why it was forced on him.
http://docs.oracle.com/javase/tutorial/rmi/implementing.html
I hope this link will be useful.
"The rules governing how arguments and return values are passed are as follows:
Remote objects are essentially passed by reference. A remote object reference is a stub, which is a client-side proxy that implements the complete set of remote interfaces that the remote object implements.
Local objects are passed by copy, using object serialization. By default, all fields are copied except fields that are marked static or transient. Default serialization behavior can be overridden on a class-by-class basis."
Explanation:
This means that, if an object is made available to all as a remote object then the sender will put the reference into the stream and send it (when sender needs to send the object). The receiver receives the reference to the original object.
If an object is serializable and being sent, the sender makes a copy of the object and send the copy, which is independent object after created.
Related
I have read various old StackOverflow discussions on this general topic but there is still one part of the puzzle which appears, to me at least, to be missing.
It is simply this: what is the actual mechanism by which the anonymous function is serialized? And, where could we find its source code?
Or is it all just magic?
Other relevant SO articles (the third of these itself points to some useful articles outside StockOverflow):
Serialization of Scala Functions
Why Scala can serialize...
How to serialize functions in Scala
I'm going to answer my own question with what, I believe is the correct answer. The reason I'm doing it this way is that it seems to me that this aspect of serialization is never explained and it does appear to work just by magic. I essentially confirmed (to my satisfaction) the answer as part of the research I was doing to ensure that my question above was indeed appropriate.
But the main reason I'm offering my own answer is that I invite knowledgeable users either to agree with it, to correct it, to expand upon it, or to destroy it. Here goes...
It's all magic. No, I'm just kidding. But essentially the mechanism, once Scala has taken the step of representing the anonymous function as a Class, is entirely provided for by Java. In addition, we, the programmer, need to ensure that an anonymous function is as much pure code as possible: no references to any objects that might not be serializable. The secret sauce is to be found in the Java class: ObjectStreamClass. Which, in turn, is invoked by the Java serialization classes: ObjectInputStream and ObjectOutputStream.
Essentially the serialized bytes contain the full pathname of the class, its serialVersionUID, and whatever other relevant information is necessary. When deserializing, the system will simply look up the class in the appropriate classpath and return a reference to it. This obviously assumes that the deserializing system has the class in its classpath. The mechanism for that is a little beyond the scope of my research but it's clear that in a system like Spark, it should be easy to arrange.
No (additional) compilation/decompilation of byte code is necessary as the classLoader has everything necessary. I'm slightly surprised to find the ObjectStreamClass in java.io rather than in the reflection package, but I suppose there's an argument for it being there, given the tight coupling with ObjectInputStream and ObjectOutputStream.
One thing to keep in mind is that while we think in terms of serializing/deserializing objects, rather than classes, what we are dealing with here is an object of type Class.
One more thing to note is that in Scala 2.12, anonymous functions are now implemented differently: as Java8 lambdas. This has broken the mechanism described above in a rather serious way. So serious, that Spark is currently having trouble supporting Scala 2.12. The holdup appears to be this issue: SPARK-14540.
Suppose, I wrote a contract in Solidity that is now currently being run by a number of nodes. For some reason, I made a change - code or configuration or both. How do I know that, all the nodes running this contract are running the latest version of the code?
Conversely, if the contract was placed in an open repository (e.g. GitHub), how do I know, the code wasn't tampered with?
What if, a majority of nodes did decide to tamper the code and run that version?
Short answer
There is no "latest" version. Basically, you cannot even make a "change" to the deployed code. Please continue to read if you really need your DApp to be updatable.
Explanation
When you compile your Solidity source code into EVM byte code, deploy it to the blockchain (by spending some Ether), and wait for the transaction to be mined, the DApp program is fixed. During runtime, the only way that could possibly make a change in the state of the DApp is invoking a public function of the contract.
Solution
You may make use of the above fact to make your DApp updatable:
Define an interface (Cat) having some abstract functions (meow) that you want them to be updatable
Define a contract (Shorthair) that implements the interface (contract Shorthair is Cat)
Deploy the contract (Shorthair)
Define another contract (FunMaker)
Define an address variable (address catAddress)
This is to store the address of your "latest" implementation
In the constructor, accept an address parameter
Assign the value to catAddress
When you want to call the updatable function (meow), do this:
Cat cat = Cat(catAddress)
cat.meow()
Create another function that accepts an address parameter (setCatAddress) so that you can update the value of the address variable (catAddress)
Now, your smart contract (FunMaker) is updatable. When you want to make an update, just write another contract that implements Cat (Shorthair2, Persian, whatever) and deploy it. After the deployment, record the address and call setCatAddress on FunMaker with it to overwrite the value of catAddress.
Caveats
The spirit of smart contracts is "define what to do, do what is defined". Trust is based on the fact that nothing could be changed after deployment. However, if you implement your DApp like this, you are basically reversing the principles.
Besides, the contract being called (Shorthair) cannot deal with balances and variables in the caller (FunMaker) directly. Despite that it is still do-able with careful design and work-arounds, it is better to evaluate if it is worth doing so at the first place.
It's organized on completely different lines.
The contract bytecode (generally from a compiler), not the source, is part of the blockchain. it's indifferent to traditional distribution channels.
The existence of the contract is part of the shared history of the chain, because the bytecode was (part of) a specific transaction that deployed the contract. Said deployment transaction is also part of the immutable history of the chain.
Nodes don't have very much latitude. They don't get to decide what version they want to run. Either they run the actual code or they cease being part of the consensus.
So, basically, you know all the nodes are running the contract you deployed, with few (if any) exceptions. It's the only correct interpretation of the chain.
Hope it helps.
How do I know the source code of the contract at a specific address?
Basically, there is no simple way.
The simplest way I can imagine is by byte code comparison:
Get the byte code at a specific address by this call
Get the source code from the owner
In most of the cases, they are willing to provide you the source code
This is because the spirit of smart contracts is "define what to do, do what is defined"
The trust comes from the fact that the user knows exactly how it is implemented --- no more and no less
Compile it with a Solidity compiler
You may find the official online compiler handy
Do a string comparison on the results
I'm exploring jsonrpc 2 for a web service. I have some experience with java rmi and very much liked that. To make things easy I using the zend framework so I think I like to use that library. There is however one thing i am missing. how do I make a procedure send back a reference to an other object.
I get that is not within the protocol because its about procedures but it would still be a useful thing. Like with the java rmi I could pick objects to send by value (serialize) or reference (remote object proxy). So what is the best way do solve this? are there any standards for this that most library's use?
I spend a view hours on google looking for this and can think of a solution (like return a url) but, I would rather use a standard then design something new.
There is one other thing i would like your opinion on. I heard an architect rand about the protocol's feature of sending batches of call's. Are the considered nice or dirty? (he thinks they where ugly but i can think of use for then)
update
I think the nicesed way is just to return a remoteref object with a url to the object. That way its only a small wrappen and a litle documentation. Yet i would like to know if there is a commen way to do this.
SMD Posibilitie's
There might be some way to specify the return type in my smd, is there anyone with idears of how to give a reference to another page in my smd return type? Or does anyone know a good explenation for the zend_json_smd class?
You can't return a reference of any kind via JSON-RPC.
There is no standard to do so (afaik) because RPC is stateless, and most developers prefer it that way. This simplicity is what makes JSON-RPC so desirable to client-side developers over SOAP (and other messes).
You could however adopt a convention in your return values that some JSON constructs should be treated as "cues" to manufacture remote "object" proxies. For example, you could create a modified JSON de-serialiser that turns:
{
"__remote_object": {
"class": "Some.Remote.Class",
"remote_id": 54625143,
"smd": "http://domain/path/to/further.smd",
"init_with": { ... Initial state of object ... }
}
}
Into a remote object proxy by:
creating a local object with a prototype named after class, initialised via init_with
downloading & processing the smd URL
creating a local proxy method (in the object proxy) for each procedure exposed via the API, such that they pass the remote_id to the server with each call (so that the server knows which remote object proxy maps to which server-side object.)
While this scheme would be workable, there are plenty of moving parts, and the code is much larger and more complicated on the client-side than for normal JSON-RPC.
JSON-RPC itself is not well standardised, so most extensions (even SMD) are merely conventions around method-names and payloads.
Before I start using CORBA I want to know something.
It would seem intuitive to me that you could use an IDL type as an attribute of another, which would then expose that attribute's methods to the client application (using ".") as well.
But is this possible?
For example (excuse my bad IDL):
interface Car{
attribute BrakePedal brakePedal;
//...
}
//then.. (place above)
interface BrakePedal{
void press();
//...
}
//...
Then in the client app, you could do: myCar.brakePedal.press();
CORBA would seem crappy if you couldn't do these kind of multi-level
object interfaces. After all, real-world objects are multi-level, right? So can
someone put my mind at ease and confirm (or try, if you already have CORBA set up) if this definitely works? None of the IDL documentation explicitly shows this in example, which is why I'm concerned. Thanks!
Declaring an attribute is logically equivalent to declaring a pair of accessor functions, one to read the value of the attribute, and one to write it (you can also have readonly attributes, in which case you would only get the read function).
It does appear from the CORBA spec. that you could put an interface name as an attribute name. I tried feeding such IDL to omniORB's IDL to C++ translator, and it didn't reject it. So I think it is allowed.
But, I'm really not sure you would want to do this in practice. Most CORBA experts recommend that if you are going to use attributes you only use readonly attributes. And for something like this, I would just declare my own function that returned an interface.
Note that you can't really do the syntax you want in the C++ mapping anyway; e.g.
server->brakePedal()->press(); // major resource leak here
brakePedal() is the attribute accessor function that returns a CORBA object reference. If you immediately call press() on it, you are going to leak the object reference.
To do this without a leak you would have to do something like this:
BrakePedal_var brakePedal(server->brakePedal());
brakePedal->press();
You simply can't obtain the notational convenience you want from attributes in this scenario with the C++ mapping (perhaps you could in the Python mapping). Because of this, and my general dislike for attributes, I'd just use a regular function to return the BrakePedal interface.
You don't understand something important about distributed objects: remote objects (whether implemented with CORBA, RMI, .NET remoting or web services) are not the same as local objects. Calls to CORBA objects are expensive, slow, and may fail due to network problems. The object.attribute.method() syntax would make it hard to see that two different remote calls are being executed on that one line, and make it hard to handle any failures that might occur.
I'm using the Agatha request/response library (and StructureMap, as utilized by Agatha 1.0.5.0) for a service layer that I'm prototyping, and one thing I've noticed is the large number of handlers that need to be created. It generally makes sense that any request/response type pair would need their own handler. However, as this scales to a large enterprise environment that's going to be A LOT of handlers.
What I've started doing is dividing up the enterprise domain into logical processor classes (dozens of processors instead of many hundreds or possibly eventually thousands handlers). The convention is that each request/response type (all of which inherit from a domain base request/response pair, which inherit from Agatha's) gets exactly one function in a processor somewhere.
The generic handler (which inherits from Agatha's RequestHandler) then uses reflection in the Handle method to find the method for the given TREQUEST/TRESPONSE and invoke it. If it can't find one or if it finds more than one, it returns a TRESPONSE containing an error message (messages are standardized in the domain's base response class).
The goal here is to allow developers across the enterprise to just concern themselves with writing their request/response types and processor functions in the domain and not have to spend additional overhead creating handler classes which would all do exactly the same thing (pass control to a processor function).
However, it seems that I still need to have defined a handler class (albeit empty, since the base handler takes care of everything) for each request/response type pair. Otherwise, the following exception is thrown when dispatching a request to the service:
StructureMap Exception Code: 202
No Default Instance defined for PluginFamily Agatha.ServiceLayer.IRequestHandler`1[[TSFG.Domain.DTO.Actions.HelloWorldRequest, TSFG.Domain.DTO, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null]], Agatha.ServiceLayer, Version=1.0.5.0, Culture=neutral, PublicKeyToken=6f21cf452a4ffa13
Is there a way that I'm not seeing to tell StructureMap and/or Agatha to always use the base handler class for all request/response type pairs? Or maybe to use Reflection.Emit to generate empty handlers in memory at application start just to satisfy the requirement?
I'm not 100% familiar with these libraries and am learning as I go along, but so far my attempts at both those possible approaches have been unsuccessful. Can anybody offer some advice on solving this, or perhaps offer another approach entirely?
I'm not familiar with Agatha. But if you want all requests for IRequestHandler<T> to be fulfilled by BaseHandler<T>, you can use the following StructureMap registration:
For(typeof(IRequestHandler<>)).Use(typeof(BaseHandler<>));
When something asks for an IRequestHandler<Foo>, it should get a BaseHandler<Foo>.