Sunday, October 18, 2009

Finding the number of cluster nodes in JBoss


Thanks to the Original Author and source

How to find out how many nodes in the cluster

If you want to know how many nodes there are in the current cluster partition, all you have to do is to ask HAPartition for the node list. HAPartition represents your cluster partition, and it contains all the information you need to know about your cluster and the nodes: their host names, IPs, position in the cluster view.

Lets assume you have a service bean that extends from HASingletonSupport. HASingletonSupport in its turn extends from HAServiceMBeanSupport.

HAServiceMBeanSupport is the one who gives you access to HAPartition object.

The code to request for HAPartition object and node list that you see below , you can put somewhere in your service bean:
HAPartition partition = getPartition();
ClusterNode[] nodes = partition.getClusterNodes();
System.out.println(nodes.length);
ClusterNode object represents your node in the cluster. It contains information about node's host name, its internet address and a few more things. getClusterNodes(), returns to you an array contains as many ClusterNode objects as you have currently in your cluster. So by getting the value of array length, you will know how many nodes your cluster has.

Another way, is to do practically the same, but to request from a HAPartition a current view of your cluster:
HAPartition partition = getPartition();
Vector v = partition.getCurrentView();

System.out.println(partition.getCurrentView().size());

for (Object o : v) {
System.out.println(o.toString());
}
The view, which is a Vector contains information about node sockets. When printed, it will return to you a String representation of node ip + port: xxx.xxx.xxx.xxx:port. Also by printing size of the Vector, you will get number of nodes in the cluster.

Important note:
I noticed there is some delay happening from the time when node leaves the cluster to the time when HAPartition returns an updated view. In another words - after node has left the cluster and topology change has occurred, the HAPartition may return to you an old view still containing the dead node. So be careful.

Also, getPartition() may return null, if super.startService() hasnt been called. Have a look at implementation of HAServiceMBeanSupport and my other post JBoss Clustering - HASingleton service.

JBoss Clustering

Thanks to the original author and Source

Singleton Service

A clustered singleton service is deployed on multiple nodes in a cluster but runs on only one of the nodes. The node running the singleton service is typically called the master node. When the master fails, another master is selected from the remaining nodes and the service is restarted on the new master.

clustered singleton diagram
Figure 1. Clustered singleton service

Many times, an application needs to ensure that a certain task is run exactly once. Thus, only one of the nodes in a cluster should execute the task. The other nodes should knowingly remain passive. Examples of singleton tasks include:

  • Sending email to the system administrator when the system is brought up or taken down. This notification does not take into account how many nodes are in the cluster. As long as at least one node is active, the system is up. When all nodes are down, the system is down.
  • Database schema validation upon startup. When a database-driven application is brought up, it is a good practice for the middle tier servers to verify whether the version of the business logic they implement matches the database schema.
  • Sending recurring notifications to system users. For example, a calendar application might send out email prior to each instance of a scheduled recurring meeting.
  • Load balancing of queued tasks. It's popular to use a single coordinator that distributes tasks among nodes in a cluster.
  • Fault tolerance. If an application uses a distributed cache, it is common to designate a single master node responsible for maintaining a current copy of distributed states. The other nodes make requests of the current master node. When the master fails, another node takes over its responsibilities.

While it is fairly easy to implement such singleton tasks in a single VM, the solution will usually not work immediately in a clustered environment. Even in the simple case of a task activated upon startup on one of the nodes in a two-node cluster, several problems must be addressed:

  • When the application is started simultaneously on both nodes, which VM should run the singleton task?
  • When the application is started on one node and then started later on another, how does the second node know not to run the singleton task again?
  • When the node that started the task fails, how does another node know to resume the task?
  • When the node that started the task fails, but later recovers, how do we ensure that the task remains running on only one of the nodes?

The logic to solve these problems is unlikely to be included in the design of a single-VM solution. However, a solution can be found to address the case at hand and it can be patched on the startup task. This is an acceptable approach for a few startup tasks and two-node clusters.

As the application grows and becomes more successful, more startup tasks may be necessary. The application may also need to scale to more than two nodes. The clustered singleton problem can quickly become mind-boggling for larger clusters, where the different node startup scenarios are far more difficult to enumerate than in the two-node case. Another complicating factor is communication efficiency. While two nodes can directly connect to each other and negotiate, 10 nodes will have to establish 45 total connections to use the same technique.

This is where JBoss comes in handy. It eliminates most of the complexity and allows application developers to focus on building singleton services regardless of the cluster topology.

We will illustrate how the JBoss clustered singleton facility works with an example. First, we will need a service archive descriptor. Let's use the one that ships with JBoss under server/all/farm/cluster-examples-service.xml. The following is an excerpt:

<!--    | This MBean is an example of a cluster Singleton    -->
<mbean code="org.jboss.ha.singleton.examples.HASingletonMBeanExample"
name="jboss.examples:service=HASingletonMBeanExample">
</mbean>
<!- - -->
<!-- | This is a singleton controller which works similarly to the
| SchedulerProvider (when a MBean target is used) -->
<mbean code="org.jboss.ha.singleton.HASingletonController"
name="jboss.examples:service=HASingletonMBeanExample-HASingletonController">
<depends>jboss:service=DefaultPartition</depends>
<depends>jboss.examples:service=HASingletonMBeanExample</depends>
<attribute name="TargetName">jboss:service=HASingletonMBeanExample</attribute>
<attribute name="TargetStartMethod">startSingleton</attribute>
<attribute name="TargetStopMethod">stopSingleton</attribute>
</mbean>
<!- - -->

This file declares two MBeans, HASingletonMBeanExample and HASingletonController. The first one is a singleton service that contains the custom code. It is a simple JavaBean with the following source code:

public class HASingletonMBeanExample
implements HASingletonMBeanExampleMBean {

private boolean isMasterNode = false;

public void startSingleton() {
isMasterNode = true;
}

public boolean isMasterNode() {
return isMasterNode;
}

public void stopSingleton() {
isMasterNode = false;
}
}

All of the custom logic for this particular singleton service is contained within this class. Our example is not too useful; it simply indicates, via the isMasterNode member variable, whether the master node is running the singleton. This value will be true only on the one node in the cluster where it is deployed.

HASingletonMBeanExampleMBean exposes this variable as an MBean attribute. It also exposes startSingleton() and stopSingleton() as managed MBean operations. These methods control the lifecycle of the singleton service. JBoss invokes them automatically when a new master node is elected.

How does JBoss control the singleton lifecycle throughout the cluster? The answer to this question is in the MBean declarations. Notice that the HASingletonMBeanExample-HASingletonController MBean also takes the name of the sample singleton MBean and its start and stop methods.

On each node in the cluster where these MBeans are deployed, the controller will work with all of the other controllers with the same MBean name deployed in the same cluster partition to oversee the lifecycle of the singleton. The controllers are responsible for tracking the cluster topology. Their job is to elect the master node of the singleton upon startup, as well as to elect a new master should the current one fail or shut down. In the latter case, when the master node shuts down gracefully, the controllers will wait for the singleton to stop before starting another instance on the new master node.

A singleton service is scoped in a certain cluster partition via its controller. Notice that, in the declaration above, the controller MBean depends on the MBean service DefaultPartition. If the partition where the singleton should run is different than the default, its name can be provided to the controller via the MBean attribute PartitionName.

Clustered singletons are usually deployed via the JBoss farming service. To test this example, just drop the service file above in the server/all/farm directory. You should be able to see the following in the JBoss JMX web console:

JMX Console, HASingletonController
Figure 2. Controller MBean view. The MasterNode attribute will have value True on only one of the nodes.

JMX Console, HASingletonMBeanExample
Figure 3. Sample singleton MBean view. The MasterNode attribute will have the same value as the MasterNode attribute on the controller MBean.

Saturday, October 17, 2009

Brief on JBoss EAR Deployment

EAR Deployment Process:

1) The EAR starts getting deployed and EARDeployer is the main class that does that.

2) All the dependent jars are scanned and deployed if not deployed. MainDeployer is the main class that does this.

3) The Queue Sevice and Topic Service will be started if there are any topics or queues defined in the Application. TopicService and QueueService are the main class that does this.

4) EJB3Deployment begins, which deploys Enterprise beans and Persistence Units in the application or module. EJB3Deployer iterates through the ear to find all the jars which has persistence units and enterprise beans for deployment.

a) If a persistence unit is detected, first an corresponding MDB will be created and registered into JMXServer. Similarly if an EJB is detected, a corresponding MDB is created and registered into JMX. JmxKernelAbstraction is the main class that does this.

b) Once PersistenceUnitMDB is registered, the service is started to create all the relevant tables n EntityManager relationships etc into db and PersistenceUnitDeployment is the class that does this.

c) Similarly once EJBMDB is registered, the service is started using EJBContainer class.

5) Once EJB Deployment is done, TomcatDeployer will deploy the web application if any in the particular module being scanned.

6) Cluster Session Management is started for this particular application, JBossCacheManager is the one responsible for this.

7) Once all the above steps are done, the application can have application specific database initializers, inventory trackers, etc started.


Before the EAR Deployment begins, all the services starting from Transaction Service, Timer Service, UDDI, WebService, etc would have started.
All the JBoss related Webapps like jmx-console, web-console will start. Once all these JBoss goes ahead with the EAR Deployment.

JBoss Lookup

Thanks to the original author.
You can find the original source here


Many a times when you are doing a lookup in the JNDI tree, you see javax.naming.NameNotFoundException. A simple code that does the lookup will look something like:

  1. Context ctx = new InitialContext();
  2. Object obj = ctx.lookup("somepath/somename");


This code just looks up the JNDI tree to get an object bound by the name "somepath/somename". Looks simple. However, chances are that you might even see this exception:

  1. javax.naming.NameNotFoundException: somepath not bound
  2. at org.jnp.server.NamingServer.getBinding(NamingServer.java:529)
  3. at org.jnp.server.NamingServer.getBinding(NamingServer.java:537)
  4. at org.jnp.server.NamingServer.getObject(NamingServer.java:543)
  5. at org.jnp.server.NamingServer.lookup(NamingServer.java:267)
  6. at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
  7. at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
  8. at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
  9. at java.lang.reflect.Method.invoke(Method.java:585)
  10. at sun.rmi.server.UnicastServerRef.dispatch(UnicastServerRef.java:294)
  11. at sun.rmi.transport.Transport$1.run(Transport.java:153)
  12. at java.security.AccessController.doPrivileged(Native Method)
  13. at sun.rmi.transport.Transport.serviceCall(Transport.java:149)
  14. at sun.rmi.transport.tcp.TCPTransport.handleMessages(TCPTransport.java:460)
  15. at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run(TCPTransport.java:701)
  16. at java.lang.Thread.run(Thread.java:595)
  17. at sun.rmi.transport.StreamRemoteCall.exceptionReceivedFromServer(StreamRemoteCall.java:247)
  18. at sun.rmi.transport.StreamRemoteCall.executeCall(StreamRemoteCall.java:223)
  19. at sun.rmi.server.UnicastRef.invoke(UnicastRef.java:126)
  20. at org.jnp.server.NamingServer_Stub.lookup(Unknown Source)
  21. at org.jnp.interfaces.NamingContext.lookup(NamingContext.java:625)
  22. at org.jnp.interfaces.NamingContext.lookup(NamingContext.java:587)
  23. at javax.naming.InitialContext.lookup(InitialContext.java:351)


Look closely at the stacktrace. It shows that while looking up the JNDI tree it could not find the jndi name "somepath" (this name may vary). The reason is simple, the JNDI tree does not have any object bound by this name.

To quote the javadocs of this exception "This exception is thrown when a component of the name cannot be resolved because it is not bound."

So how do i know, what's the name to which my object is bound? Each application server, usually provides a JNDI view which can be used to see the contents of the JNDI tree. If you know what object you are looking for (ex: the name of the bean), then you can traverse this JNDI tree to see what name it is bound to. The JNDI view is specific to every application server.

To give an example, JBoss provides its JDNI tree view, through the JMX console. Here are the steps, one has to follow to check the JNDI tree contents on JBoss:

- Go to http://<>:<>/jmx-console (Ex: http://localhost:8080/jmx-console)
- Search for service=JNDIView on the jmx-console page
- Click on that link
- On the page that comes up click on the Invoke button beside the list() method
- The page that comes up will show the contents of the JNDI tree.

Here's an sample of how the output looks like(just a small part of the entire output):

  1. java: Namespace

  2. +- XAConnectionFactory (class: org.jboss.mq.SpyXAConnectionFactory)
  3. +- DefaultDS (class: org.jboss.resource.adapter.jdbc.WrapperDataSource)
  4. +- SecurityProxyFactory (class: org.jboss.security.SubjectSecurityProxyFactory)
  5. +- DefaultJMSProvider (class: org.jboss.jms.jndi.JNDIProviderAdapter)
  6. +- comp (class: javax.naming.Context)
  7. +- JmsXA (class: org.jboss.resource.adapter.jms.JmsConnectionFactoryImpl)
  8. +- ConnectionFactory (class: org.jboss.mq.SpyConnectionFactory)
  9. +- jaas (class: javax.naming.Context)
  10. | +- dukesbank (class: org.jboss.security.plugins.SecurityDomainContext)
  11. | +- HsqlDbRealm (class: org.jboss.security.plugins.SecurityDomainContext)
  12. | +- jbossmq (class: org.jboss.security.plugins.SecurityDomainContext)
  13. | +- JmsXARealm (class: org.jboss.security.plugins.SecurityDomainContext)


  14. Global JNDI Namespace

  15. +- ebankTxController (proxy: $Proxy79 implements interface com.sun.ebank.ejb.tx.TxControllerHome,interface javax.ejb.Handle)
  16. +- ebankAccountController (proxy: $Proxy75 implements interface com.sun.ebank.ejb.account.AccountControllerHome,interface javax.ejb.Handle)
  17. +- TopicConnectionFactory (class: org.jboss.naming.LinkRefPair)
  18. +- jmx (class: org.jnp.interfaces.NamingContext)
  19. | +- invoker (class: org.jnp.interfaces.NamingContext)
  20. | | +- RMIAdaptor (proxy: $Proxy48 implements interface org.jboss.jmx.adaptor.rmi.RMIAdaptor,interface org.jboss.jmx.adaptor.rmi.RMIAdaptorExt)
  21. | +- rmi (class: org.jnp.interfaces.NamingContext)
  22. | | +- RMIAdaptor[link -> jmx/invoker/RMIAdaptor] (class: javax.naming.LinkRef)
  23. +- HTTPXAConnectionFactory (class: org.jboss.mq.SpyXAConnectionFactory)
  24. +- ConnectionFactory (class: org.jboss.mq.SpyConnectionFactory)
  25. +- ebankCustomer (proxy: $Proxy67 implements interface com.sun.ebank.ejb.customer.LocalCustomerHome)
  26. +- UserTransactionSessionFactory (proxy: $Proxy14 implements interface org.jboss.tm.usertx.interfaces.UserTransactionSessionFactory)
  27. +- ebankCustomerController (proxy: $Proxy77 implements interface com.sun.ebank.ejb.customer.CustomerControllerHome,interface javax.ejb.Handle)
  28. +- HTTPConnectionFactory (class: org.jboss.mq.SpyConnectionFactory)
  29. +- XAConnectionFactory (class: org.jboss.mq.SpyXAConnectionFactory)
  30. +- TransactionSynchronizationRegistry (class: com.arjuna.ats.internal.jta.transaction.arjunacore.TransactionSynchronizationRegistryImple)
  31. +- ebankAccount (proxy: $Proxy68 implements interface com.sun.ebank.ejb.account.LocalAccountHome)
  32. +- UserTransaction (class: org.jboss.tm.usertx.client.ClientUserTransaction)
  33. +- UILXAConnectionFactory[link -> XAConnectionFactory] (class: javax.naming.LinkRef)
  34. +- UIL2XAConnectionFactory[link -> XAConnectionFactory] (class: javax.naming.LinkRef)
  35. +- queue (class: org.jnp.interfaces.NamingContext)
  36. | +- A (class: org.jboss.mq.SpyQueue)
  37. | +- testQueue (class: org.jboss.mq.SpyQueue)
  38. | +- ex (class: org.jboss.mq.SpyQueue)
  39. | +- DLQ (class: org.jboss.mq.SpyQueue)
  40. | +- D (class: org.jboss.mq.SpyQueue)
  41. | +- C (class: org.jboss.mq.SpyQueue)
  42. | +- B (class: org.jboss.mq.SpyQueue)


Let's see what this tells us. Let's consider the Global JNDI Namespace first. It contains (among other things) the following:
  1. +- ebankTxController (proxy: $Proxy79 implements interface com.sun.ebank.ejb.tx.TxControllerHome,interface javax.ejb.Handle)


This tells me that an object which implements com.sun.ebank.ejb.tx.TxControllerHome and javax.ejb.Handle interfaces is bound to the JNDI tree by the jndi-name "ebankTxController". So if at all i have to lookup this object, my lookup code would be something like:

  1. Context ctx = new InitialContext();
  2. ctx.lookup("ebankTxController");


Similarly in the same Global JDNI Namespace, we see :

  1. +- queue (class: org.jnp.interfaces.NamingContext)
  2. | +- A (class: org.jboss.mq.SpyQueue)



Make note of the nesting of the names here. This tells me that an object of type org.jboss.mq.SpyQueue is bound by the name "A under the path queue". So your lookup for this object should look like:

  1. Context ctx = new InitialContext();
  2. ctx.lookup("queue/A");


Now let's move on to the java: namespace in the JNDI tree view above. The difference between a Global JNDI namespace and the java: namespace is that, the object bound in the java: namespace can be looked-up ONLY by clients within the SAME JVM. Whereas, in case of Global JNDI namespace, the objects bound in this namespace can be looked-up by clients, even if they are not in the same JVM as the server. One would ask, how does this matter? Consider a standalone java program(client) which tries to lookup some object on the server (running in its own JVM). Whenever a standalone client is started (using the java command), a new JVM is instantiated. As a result, the server (which is started in its own JVM) and the client are running on different JVMs. Effectively, the client will NOT be able to lookup objects bound in the java: namespace of the server. However, the client can lookup the objects present in the Global JNDI namespace of the server.

So, why are we discussing these details, in a topic which was meant to explain the NameNotFoundException? Let's consider the java: namespace output above. There's a

  1. +- DefaultDS (class: org.jboss.resource.adapter.jdbc.WrapperDataSource)


This tells me that there's an object bound to the name DefaultDS in the java: namespace. So my lookup code would be:

  1. Context ctx = new InitialContext();
  2. ctx.lookup("java:/DefaultDS");


As explained above, this code is going to return you the object, if this piece of code runs in the same JVM as the server. However, if this piece of code is run from a client in different JVM (maybe a standalone client), then it's going to run into NameNotFoundException. The reason i explained the java: and the Global JNDI namespace is that, sometimes people are surprised that even though the JNDI view shows that the object is bound in the java: namespace(with the same name as the one they pass to the lookup method), they still run into NameNotFoundException. The probable reason might be, the client is in a different JVM.

Thursday, October 1, 2009

All you need to know about Javascript Inheritance

Classical Inheritance

<html>
<script>
function Person(name)
{
this.name = name;
}

Person.prototype.getName = function() {
return this.name;
}


function Author(name, book)
{
Person.call(this, name);
this.book = book;
}


Author.prototype = new Person();

Author.prototype.getBook = function() {
return this.book;
}




var simpson = new Author("Simpson", "The Big Fat Book");
alert(simpson.getName());
alert(simpson.getBook());

function Me()
{
Author.call(this, "Vinuth", "GentleMenz Arena");
}

Me.prototype = new Author();

Me.prototype.getBook = function() {
return "MyBreadBasket";
}

var me = new Me();
alert(me.getName() + " - " + me.getBook());
</script>
</html>

How of Classical Inheritance

1) Define a function as a constructor,
for e.g., Person, Author and Me shown above.

2) Constructors initializes the member variables and methods using the "this" keyword as shown in Person and Author constructors.

3) Define the complete structure by adding methods.
In the above example Person is defined as having a method called getName.
In javascript prototype keyword is used extensively for this as shown below.

Person.prototype.getName = function() {
return this.name;
}


4) Extend Author from Person and this is done using two steps.
a) In the constructor of Author call the Person's constructor like Person.call(this,...);
"this" as the parameter to the call method says that you are invoking Person in the Author's context,
i.e., "this" here refers to Author's Object.
b) Prototype chaining:
It is a way to define the hierarchy of objects.
Here Author's prototype is linked to Person meaning Author is an extension of Person or Author is of type Person.
This is done using Author.prototype = new Person();

5) Creating the objects is as simple as "var author = new Author();" and calling a method of its super class will be like "author.getName();"




Prototypal Inheritance

<html>
<script>

var Person = {
name: "Vinuth",
getName: function() {
return this.name;
}
};


alert(Person.getName());

function clone(obj)
{
function F(){}
F.prototype = obj;
return new F();
}

var Author = clone(Person);

Author.setName = function(name) {
this.name = name;
}

alert(Author.getName());
Author.setName("Chet");
alert(Author.getName());


</script>
</html>


All about Prototypal Inheritance

1) Most importantly there is no use of keyword "function" for defining the classes.
There is no concept of classes.
The beauty of Prototypal language is that everything is an object and there is no class concept at all.
As you can see in the above example Person is not a class but its an object and it is defined using the configuration object.
Configuration objects are defined as {...} within the flower brackets "{}".

2) Since there is no concept of classes and everything in Prototypal language is object, we do not use the keyword "new" at all.

3) extends is achieved by using prototype keyword as shown in the clone() method above.

4) Any objects can be extended as easily as just defining a method or property on the object directly as follows

Author.setName = function(name) {
this.name = name;
}

Sunday, September 27, 2009

Private Members in Javascript

I just had a glance at this wonderful article on Private Members in Javascript, its really worth a read.



Objects

JavaScript is fundamentally about objects. Arrays are objects. Functions are objects. Objects are objects. So what are objects? Objects are collections of name-value pairs. The names are strings, and the values are strings, numbers, booleans, and objects (including arrays and functions). Objects are usually implemented as hashtables so values can be retrieved quickly.

If a value is a function, we can consider it a method. When a method of an object is invoked, the this variable is set to the object. The method can then access the instance variables through the this variable.

Objects can be produced by constructors, which are functions which initialize objects. Constructors provide the features that classes provide in other languages, including static variables and methods.

Public

The members of an object are all public members. Any function can access, modify, or delete those members, or add new members. There are two main ways of putting members in a new object:

In the constructor

This technique is usually used to initialize public instance variables. The constructor's this variable is used to add members to the object.

function Container(param) {
this.member = param;
}

So, if we construct a new object

var myContainer = new Container('abc');

then myContainer.member contains 'abc'.

In the prototype

This technique is usually used to add public methods. When a member is sought and it isn't found in the object itself, then it is taken from the object's constructor's prototype member. The prototype mechanism is used for inheritance. It also conserves memory. To add a method to all objects made by a constructor, add a function to the constructor's prototype:

Container.prototype.stamp = function (string) {
return this.member + string;
}

So, we can invoke the method

myContainer.stamp('def')

which produces 'abcdef'.

Private

Private members are made by the constructor. Ordinary vars and parameters of the constructor becomes the private members.

function Container(param) {
this.member = param;
var secret = 3;
var that = this;
}

This constructor makes three private instance variables: param, secret, and that. They are attached to the object, but they are not accessible to the outside, nor are they accessible to the object's own public methods. They are accessible to private methods. Private methods are inner functions of the constructor.

function Container(param) {

function dec() {
if (secret > 0) {
secret -= 1;
return true;
} else {
return false;
}
}

this.member = param;
var secret = 3;
var that = this;
}

The private method dec examines the secret instance variable. If it is greater than zero, it decrements secret and returns true. Otherwise it returns false. It can be used to make this object limited to three uses.

By convention, we make a private that parameter. This is used to make the object available to the private methods. This is a workaround for an error in the ECMAScript Language Specification which causes this to be set incorrectly for inner functions.

Private methods cannot be called by public methods. To make private methods useful, we need to introduce a privileged method.

Privileged

A privileged method is able to access the private variables and methods, and is itself accessible to the public methods and the outside. It is possible to delete or replace a privileged method, but it is not possible to alter it, or to force it to give up its secrets.

Privileged methods are assigned with this within the constructor.

function Container(param) {

function dec() {
if (secret > 0) {
secret -= 1;
return true;
} else {
return false;
}
}

this.member = param;
var secret = 3;
var that = this;

this.service = function () {
if (dec()) {
return that.member;
} else {
return null;
}
};
}

service is a privileged method. Calling myContainer.service() will return 'abc' the first three times it is called. After that, it will return null. service calls the private dec method which accesses the private secret variable. service is available to other objects and methods, but it does not allow direct access to the private members.

Closures

This pattern of public, private, and privileged members is possible because JavaScript has closures. What this means is that an inner function always has access to the vars and parameters of its outer function, even after the outer function has returned. This is an extremely powerful property of the language. There is no book currently available on JavaScript programming that shows how to exploit it. Most don't even mention it.

Private and privileged members can only be made when an object is constructed. Public members can be added at any time.

Patterns

Public

function Constructor(...) {
this.membername = value;

}
Constructor.prototype.membername = value;

Private

function Constructor(...) {
var that = this;
var
membername = value;

function membername(...) {...}

}

Note: The function statement

function membername(...) {...}

is shorthand for

var membername = function membername(...) {...};

Privileged

function Constructor(...) {
this.membername = function (...) {...};

}

Original Source

Prototype Based Programming

Prototype-based programming is a style of object-oriented programming in which classes are not present, and behavior reuse (known as inheritance in class-based languages) is performed via a process of cloning existing objects that serve as prototypes. This model can also be known as class-less, prototype-oriented or instance-based programming.

The original (and most canonical) example of a prototype-based language is the programming language Self developed by David Ungar and Randall Smith. However, the classless programming style has recently grown increasingly popular, and has been adopted for the programming languages JavaScript, Cecil, NewtonScript, Io, MOO, REBOL, Lisaac and several others.


Comparison with class-based models

With class-based languages, the structure of objects is specified in programmer-defined types called classes. While classes define the type of data and functionality that objects will have, instances are "usable" objects based on the patterns of a particular class. In this model, classes act as collections of behavior (methods) and structure that are the same for all instances, whereas instances carry the objects' data. The role distinction is thus primarily based on a distinction between structure and behavior on the one hand, and state on the other.

Advocates of prototype-based programming often argue that class-based languages encourage a model of development that focuses first on the taxonomy and relationships between classes. In contrast, prototype-based programming is seen as encouraging the programmer to focus on the behavior of some set of examples and only later worry about classifying these objects into archetypal objects that are later used in a fashion similar to classes. As such, many prototype-based systems encourage the alteration of prototypes during runtime, whereas only very few class-based object-oriented systems (such as the first dynamic object-oriented system, Smalltalk) allow classes to be altered during the execution of a program.

While the vast majority of prototype-based systems are based around interpreted and dynamically typed programming languages, it is important to point out that statically typed systems based around prototypes are technically feasible. The Omega programming language discussed in Prototype-Based Programming [1] is an example of such a system, though according to Omega's website even Omega is not exclusively static but rather its "compiler may choose to use static binding where this is possible and may improve the efficiency of a program."

Object construction

In class-based languages a new instance is constructed through the class's constructor and an optional set of constructor arguments. The resulting instance is modeled on the layout and behavior dictated by the chosen class.

In prototype-based systems there are two methods of constructing new objects, through cloning of an existing object, and through ex nihilo ("from nothing") object creation. While most systems support a variety of cloning, ex nihilo object creation is not as prominent.[2]

Systems that support ex nihilo object creation allow new objects to be created from scratch without cloning from an existing prototype. Such systems provide a special syntax for specifying the properties and behaviors of new objects without referencing existing objects. In many prototype languages, there is often a basic Object prototype that carries commonly needed methods and is used as a master prototype for all other objects. One useful aspect of ex nihilo object creation is to ensure that a new object's slot names do not have namespace collisions with the top-level Object object. (In the Mozilla JavaScript implementation, one can accomplish this by setting a newly constructed object's __proto__ property to null.)

Cloning refers to a process whereby a new object is constructed by copying the behavior of an existing object (its prototype). The new object then carries all the qualities of the original. From this point on, the new object can be modified. In some systems the resulting child object maintains an explicit link (via delegation or resemblance) to its prototype, and changes in the prototype cause corresponding changes to be apparent in its clone. Other systems, such as the Forth-like programming language Kevo, do not propagate change from the prototype in this fashion, and instead follow a more concatenative model where changes in cloned objects do not automatically propagate across descendants.[3]

//Example of true prototypal inheritance style in JavaScript.

//"ex nihilo" object creation employing the literal object notation {}.
var foo = {one: 1, two: 2};
//another "ex nihilo" object.
var bar = {three: 3};

//Gecko and Webkit JavaScript engines can directly manipulate the internal prototype link.
//For the sake of simplicity, let's just pretend that the following line works regardless of the engine used:
bar.__proto__ = foo; // bar is now the child of foo.

//If we try to access foo's properties from bar from now on, we'll succeed.
bar.one //resolves to 1.

//The child objects properties are also accessible.
bar.three //resolves 3.

Delegation

In prototype-based languages that use delegation, the language runtime is capable of dispatching the correct method or finding the right piece of data simply by following a series of delegation pointers (from object to its prototype) until a match is found. All that is required to establish this behavior-sharing between objects is the delegation pointer. Unlike the relationship between class and instance in class-based object-oriented languages, the relationship between the prototype and its offshoots does not require that the child object have a memory or structural similarity to the prototype beyond this link. As such, the child object can continue to be modified and amended over time without rearranging the structure of its associated prototype as in class-based systems. It is also important to note that not only data but also methods can be added or changed. For this reason, most prototype-based languages refer to both data and methods as "slots".

Criticism

Advocates of class-based object models who criticize prototype-based systems often have concerns that could be seen as similar to those concerns that proponents of static type systems for programming languages have of dynamic type systems (see Datatype). Usually, such concerns involve: correctness, safety, predictability, and efficiency.

On the first three points, classes are often seen as analogous to types (in most statically typed object-oriented languages they serve that role) and are proposed to provide contractual guarantees to their instances, and to users of their instances, that they will behave in some given fashion.

On the last point, efficiency, the declaration of classes simplifies many compiler optimizations that allow developing efficient method and instance variable lookup. For the Self language, much development time was spent on developing, compiling, and interpreting techniques to improve the performance of prototype-based systems versus class-based systems. For example, the Lisaac compiler produces code almost as fast as C. Tests have been run with an MPEG-2 codec written in Lisaac, copied from a C version. These tests show the Lisaac version is 1.9% slower than the C version with 37% fewer lines of code[5].

The most common criticism made against prototype-based languages is that the community of software developers is not familiar with them, despite the popularity and market permeation of JavaScript. This knowledge level of prototype based systems seems to be changing with the proliferation of JavaScript frameworks and increases in the complex use of JavaScript as "Web 2.0" matures.