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

Drawing text on top of a BufferedImage

Main.java:

import java.awt.image.*;
import java.awt.event.*;
import javax.swing.*;
import java.awt.*;
 
public class Main extends JFrame {
   BufferedImage image;
 
   public Main() {
      addWindowListener(new WindowAdapter() {
         public void windowClosing(WindowEvent we) {
            System.exit(1);
         }
      });
 
      createImage();
   }
 
   public void createImage() {
      Image backImage = new javax.swing.ImageIcon("mong.jpg").getImage(); 
      int width = backImage.getWidth(this); 
      int height = backImage.getHeight(this); 
      image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB); 
      Graphics2D g2d = image.createGraphics(); 
      g2d.drawImage(backImage, 0, 0, this); 

      g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
                           RenderingHints.VALUE_ANTIALIAS_ON);
      Font f = new Font("Mistral", Font.BOLD, 56);
      g2d.setFont(f);
      String text = "Philip Elliott";
      FontMetrics fm = getFontMetrics(f);       
      int swidth = fm.stringWidth(text);
      int sheight = fm.getAscent();
 
      GradientPaint gp = new GradientPaint(20, 50, Color.red, 
                                           100, 130, Color.yellow, true); 
      g2d.setPaint(gp);
      g2d.drawString(text, width/2 - swidth/2, height/2 + sheight/2);   
 
      setSize(width, height);
   }
  
   public void paint(Graphics g) { 
      Graphics2D g2d = (Graphics2D) g; 
 
      g2d.drawImage(image, null, 0, 0); 
   }
 
   public static void main(String []args) {
      Main main = new Main();
      main.setVisible(true);
   }
}

Image used:

Using PipedInputStream and PipedOutputStream

A PipedInputStream and PipedOutputStream are used to communicate between threads. If you connect the two together, whatever you write to the PipedOutputStream, you receive on the PipedInputStream.

Here’s an example:

Main.java:

import java.io.*;
 
public class Main
{
   public static void main(String []args) {
      try {
         PipedOutputStream pos = new PipedOutputStream();
         PipedInputStream pis = new PipedInputStream(pos);
 
         BufferedInputStream bis = new BufferedInputStream(pis);
  
         new DataCollector(pos).start();
  
         // thread has started to produce data, start 
         // reading data through the pipe here
         while (true) {
            byte[] buffer = new byte[64];
            bis.read(buffer);
            System.out.println("Received: " + new String(buffer));
         }
      }
      catch(IOException e) { 
         e.printStackTrace();
      }
   }
}
 
class DataCollector extends Thread
{
   private BufferedOutputStream bos;
 
   public DataCollector(OutputStream out) {
      this.bos = new BufferedOutputStream(out);
   }
  
   public void run() {
      // generate data here
      int count=0;
      while (true) {
         try {
            count++;
            String data = "data [" + count + "]";
            bos.write(data.getBytes());
            // perform a flush here to make the receiver get it right away
            bos.flush();
            sleep(1000);
         }
         catch(Exception e) {
            e.printStackTrace();
         }
      }
   }
}

outputs:

Received: data [1]
Received: data [2]
Received: data [3]
Received: data [4]
Received: data [5]
Received: data [6]
Received: data [7]
Received: data [8]
Received: data [9]
. . .

Redirecting System.out to a file

Instantiate a PrintStream that streams to your file and use the System.setOut method.
The same can be done for the input and error streams (setIn and setErr).

import java.io.*;
 
public class Main
{
   public static void main(String args[]) {
      try {
         BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("log"));
         PrintStream ps = new PrintStream(bos);
         System.setOut(ps);
 
         System.out.println("Hello world!");
 
         ps.close();
      }
      catch(FileNotFoundException e) {
         System.out.println(e);
      }
   }
}

List the available system roots in Java

Use the method listRoots in the File class. Notice that this is filesystem dependent. On Unix, there is only one system root: “/”. On Windows, it depends on drives that are mapped.
Here’s an example:

Main.java:

import java.io.*;
   
public class Main {
   public static void main(String[] args) {
      File[] roots = File.listRoots();
      for (int i=0; i<roots.length; i++) {
         System.out.println(roots[i]);
      }
   }
}

outputs on my machine:

A:
C:
D:
E:

Determining what formats are supported by ImageIO

ImageIO is extensible. You can add third party plug-ins for other image formats than the standard ones.

Main.java:

import javax.imageio.*;
 
public class Main
{
   public static void main(String []args) {
      String[] formatNames = ImageIO.getReaderFormatNames();
 
      for (int i=0; i<formatNames.length; i++) {
         System.out.println(formatNames[i]);
      }
   }
}

outputs:

png
jpeg
JPEG
gif
jpg
JPG

Example of using clone()

Implement the Cloneable interface and call super.clone() if to make a bit-by-bit shallow copy. A shallow copy implies that only the references are duplicated in the new object and not the referents. This means that changing a referent in your original object has also an effect on the destination object. To prevent this from happening, you need to make a deep copy, that is manually creating duplicates for the members you don’t want to have shared. If all of your classes implement the Serializable marker interface, you can also make a deep copy by serializing using ObjectOutputStream and deserialize it using ObjectInputStream.
Look what happens in the two following examples.

Shallow copy

Main.java:

public class Main {
   public static void main(String args[]) {
      A a1 = new A();            // create an instance of A
      A a2 = (A) a1.clone();     // shallow-copy clone
 
      a1.sb.append(", world!");  // change the stringbuffer member of the first object
 
      System.out.println(a1);
      System.out.println(a2);    // not that the second object has also changed!
   }
}
 
class A implements Cloneable
{
   public StringBuffer sb = new StringBuffer("Hello");
 
   public String toString() {
      return sb.toString();
   }
 
   public Object clone() {
      try {
         return super.clone();
      } 
      catch(CloneNotSupportedException e) { }
 
      return null;
   }
}

outputs:

Hello, world!
Hello, world!

Deep copy

Main.java:

public class Main {
   public static void main(String args[]) {
      A a1 = new A();            // create an instance of A
      A a2 = (A) a1.clone();     // deep-copy clone
 
      a1.sb.append(", world!");  // change the stringbuffer member of the first object
      System.out.println(a1);
      System.out.println(a2);    // not that the second object has not changed now!
   }
}
 
class A implements Cloneable
{
   public StringBuffer sb = new StringBuffer("Hello");
 
   public String toString() {
      return sb.toString();
   }
 
   public Object clone() {
      try {
         A a = (A) super.clone();
         a.sb = new StringBuffer(sb.toString());
         return a;
      } 
      catch(CloneNotSupportedException e) { }
 
      return null;
   }
}

outputs:

Hello, world!
Hello

For more information on cloning an on whether you should catch the CloneNotSupportedException or specify a throws clause, see the link below.

Fast copying an array

There is a fast native method available in the java.lang.System class: arraycopy().
It can be used to copy a region of one array to another. If an array of objects
is copied, only the references are copied. arraycopy() does not allocate memory
for the destination array. Make sure you have allocated enough memory for the
destination array to hold the copied region.

This is its signature:
arraycopy(Object src, int srcOffset, Object dst, int dstOffset, int count)

Following example demonstrates the use:

public class Main
{
   public static void main(String []args) {
      int [] src = { 1, 2, 3, 4, 5, 6, 7, 8 };
      int [] dst = { 0, 0, 0, 0, 0, 0, 0, 0 };
 
      System.arraycopy(src, 2, dst, 1, 3);
   
      printArray(src);
      printArray(dst); 
   }
 
   public static void printArray(int []array) {
      for (int i=0; i<array.length; i++) {
         System.out.print(array[i] + " ");
      }
      System.out.println();
   }
}

outputs:

1 2 3 4 5 6 7 8 
0 3 4 5 0 0 0 0 

Returning a localized Exception

Throwable has a method called getLocalizedMessage, designed so that you can return a message in a language different than the standard getMessage language. By default, getLocalizedMessage returns the same as getMessage, but when you subclass Exception, you can provide your own implementation and preferably look up the localized message using a ResourceBundle.

This example introduces a Download class designed such that it can only handle the HTTP protocol. If it’s not, it will throw our exception DownloadProtocolException. The exception is caught and the message is printed both in the default locale language and a dutch one.

Main.java:

import java.util.*;
import java.io.*;
  
public class Main
{
   public static void main(String []args) {
      try {
         Download d = new Download("ftp://microsoft.com/download/ie5.exe");
         d.start();
      }
      catch(DownloadProtocolException e) {
         System.out.println(e.getMessage());
         System.out.println(e.getLocalizedMessage(new Locale("nl", "BE")));
      }    
   }
}
 
class Download
{
   String url;
 
   public Download(String url) throws DownloadProtocolException {
      if (!url.startsWith("http://")) {
         throw new DownloadProtocolException(url);
      }
   }
 
   public void start() {
      // . . .
   }
}
 
class DownloadProtocolException extends Exception {
   private String url;
 
   public DownloadProtocolException(String url) {
      this.url = url;
   }
 
   public String getMessage() {
      return getLocalizedMessage(Locale.getDefault());
   }
   
   public String getLocalizedMessage(Locale locale) {
      ResourceBundle rb = ResourceBundle.getBundle("ErrorMessages", locale);
      return rb.getString("DownloadProtocolException") + ": " + url;
   }
}

ErrorMessages.properties:

DownloadProtocolException=Wrong protocol (only supports HTTP protocol)

ErrorMessages_nl_BE.properties:

DownloadProtocolException=Fout protocol (ondersteund slechts HTTP protocol)

Make sure these .properties can be found through a path in the classpath.

Running the app outputs:

Wrong protocol (only supports HTTP protocol): ftp://microsoft.com/download/ie5.exe
Fout protocol (ondersteund slechts HTTP protocol): ftp://microsoft.com/download/ie5.exe