Tuesday, April 30, 2013

Reading Groovy objects from Java

Loading a Groovy object in Java is not as easy at it seems, but doesn't have to be hard.

The problem with Groovy dynamic classes is that the default class loader is not aware of them. Using the GroovyClassLoader should be as simple as:
GroovyClassLoader gcl = new GroovyClassLoader(); 
Thread.currentThread().setContextClassLoader(gcl); 

Doesn't do the trick and a call to the ObjectInputStream will raise the devil's ClassNotFoundException.

After many attempts refining my Google search from "reading Groovy objects" down to "ObjectInputStream ClassLoader" I finally found this link and was able to solve the problem.
The trick was overriding the resolveClass method from the ObjectInputStream, which apparently always uses the default class loader.

Full code example below.

TestObjectInputStream.java:
public class TestObjectInputStream extends ObjectInputStream { 

    @Override 
    public Class resolveClass(ObjectStreamClass desc) throws IOException,
            ClassNotFoundException { 

        ClassLoader currentTccl = null
        try { 
            currentTccl = Thread.currentThread().getContextClassLoader();
            return currentTccl.loadClass(desc.getName()); 

        } catch (Exception e) { 
        } 

        return super.resolveClass(desc); 
    } 

    public TestObjectInputStream(InputStream in) throws IOException { 
        super(in); 
    } 

}

TestSave.java:
public class TestSave { 
   public static void main(String[] args) throws CompilationFailedException, 
            IOException, InstantiationException, IllegalAccessException, 
            ClassNotFoundException, IllegalArgumentException, 
            SecurityException, InvocationTargetException, NoSuchMethodException { 
        GroovyClassLoader gcl = new GroovyClassLoader(); 
        Thread.currentThread().setContextClassLoader(gcl); 
                                                             
        String fileName = "scripts/SimpleData.groovy"
     
        Class clazz = gcl.parseClass(new File(fileName)); 

         
        Object instance = clazz.newInstance(); 

        System.out.println("WRITING OBJECT FROM CLASS: " + instance.getClass());

        // write 
        File outFile = new File("file.bin"); 
        FileOutputStream fos = new FileOutputStream(outFile); 
        ObjectOutputStream oos = new ObjectOutputStream(fos); 
        oos.writeObject(instance); 

        // read 
        File inFile = new File("file.bin"); 
        FileInputStream fis = new FileInputStream(inFile); 
        TestObjectInputStream ois = new TestObjectInputStream(fis); 

        Object obj = ois.readObject(); 

        System.out.println("Class: " + obj.getClass()); 

        System.out.println("Object: " + obj.toString()); 
        System.out.println("Object: " + obj.toString()); 
        System.out.println("Object: " + obj.toString()); 

        Serializable seriobj = (Serializable) obj; 

        System.out.println("Serializable Object: " + seriobj); 
    } 
SimpleData.groovy:
class SimpleData implements Serializable { 
    public int value = 1; 

    public SimpleData(){ 
    } 

    public String toString(){ 
        return "Value: " + (value ++); 
    } 

And the console's output:
WRITING OBJECT FROM CLASS: class SimpleData
Class: class SimpleData
Object: Value: 1
Object: Value: 2
Object: Value: 3
Serializable Object: Value: 4




Thursday, April 18, 2013

Reality will change

A VR road-map

early 2013 - early adopters
Oculus Rift developer version comes out, lot's of flaws but it's a clear improvement on what was previously available.
Some issues are: Lack of positional tracking, Low screen resolution


2013 - the hacker scene
Hackers will do everything you can imagine.

*Oculus Rift streaming Two cameras on the other side of the world? Will be done this year
Imagine looking around and seeing 3d.. on the other side of the globe!

*Oculus Rift with mounted MS Kinect? This year
This will be the first real shot at augmented reality. 
Yes... It will be an interface to much (you'll have cameras in front of your face that will send data to your computer that will forward it to each eye....)

But with the depth perception from Kinect, you'll be able to do just about anything with reality.

late 2013 - Project Glass
In it's current model, I suspect that if Glass sells is because either they can sell it as a status symbol or it's so cheap it's worth to buy it just to have an handsfree camera. 
Don't take me wrong, I love the idea, but after having watched parts of the developer conference I believe it's not there yet... Imagine Android 1.0.

2014 - a new market is born
Oculus Rift consumer version, low screen resolution has been mostly fixed. Positional head-tracking can be done with 3rd party hardware. Some games already offer support (think Razor Hydra, Kinect, ...)
Lots of new startups showing up around OR. 
- Some will target real-life simulations, think surgeries, think fobias, war, telepresence..
- Some will target entertainment in all fronts. Games will be the first, but titles such as "Virtual Vacations" will show-up. Adult entertainment also.

late 2014 - big players arrive
Samsung and Sony both release their new VR headsets (MS will follow in early 2015).

Project glass will grow in users but will remain pretty much the same. Think Android 2.0


early 2015 - tech teasers

Samsung makes some demos at CES showing for the first time VR headsets with incorporated Kinect like functionality and transparent screens/lens. These are bulky but they've removed the need for projecting reality onto the headset.


2016 - maturity
Nothing relevant will happen. Lot's of hype on new products but basically technology will mature. Singularity sceptics will forget the last 3 years.

2017 - Augmented VR
Samsung, Google or other, including Palmer Luckey - millionaire, releases the first wearable augmented reality kit. 
This will be the first "normal" glasses that will include 3d mapping of the real-world and lenses that will work as a reality overlay.
2018 - The merge
Real and Virtual reality will merge. There will be new words to distinguish between "Real-Reality" and the "Other realities"

Virtual worlds such as second life will stop being considered "virtual". People will say things like "Last night I was in Saturn-53, we should meet there I'll give you the link."


2019
You tell me :-)






Tuesday, April 9, 2013

nio-threaded-tools

Introduction

I was trying to find a non-blocking multi-threaded socket server in Java and could not find anything awesome. The best I could find was this hack on stackoverflow (http://stackoverflow.com/questions/5862971/java-readobject-with-nio).
I took the hack and basically used it as inspiration for this tools. Enjoy.

Quick start

This will allow you to seamlessly use non-blocking NIO sockets in a thread pool.

Server

Starting the server: SeriServer server = new SeriServer(6001); // port 6001, uses the default 10 threads
Starting the server in single thread: SeriServer server = new SeriServer(6001,1);// 1 thread
Reading data from the server: SeriDataPackage objectFromClient = server.read()
Accessing data read from server: System.out.println(objectFromClient.getObject().toString());
Sending data back to the client: server.reply(objectFromClient, message); // message must be serializable

Client

Starting a client: client = new SeriClient("localhost", 6001);
Sending data to server: client.send(message); // message must be serializable
Reading message from server: SeriDataPackage objectFromServer = client.read();
Accessing data read from server: System.out.println(objectFromServer.getObject().toString());

Server processing

You can also do automatic processing from the server threads, via the SeriSeriver.setProcessor:
final SeriServer server = new SeriServer(5003, 3);
server.setProcessor(new SeriProcessor() {
        public void process(SeriDataPackage pack) {
                try {                                   
                        server.reply(pack, "*" + pack.getObject().toString() + "*");
                } catch (IOException e) {
                }                               
                }
        });
                                
SeriClient client = new SeriClient("localhost", 5003);
client.send("TEST");
SeriDataPackage response = client.read();
System.out.println(response.getObject());
This will output: *TEST*