Desktop sharing using ssh tunnel

Share desktop of A to B with C as the hop. You’ll need access to your own server (C).

Execute on A: (assuming 192.168.1.100 is the ip of machine A)

% ssh -R 3390:192.168.1.100:3389 -l username myserver.com
log in and execute
ping 8.8.8.8 -i 5
to prevent the connection from timing out

Execute on B

% ssh -l username myserver.com -L 3391:localhost:3390

This means that you will be able to connect at localhost:3391 from your home computer and everything will be forwarded to myserver.com:3390.

Point your remote desktop connection to localhost:3391

cropped-DSC_0066-1024x477

Hibernate 4 Integrator pattern and Spring’s DI

Enabling @Autowired in Hibernate entities.

Create an EventListener that kicks in after a Hibernate LOAD event.  Using AutowireCapableBeanFactory to wire @Autowire’d dependencies.

package be.esus.core.infrastructure.hibernate;

import be.core.architecture.common.locator.SpringLocator;
import org.hibernate.event.spi.PostLoadEvent;
import org.hibernate.event.spi.PostLoadEventListener;
import org.springframework.beans.factory.config.AutowireCapableBeanFactory;

// https://jira.spring.io/browse/SPR-9187
public class MyPostLoadEventListener implements PostLoadEventListener {
   @Override
   public void onPostLoad(PostLoadEvent postLoadEvent) {
      Object entity = postLoadEvent.getEntity();

      AutowireCapableBeanFactory spring = SpringLocator.getApplicationContext().getAutowireCapableBeanFactory();
      spring.autowireBean(entity);
   }
}

(SpringLocator is a simple custom class that is ApplicationContextAware in order to have static access to the ApplicationContext)

Register your new listener in Hibernate’s EventListenerRegistry.

package be.esus.core.infrastructure.hibernate;

import org.hibernate.cfg.Configuration;
import org.hibernate.engine.spi.SessionFactoryImplementor;
import org.hibernate.event.service.spi.EventListenerRegistry;
import org.hibernate.event.spi.EventType;
import org.hibernate.integrator.spi.Integrator;
import org.hibernate.metamodel.source.MetadataImplementor;
import org.hibernate.service.spi.SessionFactoryServiceRegistry;
import org.springframework.stereotype.Component;

@Component
public class MyEventListenerIntegrator implements Integrator {

   @Override
   public void integrate(Configuration configuration, SessionFactoryImplementor sessionFactory,
                         SessionFactoryServiceRegistry serviceRegistry) {
      EventListenerRegistry eventListenerRegistry = serviceRegistry.getService( EventListenerRegistry.class );

      eventListenerRegistry.appendListeners(EventType.POST_LOAD, new MyPostLoadEventListener());
   }

   @Override
   public void integrate(MetadataImplementor metadataImplementor,
                         SessionFactoryImplementor sessionFactoryImplementor,
                         SessionFactoryServiceRegistry sessionFactoryServiceRegistry) {

   }

   @Override
   public void disintegrate(SessionFactoryImplementor sessionFactoryImplementor,
                            SessionFactoryServiceRegistry sessionFactoryServiceRegistry) {

   }
}

To register your SPI (see service loader), create
a (text) file called org.hibernate.integrator.spi.Integrator in META-INF/services/ and put the FQCN of your integrator in it:

be.esus.core.infrastructure.hibernate.MyEventListenerIntegrator

Converting an InputStream to a String

Main.java:

import java.io.*;
 
public class Main
{
   public static void main(String []args) throws IOException {
      if (args.length != 1) {
         System.out.println("Usage: java Main <file>");
         System.exit(1);
      }
      
      BufferedInputStream bis = new BufferedInputStream(new FileInputStream(args[0]));
      ByteArrayOutputStream baos = new ByteArrayOutputStream();
      
      long start = System.currentTimeMillis();
      int b;
      
      byte[] buf = new byte[2048];
      while ((b = bis.read(buf)) != -1) {
         baos.write(buf);
      }
      System.out.println("Time to read in file: " + (System.currentTimeMillis() - start));
      
      byte[] buffer = baos.toByteArray();
      
      String result = new String(buffer);  // or "new String(buffer, encoding)"

      System.out.println(result);
   }
}

Using covariant return types in JDK 1.5

An argument or return type in an overridden method that is made more specialized is called to be covariant. Allowing covariant return types in Java has been in Sun’s bugparade for a long time (http://bugs.sun.com/bugdatabase/view_bug.do? bug_id=4144488. Now finally, JDK 1.5 supports it.

The protected clone() method of the Object class can be overridden, made public and support shallow or deep cloning of objects. Prior to 1.5.0, the return type of clone() had to be Object and a cast was necessary:

   Dolly d2 = (Dolly) d1.clone();

Specifying any other return type than Object caused the following exception:

clone() in Dolly cannot override clone() in java.lang.Object; attempting to use incompatible return type

Now 1.5 supports overridden methods to have a different return type as long as they are a specialization of the method in the superclass.

Main.java:

public class Main
{
   public static void main(String []args) {
      Dolly d1 = new Dolly();
      Dolly d2 = null;
       
      try {
         d2 = d1.clone();
      }
      catch(CloneNotSupportedException e) {
      }
       
      System.out.println(d1);
      System.out.println(d2);
   }
}

class Dolly implements Cloneable
{
   long fur = 123456;
    
   public Dolly clone() throws CloneNotSupportedException {
      try {
         return (Dolly) super.clone();
      }
      catch(CloneNotSupportedException e) {
         throw e;
      }
   }
    
   public String toString() {
      return ""+fur;
   }
}

Storing properties into an XML file in JDK 1.5

StoreProps.java:

import java.util.*;
import java.io.*;
 
public class StoreProps
{
   public static void main(String []args) {
      Properties props = new Properties();
       
      props.put("path", "c:\program files\app");
      props.put("socketlock", "4550");
       
      System.out.println(props);
       
      try {
         // the second parameter is a single comment you can provide
         props.storeToXML(new FileOutputStream(new File("config.xml")), "Configuration for application");
      }
      catch(IOException e) { 
         e.printStackTrace();
      }
   }
}

Generates the file config.xml:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE properties SYSTEM "http://java.sun.com/dtd/properties.dtd">
<properties>
<comment>Configuration for application</comment>
<entry key="socketlock">4550</entry>
<entry key="path">c:program filesapp</entry>
</properties>

Comparing StringBuiler with StringBuffer

StringBuilder is a replacement for the thread-safe StringBuffer class. It works much faster as it has no synchronized methods. So, if you are doing lots of String operations in a single thread, you will gain a lot of performance when using this class.

Here’s a comparison.

Main.java:

public class Main
{
   public static void main(String []args) {
      stringBufferTest();
      stringBuilderTest();
   }
    
   public static void stringBufferTest() {
      long startTime = System.nanoTime();
      StringBuffer sb = new StringBuffer();
      for (int i=0; i<100000; i++) {
         sb.append((char) 'a');
      }
      System.out.println("StringBuffer test: " + (System.nanoTime() - startTime));
   }
    
   public static void stringBuilderTest() {
      long startTime = System.nanoTime();
      StringBuilder sb = new StringBuilder();
      for (int i=0; i<100000; i++) {
         sb.append((char) 'a');
      }
      System.out.println("StringBuilder test: " + (System.nanoTime() - startTime));
   }
}

outputs:

StringBuffer test: 12849957
StringBuilder test: 8935494

Using the tool jconsole in JDK1.5

The JMX compliant tool jconsole comes with JDK1.5. It allows to manage the VM, check the memory usage of the different memory managers, monitor the thread usage, see how many classes are loaded, etc.

The simplest way to use jconsole is to start up the Java application a JMX agent:

   java -Dcom.sun.management.jmxremote Main

Then, specify the process ID of the Java application when starting up jconsole:

   c:j2sdk1.5.0binjconsole <pid>

To find out the process ID, you can use the ps command on UNIX and the Task Manager on Windows.

There is a workaround to quickly find out the process ID. This following Java application prints out its own process ID and then infinitely starts creating threads that on their turn fill up the memory by creating a number of arrays.

Main.java:

import java.util.*;
import java.lang.reflect.*;
import java.lang.management.*;
 
public class Main
{
   public static void main(String []args) {
      try {
         System.out.println("Process-id: " + getProcessId());
      }
      catch(Exception e) { }
    
      while (true) {
         new Thread(new Task()).start();
          
         try { Thread.sleep(500); } catch(InterruptedException e) { }
      }
   }
    
   public static int getProcessId() throws Exception {
      // next line to trigger loading of library
      ManagementFactory.getThreadMXBean();
       
      Class c = Class.forName("sun.management.VMManagementImpl");
         
      Constructor constructor = c.getDeclaredConstructor(new Class[] { });
      constructor.setAccessible(true);
      Object impl = constructor.newInstance(new Object[] { });
       
      Method m = c.getDeclaredMethod("getProcessId", new Class[] { });
      m.setAccessible(true);
      Object result = m.invoke(impl, new Object[] { });
      
      return (Integer) result;
   }   
}
 
class Task implements Runnable
{
   public void run() {
      Vector<byte[]> v = new Vector<byte[]>();
      while (true) {
         v.add(new byte[10000]);
          
         try { Thread.sleep(100); } catch(InterruptedException e) { }
      }
   }
}

outputs:

Process-id: 2492
... (fills up heap space and eventually throws an OutOfMemoryException)

Then start up the jconsole from the command-line as follows:

   c:j2sdk1.5.0binjconsole 2492

Remote Management

You can also remotely connect. Passwords can be specified and SSL can be enabled (both are default). To start up the Java application without passwords and with SSL disabled, execute this:

java -Dcom.sun.management.jmxremote.port=1097 -Dcom.sun.management.jmxremote.ssl=false 
                                              -Dcom.sun.management.jmxremote.authenticate=false Main

Then, when jconsole starts up specify the host name and port to connect.

You can also use SSL and passwords and roles (like readonly, readwrite). Check the jconsole documentation to do so.

Get started with CopyOnWriteArrayList

The CopyOnWriteArrayList class allows to quickly (no synchronization required) iterate over a list while other threads have the possibility to insert elements to it meanwhile. The following example shows that you simply can’t do that with an ordinary ArrayList:

import java.util.*;
  
public class Main
{
   public static void main(String[] args) {
      ArrayList<String> al = new ArrayList<String>();
     
      new Thread(new Producer(al)).start();
        
      try { Thread.sleep(100); } catch(Exception e) { }
        
      Iterator iter = al.iterator();
      while (iter.hasNext()) {
         System.out.println(iter.next());
      }
   }
}
  
class Producer implements Runnable
{
   private ArrayList<String> al = null;
 
   public Producer(ArrayList<String> al) {
      this.al = al;
   }
  
   public void run() {
      for (int i=0; i<100000; i++) {
         String message = "element #" + i;
         //System.out.println("Adding " + message);
         al.add(message);         
      }
   }
}

outputs, in one run:

element #0
element #1
element #2
element #3
element #4
element #5
element #6
element #7
element #8
element #9
Exception in thread "main" java.util.ConcurrentModificationException
        at java.util.AbstractList$Itr.checkForComodification(AbstractList.java:449)
        at java.util.AbstractList$Itr.next(AbstractList.java:420)
        at Main.main(Main.java:14)

The new java.util.concurrent.CopyOnWriteArrayList solves this problem, but comes at a cost. The CopyOnWriteArrayList makes an entire copy of the underlying array every time it is modified. Only those methods are synchronized.

The following example creates a Producer that continually puts messages on an ArrayList. The other (main) thread waits for a bit, then requests an iterator on the ArrayList. This causes the reference of the original array to be copied into an instance of the internal private (to CopyOnWriteArray) class COWIterator. Any modification performed on the CopyOnWriteArrayList object will not interfere as a new array is instantiated and the old array is copied into it (with System.arraycopy).

Main.java:

import java.util.concurrent.*;
import java.util.*;
  
public class Main
{
   public static void main(String[] args) {
      CopyOnWriteArrayList<String> al = new CopyOnWriteArrayList<String>();
     
      new Thread(new Producer(al)).start();
        
      try { Thread.sleep(10); } catch(Exception e) { }
        
      int counter = 0;
      Iterator iter = al.iterator();
      while (iter.hasNext()) {
         iter.next();
         counter++;
      }
      System.out.println("Iterator returned " + counter + " elements");
   }
}
  
class Producer implements Runnable
{
   private CopyOnWriteArrayList<String> al = null;
 
   public Producer(CopyOnWriteArrayList<String> al) {
      this.al = al;
   }
 
   public void run() {
      for (int i=0; i<100000; i++) {
         String message = "element #" + i;
         //System.out.println("Adding " + message);
         al.add(message);  
      }
   }
}

- How do I easily print out the contents of a one-dimensional array in JDK 1.5?

The old way:

import java.util.*;
 
public class Main
{
   public static void main(String []args) {
      Message[] messages = new Message[10];
      for (int i=0; i<10; i++) {
         Message m = new Message("contents #" + i);
         messages[i] = m;
      }
       
      System.out.println(messages);  // damn, prints out something like [LMessage;@10b62c9 
                                     // need to iterate over the array      
   }
}
 
class Message
{
   String contents = null;
 
   public Message(String contents) {
      this.contents = contents;
   }
    
   public String toString() {
      return contents;
   }
}

The new way:

import java.util.*;
 
public class Main
{
   public static void main(String []args) {
      Message[] messages = new Message[10];
      for (int i=0; i<10; i++) {
         Message m = new Message("contents #" + i);
         messages[i] = m;
      }
       
      System.out.println(Arrays.toString(messages));
   }
}
 
class Message
{
   String contents = null;
 
   public Message(String contents) {
      this.contents = contents;
   }
    
   public String toString() {
      return contents;
   }
}

prints out:

[contents #0, contents #1, contents #2, contents #3, contents #4, contents #5, 
contents #6, contents #7, contents #8, contents #9]

Using a ConcurrentLinkedQueue

A ConcurrentLinkedQueue is an unbounded non-blocking FIFO queue. Although there is already a thread-safe implementation of a linked list:

   List list = Collections.synchronizedList(new LinkedList(...));

the ConcurrentLinkedQueue offers better concurrent performance and scalability.

Main.java:

import java.util.concurrent.*;
import java.util.*;
 
public class Main
{
   public static void main(String []args) {
      Queue<Message> queue = new ConcurrentLinkedQueue<Message>();
 
      Producer p = new Producer(queue);
      new Thread(p).start();
 
      // wait a bit before consuming to allow the queue to fill up
      // and force a blocking wait
      try { Thread.sleep(1000); } catch(InterruptedException e) { }
      Consumer c = new Consumer(queue);
      new Thread(c).start();
   }
}
 
class Producer implements Runnable
{
   private Queue<Message> queue;
 
   public Producer(Queue<Message> queue) {
      this.queue = queue;
   }
 
   public void run() {
      for (int i=0; i<1000; i++) {
         Message<String> m = new Message<String>("message contents #" + i);
         System.out.println("Producing '" + m + "'");
         queue.offer(m);
      }
   }
}
 
class Consumer implements Runnable
{
   private Queue<Message> queue;
    
   public Consumer(Queue<Message> queue) {
      this.queue= queue;
   }
    
   public void run() {
      while (true) {
         Message m = queue.poll();
         if (m != null) {
            System.out.println("tConsuming '" + m + "'");
         }
         else {
            System.out.println("All elements consumed.");
            break;
         }
      }
   }
}
 
class Message<T> {
   private T contents;
    
   public Message(T contents) {
      this.contents = contents;
   }
    
   public T getContents() {
      return contents;
   }
    
   public String toString() {
      return ""+contents;
   }
}