blogger templates blogger widgets
Showing posts with label archive. Show all posts
Showing posts with label archive. Show all posts
This is part of a list of blog posts.
To browse the contents go to

Practical EJB

Below notes are from the Head First Book.

In EJB, remember, the Remote object (EJBObject) is the bean’s bodyguard. The bean sits back, protected from all client invocations, while the EJBObject implements the Remote interface and takes the remote calls



Session beans

Clients share the Home, but never the bean.Each client gets his own EJBObject reference and his own bean. The client never shares a bean with another client, although the meaning of “shares” depends on whether the bean is stateful or stateless.



Entity beans

Clients share the Home, and may share the bean.



Rules for local interfaces:

- Import javax.ejb.* (or use fully-qualified names).

- Extend EJBLocalObject (for the component interface) or EJBLocalHome (for the home interface).

- Declare one or more business methods in the component interface.

- All create methods in the local home must return the local component interface, and declare a CreateException.

- Any method you declare in the home or component interface can declare your own application exceptions, which must be compiler-checked exceptions (i.e. not subclasses of RuntimeException).

- You must NOT declare a RemoteException for any methods


isIdentical Method:



Session Beans:



Stateful session beans: Creation and Invocation


When ejbPassivate() completes, every non-transient instance variable MUST be a reference to one of the following:
- a Serializable object
- a null value
- a bean’s remote component or home interface, even if the stub class is not Serializable (in other words, you don’t have to worry about it!)
- a bean’s local component or home interface, even if it’s not Serializable (again, you don’t have to worry)
- a SessionContext object, even if it’s not Serializable
- the bean’s special JNDI context, or any of its subcontexts
- the UserTransaction interface (something you can get from your SessionContext—we’ll see that in the transactions chapter)
- a resource manager connection factory (like, an instance of javax.sql.DataSource)

ejbPassivate() - Your role - Make sure your instance variables are ready for passivation.
ejbActivate() - Your role - Reacquire your non-Serializable resources, or do whatever it takes to restore your state for use.

there’s a little teeny comment in the spec which says that there’s an exception to the rule that passivation behave just like serialization. The exception is that while serialization is required to bring back transient fields with default values, passivation doesn’t guarantee that!

What does this mean? Think about it. It means you can’t rely on transient to give you back your defaults, so after activation, you could end up with, well, anything in a variable that’s marked transient.

So, you are free to use transient, and it can make passivation more efficient, but the implication is—reset your transient variables yourself, in ejbActivate().

Things you can add if the bean is stateFULYou can have more than one create method.The create method can have arguments.The bean can be passivated, so you can write code in ejbPassivate() and ejbActivate().


Entity Beans

Client wants access to an existing entity:


Client wants to create a new entity:



Note:
In entity beans: create == new row, new EJB object
In stateful beans: create == new bean, new EJB object
In stateless beans: create == new EJB object (Container does not make a new session bean when the client calls create(), and does not pull one out of the pool until the client invokes a business method)

In entity beans: remove == deletes row, marks bean for GC
In stateful beans: remove == marks the bean for GC
In stateless beans: remove == Container doesn't care. The bean is already moved to the pool.

Synchronization of data


Forget about BMP, never used by anyone after EJB 2.0 spec.

Passivation difference between all 3 types:

- Stateless session beans go back to the pool without passivation (in other words, without getting an ejbPassivate() call).

- Stateful session beans are passivated when the Container puts them to sleep (possibly serialization) to conserve resources between client method invocations.

- Entity beans aren’t passivated in the way that stateful session beans are, but entity beans DO get an ejbPassivate() call when they’re about to go back to the pool (and an ejbActivate() when they come out of the pool).

- The most important point is that, unlike session beans, passivated entity beans are still live objects on the heap!

- There’s no such thing as a bean sleeping in a pool. Stateless beans, entity beans, and message-driven beans all use pools. And those pools are for living, RAM-using, on-the-heap objects.

- Only stateful beans are put to sleep (called, confusingly, passivation), but this has nothing to do with a pool.


Bean Construction

Before the client can use a bean for ANYTHING -- creation, finders, business methods, etc., the Container has to make a new bean instance for the pool. Bean CONSTRUCTION isn’t tied to entity bean CREATION.


Bean Creation



There are tons of rules about which methods you write and how it should be written.

CMP and CMR

The only difference between a CMP (container-managed persistent column data) field and a CMR (container-managed persistent relationship) field is the TYPE.

A CMR field is always another entity bean’s local interface type, or a Collection of them.

If it’s a Collection, it must be either java.util.Collection or java.util.Set.

You need a pair of abstract getters and setters for each CMP field (column values) and each CMR field (relationship with another entity).

APS

To define persistent fields and relationships, you need to create an abstract persistence schema. Defining the virtual fields isn’t enough. Your abstract persistence schema is a combination of your virtual fields in your bean class, plus some things you write in the deployment descriptor.

There are some naming conventions here too.

--
http://www.theserverside.com/discussions/thread/552.html

It seems to me that the J2EE platform has two competing solutions for storing client state: Stateful session beans and HttpSession parameters.

One of the most difficult thinks in the OO world is to give the right role to the right object.
Using Stateful session Beans is relevant when you need a "state machine" for your business logic, and it's is independent from how you "interact" with the system (WAP/WML, HTML, XML/B2B, etc).

HTTP session is for objects that drive the "application". It provides "state machine" for presentation logic.

There's an interesting issue with respect to timeout. If navigational state etc. is stored in the HttpSession and some other state is in stateful session beans, here's a possible problem scenario:

A user logs on to the system and does something that involves creating and using a stateful session bean. Then the user moves around for a while using functionality that does not touch the bean, thus repeatedly resetting the timeout of the HttpSession. It is then possible that the next time the user triggers a function that involves the bean, it may have timed out. The user of course expects his session to be far from timed out, since he's been working all the time. So he will not be very happy if the system tells him that, "sorry, you will have to log in again".

The only solution I can see to this problem would be to set the bean timeout so high/indefinite that the situation is unlikely to happen.

---

Transactions

You could do BMT and CMT.

BMT - short example.

Get a UserTransaction reference from your EJBContext.

context.getUserTransaction()
Start the transaction.

ut.begin()
End the transaction (commit or rollback).

ut.commit()
ut.rollback()

CMT - is how it needs to be done 99% of cases.

But how do we control the scope of transactions? Well, configurations as always. You don’t write anything transactional in your code except maybe an occasional call to EJBContext.setRollbackOnly() or EJBContext.getRollbackOnly()

CMT beans call getRollbackOnly() to find out if the transaction they’re in is already doomed. If the transaction is never going to commit, why should the bean waste time with lots of code?

An entity bean has ejbLoad() and ejbStore() to tell it when to synchronize with the database. If the transaction is about to commit, ejbStore() is called to give the bean one last chance to get it’s persistent state in order, ready to be written to the database. And if the transaction does not commit, the bean just gets another ejbLoad() to return it to its original pre-transaction state, and everything is fine.

But a session bean doesn’t have that luxury. No ejbLoad()or ejbStore() to tell it when it’s time to synchronize itself with a database. But if your session bean implements SessionSynchronization, you can give a session bean three new container callbacks, that notify the bean of three more special moments in the bean’s transactional life: when a transaction starts, when it’s about to end, and when it’s over.



those three-letter-acronyms - JTS, JTA, JCA, EJB, CDI


Ah those 3-letter-acronyms

My inspiration and drive behind this serious of posts/notes is a comment that I read on this site by Tim Jansen

I believe the reason why people are using Tomcat rather than a complete JEE server is that they DON’T KNOW all those three-letter-acronym frameworks (JPA, JMA, JTA, EJB, JSF, CDI). JEE is huge, and there is hardly any publically available documentation for it.

Basically you have the choice between complete overload (API Docs and several thousand pages of specifications) on the one hand, and documents that hardly scratch the surface (Sun’s JEE tutorial and JBoss’ Getting Started Guide) on the other hand.

Compared to this, Tomcat is attractive because it is relatively small. Servlets, JSPs and JDBC is all that you need to know. And, even better, there haven’t been any major changes in the last 10 years.

Spring adds many of the capabilities that you will miss in plain Tomcat. And even though Spring is relatively large now, there is only one framework, and a single, free, easy-to-understand but still comprehensive ‘Reference Documentation’ for it. I think pretty much everyone who ever used Spring learned it from that document.

While I would totally agree that JEE5 and 6 are great frameworks, they are still too hard to learn. There is not enough free documentation to show people how to work with it. And the API documentation and specs are literally *contaminated* with old backward-compatibility crud from the J2EE age that you don’t need to know to start a new application, but still makes up 80% of the documentation and confuses the hell out of people.


Most of what I'm writing here are notes taken from other books or sites and that's kind of plagiarism. But God help us.

Must of us are forced to learn these specs and frameworks and we have no option but to sniff around and learn stuff instead of spending hundreds of dollars on some corporation's training.

And I share because there are many people out there like me.

So where do I start?

Let's go back to 1997 when java developers moved from Java Applets to thin clients. The basic idea behind the thin clients was as simple as it was radical: move the entire business logic to the server and limit the client’s responsibilities to presentation logic and user interaction.

And that's what we have today. Since all the business logic is moved to the server, the server now needs to take care of a lot of things - Persistence and CRUD operations using JDBC, Business logic using Servlets, Generating presentation using JSPs, Managing 3rd party (service) communications using standard JDK, etc.

The most important among these was the CRUD operations using JDBC.


JDBC - DriverManager

First, we had web applications written that used the JDBC DriverManager to get the connection for each request.


Need for pooling

Creating connections every time a situation demanded caused much overhead on the server. So then came the concept of connection pools.


Note that most databases maintains a connection object pool (within the DB) which is irrelevant in our discussion. Also note that your web server has no role to control over this.

This practice of creating and maintaining connection pool within the application was tedious and error prone.

JDBC - DataSource

Then came JDBC 2.0 and with it came DataSource interface.
When using data sources, the developers had the opportunity to decide whether to use a library (like c3p0 or dbcp that supports data sources) for connection pooling or to leave the whole thing to server.

Using libraries,


Using servers,


Along the same time came JNDI and eventually, the best approach that came into practice was the data source being configured and managed by the server/container and your application just requests connection objects from this data source.

There are code samples and explanations for all the above approaches here.

Transactions

But then came businesses and thus transactions. (Well transactions were there much before that.)

A transaction is a collection of read/write operations succeeding only if all contained operations succeed.

Inherently a transaction is characterized by four properties (commonly referred as ACID) :

  • Atomicity
  • Consistency
  • Isolation
  • Durability

Atomicity
Atomicity takes individual operations and turns them into an all-or-nothing unit of work, succeeding if and only if all contained operations succeed.

Durability
A successful transaction must permanently change the state of a system, and before ending it, the state changes are recorded in a persisted transaction log.

Isolation
Transactions cannot interfere with each other (as an end result of their executions)

Consistency
Every transaction must leave the database in a consistent (correct) state.
If one operation triggers secondary actions (CASCADE, TRIGGERS), those must also succeed otherwise the transaction fails.
If the system is composed of multiple nodes, then consistency mandates that all changes be propagated to all nodes (multi-master replication). If slaves nodes are updated asynchronously then we break the consistency rule, the system becoming “eventually consistent“.

From a database perspective, the atomicity is a fixed property, but everything else may be traded-off for performance/scalability reasons.

But let’s see how a simple web application can handle transactions.

Simple, Humbler path

Here we manually switch off auto commit on the connection (or it can be made permanently false by setting the correct attributes on the datasource) then based on the business logic we commit or rollback the operations.
code:

someDAOMethod() {
Connection conn = getConnectionFromDatasource();
conn.setAutoCommit(false);
try {
do some insert/update/delete/select based on your business logic
do some more…
if (something doesn’t seem right) {
conn.rollback();
return;
}
do some more…
conn.commit(); //hopefully all is well
} catch(Exception e){
conn.rollback();
} finally {
conn.close();
}
}

For simple applications that are sure to not grow in size and popularity this is fine.

But in cases when your business model is huge with tons of logic in there - this approach will make it extremely error prone.

Let’s say your web-based application has complex business requirements.
The implementation uses a logical three tier architecture with a web layer, a business-object layer, and a data access layer, all running in the same JVM. In such a layered architecture, transaction management belongs in the business object layer, and is typically demarcated at business facades.
The data access layer will participate in transactions but should not drive them, enabling separate data access methods to be used in the one transaction.

How do we propagate transactions across multiple data access methods?

A naïve approach might be to fetch a JDBC Connection at the beginning of the business object method, switch it to manual commit mode, pass it to various
data access methods, and trigger a commit or rollback in the business object method before it returns.
This has the major drawback of coupling both the business objects and the data access objects to the specific transaction and data access strategy (in this case JDBC).

insideBusinessFunction() {
Connection conn = getConnectionFromDatasource();
conn.setAutoCommit(false);
try {
do some business logic
call daoMethod_1(conn, parameters…)
if (something doesn’t seem right) {
conn.rollback();
return;
}
call daoMethod_2(conn, parameters…)
call daoMethod_3(conn, parameters…)
conn.commit(); //hopefully all is well
} catch(Exception e){
conn.rollback();
} finally {
conn.close();
}
}

To achieve proper abstract transaction management, we need coordinating infrastructure.
That’s were JTA comes into picture.


Enter JTA - Java Transaction API

The Java Transaction API (JTA) allows applications to perform distributed transactions, that is, transactions that access and update data on two or more networked computer resources.
The JTA specifies standard Java interfaces between a transaction manager and the parties involved in a distributed transaction system:
the application,
the application server, and
the resource manager (eg. DB driver) that controls access to the shared resources affected by the transactions.

XAResource
The JTA interface between transaction manager and the resource manager is called the javax.transaction.xa.XAResource interface is a Java mapping of the industry standard XA interface based on the X/Open CAE Specification (Distributed Transaction Processing: The XA Specification).


As a developer, you can choose between using programmatic transaction demarcation in the EJB code (bean-managed) or declarative demarcation (container-managed). Regardless of whether an enterprise bean uses bean-managed or container-managed transaction demarcation, the burden of implementing transaction management is on the J2EE/EJB container.

From the outside world you can interact with JTA either through your code (programmatically) or through the J2EE server.

Bean managed (Programmatic transaction demarcation)

There are two types of bean-managed transactions:
  • JDBC type
  • JTA type

The javax.transaction.UserTransaction interface provides the application the ability to control transaction boundaries programmatically. The javax.transaction.UserTransaction method starts a global transaction and associates the transaction with the calling thread.


Container managed (Declarative transaction demarcation)

In this case, Transaction management is often accomplished using EJBs with CMT (Container-Managed Transactions).

The advantage of CMT is that it keeps transaction demarcation out of the Java code by moving it into the EJB deployment descriptor. Thus, transaction demarcation becomes a cross-cutting aspect that does not need to be hard-coded into application objects. Transactionality is associated with methods on the EJB’s component interface, a neat and usually appropriate harnessing of the programming language.

The javax.transaction.TransactionManager interface allows the application server to control transaction boundaries on behalf of the application being managed.


We will look at both in detail but before that let's see JTA's main advantage - the distributed transaction support works.


How transaction manager supports distributed transactions


The first step of the distributed transaction process is for the application to send a request for the transaction to the transaction manager. Although the final commit/rollback decision treats the transaction as a single logical unit, there can be many transaction branches involved. A transaction branch is associated with a request to each resource manager involved in the distributed transaction. Requests to three different RDBMSs, therefore, require three transaction branches. Each transaction branch must be committed or rolled back by the local resource manager. The transaction manager controls the boundaries of the transaction and is responsible for the final decision as to whether or not the total transaction should commit or rollback. This decision is made in two phases, called the Two-Phase Commit Protocol.

In the first phase, the transaction manager polls all of the resource managers (RDBMSs) involved in the distributed transaction to see if each one is ready to commit. If a resource manager cannot commit, it responds negatively and rolls back its particular part of the transaction so that data is not altered.

In the second phase, the transaction manager determines if any of the resource managers have responded negatively, and, if so, rolls back the whole transaction. If there are no negative responses, the translation manager commits the whole transaction, and returns the results to the application.





Bean managed (Programmatic transaction demarcation)


There are two types of bean-managed transactions:

  • JDBC type—You delimit JDBC transactions with the commit and rollback methods of the connection interface.
  • JTA type—You invoke the begin, commit, and rollback methods of the UserTransaction interface to demarcate JTA transactions.

We have already seen how JDBC transactions work and why that’s not a good design (Never mix business objects and the data access objects).

So now let’s see how to programmatically do JTA.

The javax.transaction.UserTransaction interface provides the application the ability to control transaction boundaries programmatically. The javax.transaction.UserTransaction method starts a global transaction and associates the transaction with the calling thread.

You must first implement an Xid class for identifying transactions (this would normally be done by the transaction manager). The Xid contains three elements: formatID, gtrid (global transaction ID), and bqual (branch qualifier ID).

The formatID is usually zero, meaning that you are using the OSI CCR (Open Systems Interconnection Commitment, Concurrency, and Recovery standard) for naming. If you are using another format, the formatID should be greater than zero A value of -1 means that the Xid is null.

The gtrid and bqual can each contain up to 64 bytes of binary code to identify the global transaction and the branch transaction, respectively. The only requirement is that the gtrid and bqual taken together must be globally unique. Again, this can be achieved by using the naming rules specified in the OSI CCR.

I tested this with IBM DB2.

package com.test.jta;

import javax.transaction.xa.Xid;

public class MyXid implements Xid {
protected int formatId;
protected byte gtrid[];
protected byte bqual[];

public MyXid() {
}

public MyXid(int formatId, byte gtrid[], byte bqual[]) {
this.formatId = formatId;
this.gtrid = gtrid;
this.bqual = bqual;
}

public int getFormatId() {
return formatId;
}

public byte[] getBranchQualifier() {
return bqual;
}

public byte[] getGlobalTransactionId() {
return gtrid;
}
}

package com.test.main;

import java.sql.Connection;
import java.sql.SQLException;
import java.sql.Statement;

import javax.sql.XAConnection;
import javax.transaction.xa.XAException;
import javax.transaction.xa.XAResource;
import javax.transaction.xa.Xid;

import com.ibm.db2.jcc.DB2XADataSource;
import com.test.jta.MyXid;

public class TestMain {

public static void main(String[] args) {
DB2XADataSource xaDS;
XAConnection xaCon = null;
XAResource xaRes;
Xid xid;
Connection con = null;
Statement stmt;
int ret;
try {
xaDS = new com.ibm.db2.jcc.DB2XADataSource();
xaDS.setDataSourceName("db2ds");
xaDS.setDatabaseName("wcsdb");
xaCon = xaDS.getXAConnection("db2admin", "db2admin");
xaRes = xaCon.getXAResource();

con = xaCon.getConnection();
stmt = con.createStatement();

xid = new MyXid(100, new byte[] { 0x01 }, new byte[] { 0x02 });
System.out.println("transaction starting");
xaRes.start(xid, XAResource.TMNOFLAGS);
stmt.executeUpdate("insert into atest(bcol) values ('hello boy')");
xaRes.end(xid, XAResource.TMSUCCESS);
System.out.println("transaction ending");
ret = xaRes.prepare(xid);
if (ret == XAResource.XA_OK) {
xaRes.commit(xid, false);
}else {
xaRes.rollback(xid);
}
System.out.println("transaction committed");
} catch (XAException e) {
e.printStackTrace();
} catch (SQLException e) {
e.printStackTrace();
} finally {
try {
con.close();
xaCon.close();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}

}
}
}

What happens if we mix local transactions in between these XA transactions?

It shouldn't cause any problem provided we are suspending the xa transaction which allows the same connection to do a local operation.
xaRes.start(xid, XAResource.TMNOFLAGS);
stmt.executeUpdate(...);
xaRes.end(xid, XAResource.TMSUSPEND);

// This update is done outside of transaction scope, so it
// is not affected by the XA rollback.
stmt.executeUpdate(...);

xaRes.start(xid, XAResource.TMRESUME);

What happens if one XA resource is shared among 2 transactions?

Two transaction branches are created, but they do not belong to the same distributed transaction. JTA allows the XA resource to do a two-phase commit on the first branch even though the resource is still associated with the second branch.

xid1 = new MyXid(100, new byte[]{0x01}, new byte[]{0x02});
xid2 = new MyXid(100, new byte[]{0x11}, new byte[]{0x22});

xaRes.start(xid1, XAResource.TMNOFLAGS);
stmt.executeUpdate(...);
xaRes.end(xid1, XAResource.TMSUCCESS);

xaRes.start(xid2, XAResource.TMNOFLAGS);

// Should allow XA resource to do two-phase commit on
// transaction 1 while associated to transaction 2
ret = xaRes.prepare(xid1);
if (ret == XAResource.XA_OK) {
xaRes.commit(xid1, false);
}

stmt.executeUpdate(...);
xaRes.end(xid2, XAResource.TMSUCCESS);

ret = xaRes.prepare(xid2);
if (ret == XAResource.XA_OK) {
xaRes.rollback(xid2);
}

How transaction branches on different connections can be joined as a single branch if they are connected to the same resource manager?

Yes. This feature improves distributed transaction efficiency because it reduces the number of two-phase commit processes. Two XA connections to the same database server are created. Each connection creates its own XA resource, regular JDBC connection, and statement. Before the second XA resource starts a transaction branch, it checks to see if it uses the same resource manager as the first XA resource uses. If this is case, as in this example, it joins the first branch created on the first XA connection instead of creating a new branch. Later, the transaction branch can be prepared and committed using either XA resource.

xaCon1 = xaDS.getXAConnection("jdbc_user", "jdbc_password");
xaRes1 = xaCon1.getXAResource();
con1 = xaCon1.getConnection();
stmt1 = con1.createStatement();

xid1 = new MyXid(100, new byte[]{0x01}, new byte[]{0x02});
xaRes1.start(xid1, XAResource.TMNOFLAGS);
stmt1.executeUpdate("insert into test_table1 values (100)");
xaRes1.end(xid, XAResource.TMSUCCESS);

xaCon2 = xaDS.getXAConnection("jdbc_user", "jdbc_password");
xaRes2 = xaCon2.getXAResource();
con2 = xaCon2.getConnection();
stmt2 = con2.createStatement();

if (xaRes2.isSameRM(xaRes1)) {
xaRes2.start(xid1, XAResource.TMJOIN);
stmt2.executeUpdate("insert into test_table2 values (100)");
xaRes2.end(xid1, XAResource.TMSUCCESS);
}
else {
xid2 = new MyXid(100, new byte[]{0x01}, new byte[]{0x03});
xaRes2.start(xid2, XAResource.TMNOFLAGS);
stmt2.executeUpdate("insert into test_table2 values (100)");
xaRes2.end(xid2, XAResource.TMSUCCESS);
ret = xaRes2.prepare(xid2);
if (ret == XAResource.XA_OK) {
xaRes2.commit(xid2, false);
}
}

ret = xaRes1.prepare(xid1);
if (ret == XAResource.XA_OK) {
xaRes1.commit(xid1, false);
}


Partially programmatic

There is another way to do all this by configuring the XA datasource on your J2EE application server and then use JNDI to look it up and get xa connections from it. (Remember you select non-managed or non-CMB when creating the datasource).


Container managed (Declarative transaction demarcation)

In this case, Transaction management is often accomplished using EJBs with CMT (Container-Managed Transactions).

The advantage of CMT is that it keeps transaction demarcation out of the Java code by moving it into the EJB deployment descriptor. Thus, transaction demarcation becomes a cross-cutting aspect that does not need to be hard-coded into application objects. Transactionality is associated with methods on the EJB’s component interface, a neat and usually appropriate harnessing of the programming language.

Another advance of EJB CMT is that it allows us to use a lot of container-specific features can be addressed only via the EJB deployment descriptor, like custom isolation levels as an important setting for JDBC transactions.

Another advantage is support for remote transaction propagation.

So far, we have considered only transactions within a single application server JVM.

The EJB component model supports this notion of transaction propagation: propagation
across calls to remote servers. However, such interoperability is not required by the J2EE 1.3 specification.
The original intention of the EJB 1.x transaction model was to allow for using a Java Transaction
Service—that is, the Java mapping of the OMG Object Transaction Service specification for CORBA—underneath.
Using EJB architecture JTS can now propagate transaction contexts across remote calls to other servers.

Disadvantages:

In EJB 1.0 and 1.1, EJBs offered only remote interfaces, meaning that declarative transaction management
was an option only if an object was made distributed, or at least pseudo-distributed.
Since the release of EJB 2.0 in 2001, CMT has required less overhead, as it became possible to give EJBs only local interfaces.

Note that you do not need EJB’s remote transaction propagation to execute a single remote method invocation that runs within its own transaction, probably the commonest requirement in distributed applications.
In such a scenario, a new transaction context will be started when the call arrives at the remote
server, and ended when the call returns. This can entirely be handled by the service implementation on the server, and does not have to affect the client or the remoting protocol in the first place. A lightweight remoting solution like RMI-JRMP or Hessian/Burlap can serve perfectly well here.

The main value of remote EJBs lies in the ability to propagate existing transaction contexts from one JVM to another, which is often not needed at all. (Keeping transaction contexts open over multiple remote calls, as when making several invocations to a Stateful Session Bean in the same transaction, is inherently dangerous. For example, if there’s a network failure, the transaction may be left open, unnecessarily consuming resources and locking out other calls.)

Before we get into EJB let's see the different transaction attributes allowed by your container.


Transaction attributes

A transaction attribute is a parameter that controls the scope of a transaction.

Because transaction attributes are stored in the deployment descriptor, they can be changed during several phases of J2EE application development: at EJB creation, at assembly (packaging), or at deployment. However, as an EJB developer, it is your responsibility to specify the attributes when creating the EJB.

You can specify the transaction attributes for the entire enterprise bean or for individual methods. If you've specified one attribute for a method and another for the bean, the attribute for the method takes precedence.

A transaction attribute may have one of the following values:

  • Required
  • RequiresNew
  • Mandatory
  • NotSupported
  • Supports
  • Never

Required
If the client is running within a transaction and invokes the enterprise bean's method, the method executes within the client's transaction. If the client is not associated with a transaction, the container starts a new transaction before running the method.

RequiresNew
If the client is running within a transaction and invokes the EJB's method, the container takes the following steps:
1. Suspends the client's transaction.
2. Starts a new transaction.
3. Delegates the call to the method.
4. Resumes the client's transaction after the method completes.
If the client is not associated with a transaction, the container starts a new transaction before running the method.

Mandatory
If the client is running within a transaction and invokes the EJB's method, the method executes within the client's transaction. If the client is not associated with a transaction, the container throws a TransactionRequiredException.

NotSupported
If the client is running within a transaction and invokes the EJB's method, the container suspends the client's transaction before invoking the method. After the method has completed, the container resumes the client's transaction.
If the client is not associated with a transaction, the container does not start a new transaction before running the method.

Supports
If the client is running within a transaction and invokes the EJB's method, the method executes within the client's transaction. If the client is not associated with a transaction, the container does not start a new transaction before running the method.

Never
If the client is running within a transaction and invokes the enterprise bean's method, the container throws a RemoteException. If the client is not associated with a transaction, the container does not start a new transaction before running the method.
Use the NotSupported attribute for methods that don't need transactions. Because transactions involve overhead, this attribute may improve performance.

The following table summarizes the effects of the transaction attributes. Transactions can be T1, T2, or None. (Both T1 and T2 transactions are controlled by the container.)

T1 transaction—Is associated with the client that calls a method in the enterprise bean. In most cases, the client is another enterprise bean.
T2 transaction—Is started by the container, just before the method executes.

Table 6-1  Transaction Attributes and Scope 

Transaction Attribute

Client's Transaction

Business Method's Transaction

Required

None

T2

T1

T1

RequiresNew

None

T2

T1

T2

Mandatory

None

Error

T1

T1

NotSupported

None

None

T1

None

Supports

None

None

T1

T1

Never

None

None

Ti

Error



Rolling Back a Container-Managed Transaction

There are two ways to roll back a container-managed transaction:

First, if a system exception is thrown, the container automatically rolls back the transaction.
Second, by invoking the setRollbackOnly method of the EJBContext interface, the bean method instructs the container to roll back the transaction. If the bean throws an application exception, the rollback is not automatic, but may be initiated by a call to setRollbackOnly.


How ISOLATION is handled for overlapping transactions?

Usually concurrency control is achieved through locking. But as we all know, locking increases the serializable portion of the executed code, affecting parallelization.

The SQL standard defines four Isolation levels:

READ_UNCOMMITTED
READ_COMMITTED
REPEATABLE_READ
SERIALIZABLE

All but the SERIALIZABLE level are subject to data anomalies (phenomena) that might occur according to the following pattern:

Dirty read

A dirty read happens when a transaction is allowed to read uncommitted changes of some other running transaction. This happens because there is no locking preventing it. In the picture above, you can see that the second transaction uses an inconsistent value as of the first transaction had rollbacked.


Non-repeatable read

A non-repeatable read manifests when consecutive reads yield different results due to a concurring transaction that has just updated the record we’re reading. This is undesirable since we end up using stale data. This is prevented by holding a shared lock (read lock) on the read record for the whole duration of the current transaction.


Phantom read

A phantom read happens when a second transaction inserts a row that matches a previously select criteria of the first transaction. We therefore end up using stale data, which might affect our business operation. This is prevented using range locks or predicate locking.


Even if the SOL standard mandates the use of the SERIALIZABLE isolation level, most database management system use a different default level.

Defaults for Oracle, Postgres, MSSQL is READ_COMMITED, MySQL is REPEATABLE_READ and DB2 is CURSOR STABILITY.

Note that individual database vendors along with their j2ee server products provide various different methodologies.


Table 16.1. Transaction Isolation Levels

Transaction Level


Dirty Read


Phantom Read


Nonrepeatable


Restriction


Performance


TRANSACTION_NONE


N/A


N/A


N/A


Lowest


Fastest


TRANSACTION_UNCOMMITED


Yes


Yes


Yes


Low


Faster


TRANSACTION_READ_COMMITED


No


Yes


Yes


High


Fast


TRANSACTION_REPEATABLE_READ


No


Yes


No


Higher


Medium


TRANSACTION_SERIALIZABLE


No


No


No


Highest


Slow



Locking mechanisms - Optimistic and pessimistic locking

Optimistic and pessimistic locking (or concurrency control) are ways of addressing a problem such as the following:
1. User A reads the row for customer #123
2. User B reads the row for customer #123
3. User B updates the row for customer #123
4. User A updates the row for customer #123 and overwrites User B’s changes
The problem here is that one user has changes that conflict with another user’s, and unless we do something about it, we’ll lose User B’s changes without even noticing.
The pessimistic concurrency control approach is to have the database server lock the row on User A’s behalf, so User B has to wait until User A has finished its work before proceeded. We effectively solve the problem by not allowing two users to work on the same piece of data at the same time. It just prevents the conflict.
The optimistic concurrency control approach doesn’t actually lock anything – instead, it asks User A to remember what the row looked like when he first saw it, and when it’s time to update it, the user asks the database to go ahead only if the row still looks like he remembers it. It doesn’t prevent a possible conflict, but it can detect it before any damage is done and fail safely.

Behind the scenes on the physical connection and database these could be implemented in various ways.

The major methods, which have each many variants, and in some cases may overlap or be combined, are:

Locking (e.g., Two-phase locking - 2PL)

Controlling access to data by locks assigned to the data. Access of a transaction to a data item (database object) locked by another transaction may be blocked (depending on lock type and access operation type) until lock release.

Serialization graph checking (also called Serializability, or Conflict, or Precedence graph checking)

Checking for cycles in the schedule's graph and breaking them by aborts.
Timestamp ordering (TO) - Assigning timestamps to transactions, and controlling or checking access to data by timestamp order.

Commitment ordering (or Commit ordering; CO)

Controlling or checking transactions' chronological order of commit events to be compatible with their respective precedence order.

Other major concurrency control types that are utilized in conjunction with the methods above include:

Multiversion concurrency control (MVCC)

Increasing concurrency and performance by generating a new version of a database object each time the object is written, and allowing transactions' read operations of several last relevant versions (of each object) depending on scheduling method. eg: Shadow paging

Index concurrency control

Synchronizing access operations to indexes, rather than to user data. Specialized methods provide substantial performance gains.

Private workspace model (Deferred update)

Each transaction maintains a private workspace for its accessed data, and its changed data become visible outside the transaction only upon its commit


Databases role in this connection and concurrency management

Wait a sec. We java developers need to be concerned with all this right? that's why we have JTA, JPA and stuff.

Well, usually we need not get our hands dirty.

Each setting that you provide for the JTA, eg: the isolation levels. get's reflected when connections are received from the database.

URL:
https://iggyfernandez.files.wordpress.com/2010/01/nocoug-200511-no-free-lunch-read-consistency.pdf




Understanding JVM internals


What is the Java Virtual Machine?

The Java Virtual Machine, or JVM, is an abstract computer that runs compiled Java programs.

The JVM is "virtual" because it is generally implemented in software on top of a "real" hardware platform and operating system. All Java programs are compiled for the JVM. Therefore, the JVM must be implemented on a particular platform before compiled Java programs will run on that platform.


How it differs from C++?

C++ is compiled directly to machine code which is then executed directly by the central processing unit.

Java is compiled to byte-code which the Java virtual machine (JVM) then interprets at runtime. Actual Java implementations do just-in-time compilation to native machine code.
So you could say there are 2 levels of compilation in Java.
Alternatively, the GNU Compiler for Java can compile directly to machine code.


Is Java truly portable?

Portability isn't a black and white, yes or no kind of thing. Portability is how easily one can I take a program and run it on all of the platforms one cares about.

There are a few things that affect this. One is the language itself. The Java language spec generally leaves much less up to "the implementation". For example, "i = i++" is undefined in C and C++, but has a defined meaning in Java. More practically speaking, types like "int" have a specific size in Java (eg: int is always 32-bits), while in C and C++ the size varies depending on platform and compiler. These differences alone don't prevent you from writing portable code in C and C++, but you need to be a lot more diligent.

Another is the libraries. Java has a bunch of standard libraries that C and C++ don't have. For example, threading, networking and GUI libraries. Libraries of these sorts exist for C and C++, but they aren't part of the standard and the corresponding libraries available can vary widely from platform to platform.

Finally, there's the whole question of whether you can just take an executable and drop it on the other platform and have it work there. This generally works with Java, assuming there's a JVM for the target platform. (and there are JVMs for many/most platforms people care about) This is generally not true with C and C++. You're typically going to at least need a recompile, and that's assuming you've already taken care of the previous two points.


Java bytecodes

Java programs are compiled into a form called Java bytecodes. The JVM executes Java bytecodes, so Java bytecodes can be thought of as the machine language of the JVM. The Java compiler reads Java language source (.java) files, translates the source into Java bytecodes, and places the bytecodes into class (.class) files. The compiler generates one class file per class in the source.


JVM Instructions

To the JVM, a stream of bytecodes is a sequence of instructions. Each instruction consists of a one-byte opcode and zero or more operands. The opcode tells the JVM what action to take. If the JVM requires more information to perform the action than just the opcode, the required information immediately follows the opcode as operands.
A mnemonic is defined for each bytecode instruction. The mnemonics can be thought of as an assembly language for the JVM. For example, there is an instruction that will cause the JVM to push a zero onto the stack. The mnemonic for this instruction is iconst_0, and its bytecode value is 60 hex.


Word Size

The basic unit of size for data values in the Java virtual machine is the word--a fixed size chosen by the designer of each Java virtual machine implementation.

One word size must be large enough to hold a value of type byte (8 bits), short (16 bits), int (32 bits), char (16 bits), float (32 bits) , returnAddress (address of an opcode within the same method), or reference(ref to obj on heap).
Two words must be large enough to hold a value of type long or double (64 bits).

An implementation designer must therefore choose a word size that is at least 32 bits, but otherwise can pick whatever word size will yield the most efficient implementation.
The word size is often chosen to be the size of a native pointer on the host platform.
In practice, pointers will be of 16-bit on a 16-bit system (if you can find one), 32-bit on a 32-bit system, and 64bits on a 64-bit system.


Doesn’t this mean that there are no performance or memory gains when using types small that 64-bit?

In a 64-bit processor, the registers are all 64-bit so if your local variable is assigned to a register and is a boolean, byte, short, char, int, float, double or long it doesn't use memory and doesn't save any resources. Objects are 8-byte aligned so they always take up a multiple of 8-byte in memory. This means Boolean, Byte, Short, Character, Integer, Long , Float and Double, AtomicBoolean, AtomicInteger, AtomicLong, AtomicReference all use the same amount of memory.

Another interesting fact is that some integers are more performant on certain platforms.
For example, in a 32-bit computer (referenced by terms like 32-bit platform and Win32) the CPU is optimized to handle a 32-bit value at a time, and the 32 refers to the number of bits that the CPU can consume or produce in a single cycle. (This is a really simplistic explanation, but it gets the general idea across).

In a 64-bit computer (most recent AMD and Intel processors fall into this category), the CPU is optimized to handle 64-bit values at a time.

So, on a 32-bit platform, a 16-bit integer loaded into a 32-bit address would need to have 16 bits zeroed out so that the CPU could operate on it; a 32-bit integer would be immediately usable without any alteration, and a 64-bit integer would need to be operated on in two or more CPU cycles (once for the low 32-bits, and then again for the high 32-bits).
Conversely, on a 64-bit platform, 16-bit integers would need to have 48 bits zeroed, 32-bit integers would need to have 32 bits zeroed, and 64-bit integers could be operated on immediately.
Each platform and CPU has a 'native' bit-ness (like 32 or 64), and this usually limits some of the other resources that can be accessed by that CPU (for example, the 3GB/4GB memory limitation of 32-bit processors). The 80386 processor family (and later x86) processors made 32-bit the norm, but now companies like AMD and then Intel are currently making 64-bit the norm.

The method area, because it contains bytecodes, is aligned on byte boundaries.

The stack and garbage-collected heap are aligned on word (32-bit) boundaries.


So now when should we even be using short or byte types?

In most cases it wouldn’t be needed unless your use case requires for eg: you are working in image manipulation or reading/writing binary streams, etc.


JVM Architecture


The "virtual hardware" of the Java Virtual Machine can be divided into four basic parts:
the pc registers,
the JVM stack,
the garbage-collected heap,
the method area,
the runtime constant pool and
the native method stack

These parts are abstract, just like the machine they compose, but they must exist in some form in every JVM implementation.

Let's cover the components that are created for each thread first then then rest of the components.

Threads

A thread is a thread of execution in a program.

Why Threads?

They are light wait processes. Moores law states that execution speed increases with transisters increasing but now-a-days we create the overall speed by adding more cores. Adding threads enables the concept of executing/utilizing these cores parallel.

The JVM allows an application to have multiple threads of execution running concurrently.

In the Hotspot JVM there is a direct mapping between a Java Thread and a native operating system Thread. After preparing all of the state for a Java thread such as thread-local storage, allocation buffers, synchronization objects, stacks and the program counter, the native thread is created. The native thread is reclaimed once the Java thread terminates. The operating system is therefore responsible for scheduling all threads and dispatching them to any available CPU. Once the native thread has initialized it invokes the run() method in the Java thread. When the run() method returns, uncaught exceptions are handled, then the native thread confirms if the JVM needs to be terminated as a result of the thread terminating (i.e. is it the last non-deamon thread).

JVM System Threads

If you use jconsole or any debugger it is possible to see there are numerous threads running in the background. These background threads run in addition to the main thread, which is created as part of invoking public static void main(String[]), and any threads created by the main thread.

The main background system threads in the Hotspot JVM are:

> VM thread
This thread waits for operations to appear that require the JVM to reach a safe-point. The reason these operations have to happen on a separate thread is because they all require the JVM to be at a safe point where modifications to the heap can not occur. The type of operations performed by this thread are "stop-the-world" garbage collections, thread stack dumps, thread suspension and biased locking revocation.

> Periodic task thread
This thread is responsible for timer events (i.e. interrupts) that are used to schedule execution of periodic operations

> GC threads
These threads support the different types of garbage collection activities that occur in the JVM

> Compiler threads
These threads compile byte code to native code at runtime

> Signal dispatcher thread
This thread receives signals sent to the JVM process and handle them inside the JVM by calling the appropriate JVM methods.



PC Registers

> Each thread of a running program has its own pc register, or program counter, which is created when the thread is started.
> The pc register is one word in size, so it can hold both a native pointer and a returnAddress.
> As a thread executes a Java method, the pc register contains the address of the current instruction being executed by the thread. An "address" can be a native pointer (to the method area) or an offset from the beginning of a method's bytecodes. If a thread is executing a native method, the value of the pc register is undefined.


JVM stack

> Each Java Virtual Machine thread has a private Java Virtual Machine stack, created at the same time as the thread.
> A Java Virtual Machine stack stores frames.

Frame

> A new frame is created and added (pushed) to the top of stack for every method invocation.
> The frame is removed (popped) when the method returns normally or if an uncaught exception is thrown during the method invocation.

Each frame contains:
1. Local variable array
2. Return value
3. Operand stack
4. Reference to runtime constant pool for class of the current method

1. Local Variables Array

> The array of local variables contains all the variables used during the execution of the method, including a reference to this, all method parameters and other locally defined variables.
> For class methods (i.e. static methods) the method parameters start from zero, however, for instance method the zero slot is reserved for this.

A local variable can be:
• boolean
• byte
• char
• long
• short
• int
• float
• double
• reference
• returnAddress

> Each slot of local variable array is of 32-bits. So to store a character, short or byte variables one slot is used. Means all smaller data-types internally gets converted into int data type.
> Long and double take 2 slots.

2. Return value

This is the return value of the method.

3. Operand stack

Other than the program counter, which can't be directly accessed by instructions, the Java virtual machine has no registers. The Java virtual machine is stack-based rather than register-based because its instructions take their operands from the operand stack rather than from registers
> The Java virtual machine uses the operand stack as a work space.
> Most JVM byte code spends its time manipulating the operand stack by pushing, popping, duplicating, swapping, or executing operations that produce or consume values.

For example, a simple variable initialization results in two byte codes that interact with the operand stack.
int i;
Gets compiled to the following byte code:
0: iconst_0 // Push 0 to top of the operand stack
 1: istore_1 // Pop value from top of operand stack and store as local variable 1


4. References to runtime constant pool

Each frame contains a reference to the runtime constant pool. The reference points to the constant pool for the class of the method being executed for that frame. This reference helps to support dynamic linking.

C/C++ code is typically compiled to an object file then multiple object files are linked together to product a usable artifact such as an executable or dll. During the linking phase symbolic references in each object file are replaced with an actual memory address relative to the final executable.

In Java this linking phase is done dynamically at runtime.

When a Java class is compiled, all references to variables and methods are stored in the class's constant pool as a symbolic reference. A symbolic reference is a logical reference not a reference that actually points to a physical memory location. The JVM implementation can choose when to resolve symbolic references, this can happen when the class file is verified, after being loaded, called eager or static resolution, instead this can happen when the symbolic reference is used for the first time called lazy or late resolution.

However the JVM has to behave as if the resolution occurred when each reference is first used and throw any resolution errors at this point. Binding is the process of the field, method or class identified by the symbolic reference being replaced by a direct reference, this only happens once because the symbolic reference is completely replaced. If the symbolic reference refers to a class that has not yet been resolved then this class will be loaded. Each direct reference is stored as an offset against the storage structure associated with the runtime location of the variable or method.


Native Method Stack

When a thread invokes a native method, it enters a new world in which the structures and security restrictions of the Java virtual machine no longer hamper its freedom. A native method can likely access the runtime data areas of the virtual machine (it depends upon the native method interface), but can also do anything else it wants.


Let's now look a the aspects that are common/independent of Threads


Heap

> The Heap is used to allocate class instances and arrays at runtime.
> Arrays and objects can never be stored on the stack because a frame is not designed to change in size after it has been created. The frame only stores references that point to objects or arrays on the heap.
> Unlike primitive variables and references in the local variable array (in each frame) objects are always stored on the heap so they are not removed when a method ends. Instead objects are only removed by the garbage collector.

To support garbage collection the heap is divided into three sections:
1. Young Generation
Often split between Eden and Survivor
2. Old Generation (also called Tenured Generation)
3. Permanent Generation

JVM and JRE


What is the Java Virtual Machine?

The Java Virtual Machine, or JVM, is an abstract computer that runs compiled Java programs. The JVM is "virtual" because it is generally implemented in software on top of a "real" hardware platform and operating system. All Java programs are compiled for the JVM. Therefore, the JVM must be implemented on a particular platform before compiled Java programs will run on that platform.


How is Java execution different from C/C++?

In short, C is compiled directly to machine code which is then executed directly by the central processing unit.

Normally the C’s program building process involves four stages and utilizes different ‘tools’ such as a preprocessor, compiler, assembler, and linker.

1. Preprocessing is the first pass of any C compilation. It processes include-files, conditional compilation instructions and macros.
2. Compilation is the second pass. It takes the output of the preprocessor, and the source code, and generates assembler source code.
3. Assembly is the third stage of compilation. It takes the assembly source code and produces an assembly listing with offsets. The assembler output is stored in an object file.
4. Linking is the final stage of compilation. It takes one or more object files or libraries as input and combines them to produce a single (usually executable) file. In doing so, it resolves references to external symbols, assigns final addresses to procedures/functions and variables, and revises code and data to reflect new addresses (a process called relocation).



Java is compiled to byte-code which the Java virtual machine (JVM) then interprets at runtime. Actual Java implementations do just-in-time compilation to native machine code. Alternatively, the GNU Compiler for Java can compile directly to machine code.



So now what is the difference between interpreter and JIT compiler?

Answer given below from stackoverflow.

With JVM, both interpreter and compiler (the JVM compiler and not the source-code compiler like javac) produce native code (aka Machine language code for the underlying physical CPU like x86) from byte code.

What's the difference then:
The difference is in how they generate the native code, how optimized it is as well how costly the optimization is. Informally, an interpreter pretty much converts each byte-code instruction to corresponding native instruction by looking up a predefined JVM-instruction to machine instruction mapping (see below pic). Interestingly, a further speedup in execution can be achieved, if we take a section of byte-code and convert it into machine code - because considering a whole logical section often provides rooms for optimization as opposed to converting (interpreting) each line in isolation (to machine instruction). This very act of converting a section of byte-code into (presumably optimized) machine instruction is called compiling (in the current context). When the compilation is done at run-time, the compiler is called JIT compiler.


What makes Java portable?

Portability isn't a black and white, yes or no kind of thing. Portability is how easily one can I take a program and run it on all of the platforms one cares about.
There are a few things that affect this. One is the language itself. The Java language spec generally leaves much less up to "the implementation". For example, "i = i++" is undefined in C and C++, but has a defined meaning in Java. More practically speaking, types like "int" have a specific size in Java (eg: int is always 32-bits), while in C and C++ the size varies depending on platform and compiler. These differences alone don't prevent you from writing portable code in C and C++, but you need to be a lot more diligent.

Another is the libraries. Java has a bunch of standard libraries that C and C++ don't have. For example, threading, networking and GUI libraries. Libraries of these sorts exist for C and C++, but they aren't part of the standard and the corresponding libraries available can vary widely from platform to platform.
Finally, there's the whole question of whether you can just take an executable and drop it on the other platform and have it work there. This generally works with Java, assuming there's a JVM for the target platform. (and there are JVMs for many/most platforms people care about) This is generally not true with C and C++. You're typically going to at least need a recompile, and that's assuming you've already taken care of the previous two points.



Java bytecodes

Java programs are compiled into a form called Java bytecodes. The JVM executes Java bytecodes, so Java bytecodes can be thought of as the machine language of the JVM. The Java compiler reads Java language source (.java) files, translates the source into Java bytecodes, and places the bytecodes into class (.class) files. The compiler generates one class file per class in the source.

To the JVM, a stream of bytecodes is a sequence of instructions. Each instruction consists of a one-byte opcode and zero or more operands. The opcode tells the JVM what action to take. If the JVM requires more information to perform the action than just the opcode, the required information immediately follows the opcode as operands.
A mnemonic is defined for each bytecode instruction. The mnemonics can be thought of as an assembly language for the JVM. For example, there is an instruction that will cause the JVM to push a zero onto the stack. The mnemonic for this instruction is iconst_0, and its bytecode value is 60 hex.


Java Language Specification

Not all major programming languages have specifications, and languages can exist and be popular for decades without a specification. ALGOL 68 was the first (and possibly one of the last) major language for which a full formal definition was made before it was implemented.

When Sun was the steward of Java, they would write specifications for features like Java EE and JPA, giving other vendors the freedom to implement as they wished. Sun would usually have an implementation of their own with which to compete, but their goal was to sell hardware. Encouraging other vendors to provide competing implementations only furthered that aim.

In Java-land these specifications are started as Java Specification Requests (JSRs). Defined here: https://jcp.org/en/jsr/overview. Once accepted, these are specifications.

Sun made most of the JDK source code (not the JVM) freely available under open-source license.


Java Virtual Machine Specification

On November 13, 2006, Sun released much of its Java virtual machine (JVM) as free and open-source software, (FOSS), under the terms of the GNU General Public License (GPL). On May 8, 2007, Sun finished the process, making all of its JVM's core code available under free software/open-source distribution terms, aside from a small portion of code to which Sun did not hold the copyright.

https://docs.oracle.com/javase/specs/

JVM specification dictates how a JVM needs to respond to byte code commands.

Other famous JVM implementation are OpenJDK, IBM J9, GCJ, etc.

The OpenJDK is the open-source implementation of the Java SE 7 JSR (JSR 336). Now there is almost no difference between the Oracle JDK and the OpenJDK. Last year, Oracle took this decision : Moving to OpenJDK as the official Java SE 7 Reference Implementation


Word Size

The basic unit of size for data values in the Java virtual machine is the word--a fixed size chosen by the designer of each Java virtual machine implementation.
One word size must be large enough to hold a value of type byte (8 bits), short (16 bits), int (32 bits), char (16 bits), float (32 bits) , returnAddress (address of an opcode within the same method), or reference(ref to obj on heap).

Two words must be large enough to hold a value of type long or double (64 bits).

On a 64-bit machine one word will be able to hold all types.

An implementation designer must therefore choose a word size that is at least 32 bits, but otherwise can pick whatever word size will yield the most efficient implementation.
The word size is often chosen to be the size of a native pointer on the host platform.
In practice, pointers will be of 16-bit on a 16-bit system (if you can find one), 32-bit on a 32-bit system, and 64bits on a 64-bit system.

Doesn’t this mean that there are no performance or memory gains when using types small that 64-bit?

In a 64-bit processor, the registers are all 64-bit so if your local variable is assigned to a register and is a boolean, byte, short, char, int, float, double or long it doesn't use memory and doesn't save any resources. Objects are 8-byte aligned so they always take up a multiple of 8-byte in memory. This means Boolean, Byte, Short, Character, Integer, Long , Float and Double, AtomicBoolean, AtomicInteger, AtomicLong, AtomicReference all use the same amount of memory.
Another interesting fact is that some integers are more performant on certain platforms.

For example, in a 32-bit computer (referenced by terms like 32-bit platform and Win32) the CPU is optimized to handle a 32-bit value at a time, and the 32 refers to the number of bits that the CPU can consume or produce in a single cycle. (This is a really simplistic explanation, but it gets the general idea across).
In a 64-bit computer (most recent AMD and Intel processors fall into this category), the CPU is optimized to handle 64-bit values at a time.
So, on a 32-bit platform, a 16-bit integer loaded into a 32-bit address would need to have 16 bits zeroed out so that the CPU could operate on it; a 32-bit integer would be immediately usable without any alteration, and a 64-bit integer would need to be operated on in two or more CPU cycles (once for the low 32-bits, and then again for the high 32-bits).

Conversely, on a 64-bit platform, 16-bit integers would need to have 48 bits zeroed, 32-bit integers would need to have 32 bits zeroed, and 64-bit integers could be operated on immediately.
Each platform and CPU has a 'native' bit-ness (like 32 or 64), and this usually limits some of the other resources that can be accessed by that CPU (for example, the 3GB/4GB memory limitation of 32-bit processors). The 80386 processor family (and later x86) processors made 32-bit the norm, but now companies like AMD and then Intel are currently making 64-bit the norm.

So now when should we even be using short or byte types?

In most cases it wouldn’t be needed unless your use case requires for eg: you are working in image manipulation or reading/writing binary streams, etc.
The method area, because it contains bytecodes, is aligned on byte boundaries. The stack and garbage-collected heap are aligned on word (32-bit) boundaries.



JVM Architecture

The "virtual hardware" of the Java Virtual Machine can be divided into 6 basic parts:
The pc registers,
the Java stack,
the garbage-collected heap,
the method area,
the runtime constant pool
and the native method stack

These parts are abstract, just like the machine they compose, but they must exist in some form in every JVM implementation.


PC Registers

Each thread of a running program has its own pc register, or program counter, which is created when the thread is started.
The pc register is one word in size, so it can hold both a native pointer and a returnAddress.

As a thread executes a Java method, the pc register contains the address of the current instruction being executed by the thread. An "address" can be a native pointer (to the method area) or an offset from the beginning of a method's bytecodes. If a thread is executing a native method, the value of the pc register is undefined.


Java stack

Each Java Virtual Machine thread has a private Java Virtual Machine stack, created at the same time as the thread.
A Java Virtual Machine stack stores frames.

Frame

A frame is used to store data and partial results, as well as to perform dynamic linking, return values for methods, and dispatch exceptions.
A new frame is created each time a method is invoked. A frame is destroyed when its method invocation completes, whether that completion is normal or abrupt (it throws an uncaught exception).
Each frame contains:
• Local variable array
• Operand stack
• Frame data

Local Variables Array

The array of local variables contains all the variables used during the execution of the method, including a reference to this, all method parameters and other locally defined variables. For class methods (i.e. static methods) the method parameters start from zero, however, for instance method the zero slot is reserved for this.
A local variable can be:
• boolean
• byte
• char
• long
• short
• int
• float
• double
• reference
• returnAddress

Each slot of local variable array is of 32-bits. So to store a character, short or byte variables one slot is used. Means all smaller data-types internally gets converted into int data type.
Long and double take 2 slots.

Operand Stack

Like the local variables, the operand stack is organized as an array of words. But unlike the local variables, which are accessed via array indices, the operand stack is accessed by pushing and popping values.
The virtual machine stores the same data types in the operand stack that it stores in the local variables, Other than the program counter, which can't be directly accessed by instructions, the Java virtual machine has no registers. The Java virtual machine is stack-based rather than register-based because its instructions take their operands from the operand stack rather than from registers.
The Java virtual machine uses the operand stack as a work space. Many instructions pop values from the operand stack, operate on them, and push the result. For example, the iadd instruction adds two integers by popping two ints off the top of the operand stack, adding them, and pushing the int result.

Here is how a Java virtual machine would add two local variables that contain ints and store the intresult in a third local variable:
iload_0 // push the int in local variable 0
iload_1 // push the int in local variable 1
iadd // pop two ints, add them, push result
istore_2 // pop int, store into local variable


Frame Data

This is to support constant pool resolution, normal method return, and exception dispatch.

Many instructions in the Java virtual machine's instruction set refer to entries in the constant pool. Some instructions merely push constant values of type int, long, float, double, or String from the constant pool onto the operand stack. Some instructions use constant pool entries to refer to classes or arrays to instantiate, fields to access, or methods to invoke. Other instructions determine whether a particular object is a descendant of a particular class or interface specified by a constant pool entry.

Aside from constant pool resolution, the frame data must assist the virtual machine in processing a normal or abrupt method completion. If a method completes normally (by returning), the virtual machine must restore the stack frame of the invoking method. It must set the pc register to point to the instruction in the invoking method that follows the instruction that invoked the completing method. If the completing method returns a value, the virtual machine must push that value onto the operand stack of the invoking method.

The frame data must also contain some kind of reference to the method's exception table, which the virtual machine uses to process any exceptions thrown during the course of execution of the method.
An exception table defines ranges within the bytecodes of a method that are protected by catch clauses. Each entry in an exception table gives a starting and ending position of the range protected by a catch clause, an index into the constant pool that gives the exception class being caught, and a starting position of the catch clause's code.

Native Method Stacks
In addition to all the runtime data areas defined by the Java virtual machine specification and described previously, a running Java application may use other data areas created by or for native methods. When a thread invokes a native method, it enters a new world in which the structures and security restrictions of the Java virtual machine no longer hamper its freedom. A native method can likely access the runtime data areas of the virtual machine (it depends upon the native method interface), but can also do anything else it wants. It may use registers inside the native processor, allocate memory on any number of native heaps, or use any kind of stack.


The Heap

Whenever a class instance or array is created in a running Java application, the memory for the new object is allocated from a single heap. As there is only one heap inside a Java virtual machine instance, all threads share it. Because a Java application runs inside its "own" exclusive Java virtual machine instance, there is a separate heap for every individual running application. There is no way two different Java applications could trample on each other's heap data. 

Garbage Collection

A garbage collector's primary function is to automatically reclaim the memory used by objects that are no longer referenced by the running application. It may also move objects as the application runs to reduce heap fragmentation.

A garbage collector is not strictly required by the Java virtual machine specification. The specification only requires that an implementation manage its own heap in some manner. For example, an implementation could simply have a fixed amount of heap space available and throw an OutOfMemory exception when that space fills up. While this implementation may not win many prizes, it does qualify as a Java virtual machine. 


Object Representation

The Java virtual machine specification is silent on how objects should be represented on the heap.