Good news: HTML5 has arrived (thank you in part to Apple). We are no longer limited to using applet, object, svg or img tags to present dynamic visual content. We can use the canvas element in addition to the geolocation and storage functionality.
As a first example, i have of course written a very rudimentary version of John Horton Conways' "Game of Life". The William Gosper "glider gun" is an excellent proof of concept.
The following link will take you to a pure HTML5 document that renders the glider gun sequence. You will need the latest Android 2.x, Chrome, IE9, Firefox or Opera browser to see the canvas element.
Cellular Automata simulation in HTML5 using the canvas element
http://99.240.95.213:7101/radar/html5.xhtml (IE9, Chrome and (android based Firefox))
http://99.240.95.213:7101/radar/html5.html (android 2.x base browser)
http://99.240.95.213:7101/collatz/faces/index.xhtml
http://99.240.95.213:7101/collatz/ajaxclient.jsp
Cellular Automata simulation in a Java SE Applet
http://www.objectivej.com/inorganiclife/experiments/life/LifeAnimApplet.html
Cellular Automata simulation in a Wikipedia animated GIF
http://en.wikipedia.org/wiki/Conway%27s_Game_of_Life
Distributed Java
Java based concurrent software and strategies for Grid, Cloud and Clustered environments
Sunday, October 30, 2011
HTML5 Canvas element has arrived
Sunday, May 8, 2011
Thread Safety
The following Java API is known to be not thread safe.
SimpleDateFormat is not thread safe
The SimpleDateFormat implementation of DateFormat is not thread safe by design. If you wish to use this API you have several architectures to choose from in your application.
Use sychronization in your implementation - not advisable since this will queue your requests
Use InheritedThreadLocal storage by using get/set to use an instance of SimpleDateFormat per thread - recommended for environments running in thread pools - like in EE application servers.
Here we use an InheritedThreadLocal map entry to store an instance of the DateFormat object for each thread. See p.45 section 3.3 Thread confinement of "Java Concurrency in Practice" by Brian Goetz. Also, do not set this field before starting this thread or the ThreadLocal map value will be cleared to initialValue()
Use a pool of SimpleDateFormat instances - not in this case.
I will use the ThreadLocal map to store a unique instance for each thread of my running application. However, any ThreadLocal will not do - as I may be running in a pooled environment - like in an application server container like WebLogic, Tomcat, OC4J, WebSphere, JBoss, Spring tc, Spring dm, Geronimo and even JRun. In this case we need to use the subclass InheritableThreadLocal. When child threads are created, these threads will get a reference to their parent thread's ThreadLocal value by default. We will also want to override the InheritableThreadLocal.childValue() function to clone the parent value so that we are fully threads safe. Doing so will ensure thread safety whether ThreadLocal variables are set before or after thread creation.
SAXParser in JDOM SAXBuilder is not thread safe
The parser in SAXBuilder must be set to not be reused in your constructor.
See the following API
http://www.jdom.org/docs/apidocs/org/jdom/input/SAXBuilder.html#setReuseParser(boolean)
SimpleDateFormat is not thread safe
The SimpleDateFormat implementation of DateFormat is not thread safe by design. If you wish to use this API you have several architectures to choose from in your application.
Use sychronization in your implementation - not advisable since this will queue your requests
Use InheritedThreadLocal storage by using get/set to use an instance of SimpleDateFormat per thread - recommended for environments running in thread pools - like in EE application servers.
Here we use an InheritedThreadLocal map entry to store an instance of the DateFormat object for each thread. See p.45 section 3.3 Thread confinement of "Java Concurrency in Practice" by Brian Goetz. Also, do not set this field before starting this thread or the ThreadLocal map value will be cleared to initialValue()
Use a pool of SimpleDateFormat instances - not in this case.
I will use the ThreadLocal map to store a unique instance for each thread of my running application. However, any ThreadLocal will not do - as I may be running in a pooled environment - like in an application server container like WebLogic, Tomcat, OC4J, WebSphere, JBoss, Spring tc, Spring dm, Geronimo and even JRun. In this case we need to use the subclass InheritableThreadLocal. When child threads are created, these threads will get a reference to their parent thread's ThreadLocal value by default. We will also want to override the InheritableThreadLocal.childValue() function to clone the parent value so that we are fully threads safe. Doing so will ensure thread safety whether ThreadLocal variables are set before or after thread creation.
private static final InheritableThreadLocalformat = new InheritableThreadLocal () { @Override public DateFormat initialValue() { // This default value will get replaced by non-default constructors return new SimpleDateFormat(DefaultFormat); } @Override // All child threads must clone the formatter and not share the parent formatter by default protected DateFormat childValue(DateFormat parentValue) { // Object.clone() is a shallow copy, however DateFormat.clone() replicates mutable fields return (DateFormat) parentValue.clone(); } };
SAXParser in JDOM SAXBuilder is not thread safe
The parser in SAXBuilder must be set to not be reused in your constructor.
See the following API
http://www.jdom.org/docs/apidocs/org/jdom/input/SAXBuilder.html#setReuseParser(boolean)
aBuilder = new SAXBuilder(); aBuilder.setReuseParser(false);
Monday, January 10, 2011
Multiple Instruction Multiple Data
We need to start thinking about how existing and future Java API's will work with all the combinations of multiple data sets, multiple virtual machines, multiple physical hardware devices and multiple clients. The issues surround how we handle concurrent access, availability, synchronization, distribution and sharing of all these resources.
I1: Data sharing:
I1: Data sharing:
- shared database (old)
- shared schema (new)
Labels:
caching,
concurrency,
mimd,
multitenancy,
SIMD,
software as a service
Friday, November 5, 2010
TODO
- investigate the excellent article from Microsoft Research on multinenancy as part of most SaaS http://msdn.microsoft.com/en-us/library/aa479086.aspx implementations
- Add applications to live application server
http://99.240.95.213/radar/html5.xhtml - MapReduce (via Apache Hadoop) on one of my clusters or one of my Amazon EC2 AWS instances using Amazon Elastic MapReduce as a wrapper for Hadoop or on the upcoming Oracle cloud service - see http://www.youtube.com/watch?v=Wu9HMM9l3Go
- Project Fortress from the programming languages lab of very honoured new coworker Guy Steele !
- Full review of historical architectures MIT Cosmic Cube (MIMD), CM-2 (SIMD) and Illiac IV (SIMD) and how they influence the KiloCore prototype
- JVM Bytecode spec section and Proxy.getNewInstance()
- Finish review of BeMicro's board for the 22k Altera FPGA
- JRebel for ZeroTurnaround
- Three phase commit protocol for databases
- Spring Roo, Insight and AOP
- Java needs an automatic for loop parallelization API like other languages like .NET
- .NET JMS client for WebLogic http://download.oracle.com/docs/cd/E12840_01/wls/docs103/jms_dotnet/overview.html
http://jre.sfbay.sun.com/java/re/jdk/6u24/promoted/fcs/b07/licenseebundles/jdk6_24/
Inform Ed Ort of Oracle that the JAX RS example on the main Java EE site does not compile (it was written back in Dec 2009 when the spec first came out)
http://www.oracle.com/technetwork/articles/javaee/javaee6overview-141808.html#jaxrs
For example, the following imports are invalid and have syntax errors
import javax.ws.rs.Get; import javax.ws.rs.Post; import javax.ws.rs.core UriInfo;These should be
import javax.ws.rs.GET; import javax.ws.rs.POST; import javax.ws.rs.core.UriInfo;In order to match their use as annotations later on.
I try to copy only directly from my Eclipse or NetBeans IDE - and not edit code directly on a blog - so this does not happen.
Hardware:
- 256 bit ALU using PB8X-32
- Vector ALU pipeline
- 128 bit universal bidirectional shift register
- Toroidal grid parallel processor (Propeller PA8X-32 or XMOS G4
- Ambric like mesh processor where each PU executes a single Java Object thread (so a kilocore represents 1024 pooled object instances)
- Data flow machine where each processing unit node represents a scalar operation or data element in a RPN or Forth like flow
Tuesday, November 2, 2010
Accessing multiple remote EJB 3.0 Session Beans via JNDI in an SE Client - Experiment
Update: This project is superceeded by the Collatz Distributed Java EE Application Tutorial
Note: This code will run on both a Java SE client or an EE container like Oracle WebLogic.
Here as a preparation for using or understanding how a distributed java application runs under a shared level 2 cache before we actually use one. We can develop our own naive cache by referencing ''session beans'' on one or more WebLogic server applications acting as a distributed application and possibly using our own HashMap - old school and unnecessary but part of essential learning.
WebLogic RMI Client Configuration
The following stateful session bean goes into an EAR and is deployed on each EE container in your cluster.
The key point is to rename your session bean and reference it by name#application.
Java EE Stateless Session Bean
GlassFish 3.1 and Remote EJB clients
GlassFish 3.1 no longer ships with the non-OSGI gf-client.jar, however the actual OSGI gf-client-module.jar that the manifest in gf-client wraps is still in the modules directory.
see:
http://java.net/jira/browse/GLASSFISH-13295
GlassFish 3.0.1 Results:
You don't need to specify the HashTable parameter for the InitialContext connection for GlassFish.
run:
Context for xps435 : javax.naming.InitialContext@c8f6f8
Feb 6, 2011 6:53:18 PM com.sun.enterprise.transaction.JavaEETransactionManagerSimplified initDelegates
INFO: Using com.sun.enterprise.transaction.jts.JavaEETransactionManagerJTSDelegate as the delegate
Remote Object: org.dataparallel.collatz.business._CollatzFacadeRemote_Wrapper@498cb673
Narrowed Session Bean: org.dataparallel.collatz.business._CollatzFacadeRemote_Wrapper@498cb673
Note: This code will run on both a Java SE client or an EE container like Oracle WebLogic.
Here as a preparation for using or understanding how a distributed java application runs under a shared level 2 cache before we actually use one. We can develop our own naive cache by referencing ''session beans'' on one or more WebLogic server applications acting as a distributed application and possibly using our own HashMap - old school and unnecessary but part of essential learning.
WebLogic RMI Client Configuration
Here we have a very simple JNDI client that acts as a hello world distributed host and manages remote session beans on two physical WebLogic servers.
The JNDI protocol uses t3
The JNDI factory class for WebLogic is weblogic.jndi.WLInitialContextFactory
The default JNDI name for you SSB can be redifined via the mappedName annotation to ejb/Node with the corresponding remoteReference as java:comp/env/ejb/Node
The key to using an EJB 3.0 session bean remotely is to narrow the Object to the bean interface.The following stateful session bean goes into an EAR and is deployed on each EE container in your cluster.
@Stateful(mappedName="ejb/Node") @Local public class Node implements NodeRemote, NodeLocal { private int transition; private int state; public void setState(int aState) { System.out.println("_Distributed: new state: " + aState); state = aState; } public int getState() { return state; } }This goes on your SE client.
public class JNDIClient { public static final List<String serverNames = new ArrayList<String>(); private Map<String, Hashtable<String, String>> contextMap = new HashMap<String, Hashtable<String, String>>(); private Map<String, Context> rmiContextMap = new HashMap<String, Context>(); private Map<String, NodeRemote> remoteObjects = new HashMap<String, NodeRemote>(); private Map<String, Integer> stateToSet = new HashMap<String, Integer>(); private static Map<String, String> serverIPMap = new HashMap<String, String>(); // How many processors are available (real + hyperthreaded) private static int availableProcessors; private static final String CONTEXT_FACTORY_NAME = "weblogic.jndi.WLInitialContextFactory"; private static final String SESSION_BEAN_REMOTE_NAME = "ejb/Node#org.eclipse.persistence.example.distributed.NodeRemote"; //private String sessionBeanRemoteName = "java:comp/env/ejb/Node"; // EE only //private String sessionBeanRemoteName = "org_eclipse_persistence_example_distributed_ClientEARorg_eclipse_persistence_example_distributed_ClientEJB_jarNode_Home" ; /** * For each server add the name key and corresponding RMI URL */ static { // Beowulf5 on Cat6 1Gb/Sec serverNames.add("beowulf5"); serverIPMap.put("beowulf5", "t3://192.168.0.165:7001"); // Beowulf6 on Cat6 1Gb/Sec serverNames.add("beowulf6"); serverIPMap.put("beowulf6", "t3://192.168.0.166:7001"); availableProcessors = Runtime.getRuntime().availableProcessors(); } public void connect() { /** * Note: only import weblogic.jar and naming.jar */ // For JNDI we are forced to use Hashtable instead of HashMap // populate the hashtables for(String aServer : serverNames) { Hashtable aTable = new Hashtable(); contextMap.put(aServer,aTable); aTable.put(Context.INITIAL_CONTEXT_FACTORY,CONTEXT_FACTORY_NAME); aTable.put(Context.PROVIDER_URL, serverIPMap.get(aServer)); } System.out.println("Available Processors on this System: " + availableProcessors); /** * Setup and connect to RMI Objects */ try { // Establish RMI connections to the session beans for(String aServer : serverNames) { Context aContext = new InitialContext(contextMap.get(aServer)); rmiContextMap.put(aServer, aContext); System.out.println("Context for " + aServer + " : " + aContext); // For qualified name look for weblogic log "EJB Deployed EJB with JNDI name" Object aRemoteReference = aContext.lookup(SESSION_BEAN_REMOTE_NAME); System.out.println("Remote Object: " + aRemoteReference); NodeRemote aNode = (NodeRemote) PortableRemoteObject.narrow(aRemoteReference, NodeRemote.class); remoteObjects.put(aServer, aNode); System.out.println("Narrowed Session Bean: " + aNode); // initialize state list stateToSet.put(aServer, new Integer(0)); } NodeRemote aNode; StringBuffer aBuffer = new StringBuffer(); // Endlessly generate RMI requests for(;;) { // Send messages to entire grid in parallel /** * Issue: One JVM halt will affect the entire distributed app. */ for(String remoteServer : remoteObjects.keySet()) { aNode = remoteObjects.get(remoteServer); // increment server's pending state stateToSet.put(remoteServer, stateToSet.get(remoteServer).intValue() + 1); try { aNode.setState(stateToSet.get(remoteServer)); aBuffer = new StringBuffer("State from: "); aBuffer.append(remoteServer); aBuffer.append(" = "); aBuffer.append(aNode.getState()); System.out.println(aBuffer.toString()); } catch (EJBException e) { // weblogic.transaction.internal.TimedOutException: Transaction timed out after 29 seconds e.printStackTrace(); } } } } catch (Exception e) { e.printStackTrace(); } } public static void main(String[] args) { JNDIClient client = new JNDIClient(); client.connect(); } }
The key point is to rename your session bean and reference it by name#application.
Java EE Stateless Session Bean
@Stateless(mappedName = "ejb/CollatzFacade") public class CollatzFacade implements CollatzFacadeRemote, CollatzFacadeLocal {Java SE Client
private static final String SESSION_BEAN_REMOTE_NAME = "ejb/CollatzFacade#org.eclipse.persistence.example.distributed.collatz.business.CollatzFacadeRemote";
GlassFish 3.1 and Remote EJB clients
GlassFish 3.1 no longer ships with the non-OSGI gf-client.jar, however the actual OSGI gf-client-module.jar that the manifest in gf-client wraps is still in the modules directory.
see:
http://java.net/jira/browse/GLASSFISH-13295
GlassFish 3.0.1 Results:
You don't need to specify the HashTable parameter for the InitialContext connection for GlassFish.
run:
Context for xps435 : javax.naming.InitialContext@c8f6f8
Feb 6, 2011 6:53:18 PM com.sun.enterprise.transaction.JavaEETransactionManagerSimplified initDelegates
INFO: Using com.sun.enterprise.transaction.jts.JavaEETransactionManagerJTSDelegate as the delegate
Remote Object: org.dataparallel.collatz.business._CollatzFacadeRemote_Wrapper@498cb673
Narrowed Session Bean: org.dataparallel.collatz.business._CollatzFacadeRemote_Wrapper@498cb673
Subscribe to:
Posts (Atom)