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

Listing the available fonts on your system

You could use the Toolkit method getFontList:

      String fontnames[] = Toolkit.getDefaultToolkit().getFontList();

However, this method is deprecated. Here’s a newer version:

import java.awt.*;
 
public class Main
{
   public static void main(String[] args) {
 
     GraphicsEnvironment env = GraphicsEnvironment.getLocalGraphicsEnvironment();
     String[] fontnames = env.getAvailableFontFamilyNames();
 
     System.out.println("Available fonts:n");
     for(int i=0; i<fontnames.length; i++)
        System.out.println(fontnames[i]);
     }
}

outputs:

Available fonts:

Andale Mono IPA
Arial
Arial Black
Arial Narrow
Book Antiqua
Bookman Old Style
Century Gothic
Comic Sans MS
Courier New
Curlz MT
Default
Dialog
dialog.bold
dialog.bolditalic
dialog.italic
DialogInput
dialoginput.bold
dialoginput.bolditalic
dialoginput.italic
Edwardian Script ITC
eelfont001
eelfont002
Engravers MT
Franklin Gothic Book
Franklin Gothic Demi Cond
Franklin Gothic Heavy
Franklin Gothic Medium Cond
Garamond
Georgia Ref
Haettenschweiler
Impact
Jokerman
Juice ITC
Lucida Bright
Lucida Console
Lucida Sans
Lucida Sans Typewriter
Lucida Sans Unicode
Marlett
Mediascape OSD Icon
Mistral
Monospaced
monospaced.bold
monospaced.bolditalic
monospaced.italic
MS Reference 1
MS Reference 2
MS Reference Sans Serif
MS Reference Serif
MS Reference Specialty
OCR A Extended
RefSpecialty
Rockwell
SansSerif
sansserif.bold
sansserif.bolditalic
sansserif.italic
Serif
serif.bold
serif.bolditalic
serif.italic
Symbol
Tahoma
Tera Special
Times New Roman
Trebuchet MS
Verdana
Verdana Ref
Webdings
Wingdings
Wingdings 2

Shearing an image

Shearing is performing an operation on the image in which the parallel lines will remain parallel while opposite corners are pulled apart (one or two dimensions).

Main.java:

import java.awt.event.*;
import java.awt.image.*;
import java.awt.geom.*;
import javax.swing.*;
import java.awt.*;
 
public class Main extends JFrame {
   private Image image;
 
   public Main() {
      addWindowListener(new WindowAdapter() {
         public void windowClosing(WindowEvent we) {
            System.exit(1);
         }
      });
 
      image = Toolkit.getDefaultToolkit().getImage("c:\djkrush.jpg");
      waitForImage(image);
      image = shearImage(image, 1, 0);
      setSize(image.getWidth(null), image.getHeight(null));
   }
 
   public void paint(Graphics g) {
      g.drawImage(image, 0, 0, this);
   }
 
   public void waitForImage(Image image) {
      MediaTracker mt = new MediaTracker(this);
 
      int id = 0;
      mt.addImage(image, id);
 
      try {
         mt.waitForID(id);
      }
      catch(InterruptedException e) {
         System.out.println("Image loading interrupted : " + e);
      }
   }
 
   public Image shearImage(Image image, double shearx, double sheary) {
      BufferedImage bi = toBufferedImage(image);
 
      AffineTransformOp op = new AffineTransformOp(
                   AffineTransform.getShearInstance(shearx, sheary), null); 
 
      return op.filter(bi, null); 
   }
 
   public BufferedImage toBufferedImage(Image image) {
      BufferedImage bi = new BufferedImage(image.getWidth(null), image.getHeight(null), 
                                           BufferedImage.TYPE_INT_RGB); 
 
      // copy the original image
      Graphics g = bi.createGraphics();
    
      g.drawImage(image, 0, 0, null);
      g.dispose();
 
      return bi;
   }
 
   public static void main(String []args) {
      Main main = new Main();
      main.setVisible(true);
   }
}

Image used:

Get the SUID of a class at runtime

Invoke the method getSerialVersionUID on an instance of the class ObjectStreamClass.

Main.java:

import java.io.*;
 
public class Main implements Serializable {
   public static void main(String args[]) {
      ObjectStreamClass osc = ObjectStreamClass.lookup(Test1.class);
      System.out.println("serialVersionUID for class Test1: " + osc.getSerialVersionUID());
 
      osc = ObjectStreamClass.lookup(Test2.class);
      System.out.println("serialVersionUID for class Test2: " + osc.getSerialVersionUID());
   }
}
 
class Test1 implements Serializable {
}
 
class Test2 implements Serializable {
   static final long serialVersionUID = 1;
}

outputs:

serialVersionUID for class Test1: 3264391750135642662
serialVersionUID for class Test1: 1

Detecting CAPS LOCK in Java

From JDK1.3, you should normally be able to get the state using the Toolkit class as shown in following example.

Main.java

import java.awt.*;
 
public class Main
{
   public static void main(String []args) {
      Toolkit tk = Toolkit.getDefaultToolkit();
      System.out.println(tk.getLockingKeyState(java.awt.event.KeyEvent.VK_CAPS_LOCK));
 
      System.exit(1);
   }
}

However, check out this bug.

Difference between getAbsolutePath and getCanonicalPath

getCanonicalPath() resolves relative paths. It also restores original capitalization. You can use canonical paths to determine if two paths are the same, eg. c:windows..autoexec.bat and c:autoexec.bat will be equal if you get the path using getCanonicalPath but different with getAbsolutePath.

Main.java:

import java.io.*;
 
public class Main {
   public static void main(String args[]) {
      printPath("autoexec.bat");
      printPath("c:\windows\system32\.\cloud.gif");
      printPath("c:\windows\..\autoexec.bat");
      printPath("c:\windows");
   }
 
   public static void printPath(String s) {
      try {
         System.out.println(s);
         System.out.println("tgetAbsolutePath()t" + new File(s).getAbsolutePath());
         System.out.println("tgetCanonicalPath()t" + new File(s).getCanonicalPath());
      }
      catch(IOException e) {
         System.out.println(e); 
      }
   }
}

outputs:

autoexec.bat
	getAbsolutePath()		C:\autoexec.bat
	getCanonicalPath()	C:autoexec.bat
c:windowssystem32.cloud.gif
	getAbsolutePath()		c:windowssystem32.cloud.gif
	getCanonicalPath()	C:WINDOWSSYSTEM32cloud.gif
c:windows..autoexec.bat
	getAbsolutePath()		c:windows..autoexec.bat
	getCanonicalPath()	C:autoexec.bat
c:windows
	getAbsolutePath()		c:windows
	getCanonicalPath()	C:WINDOWS

Catching events while an image is being read using ImageIO

Add an IIOReadProgressListener to your reader.

   IIOReadProgressListener listener = new MyReadProgressListener();
   reader.addIIOReadProgressListener(listener);

It’ll throw events while the reading process is going on. The following example shows a JProgressBar while reading the image fruit.png, to be used as background.

Main.java:

import javax.imageio.metadata.*; 
import javax.imageio.stream.*;
import javax.imageio.event.*;
import javax.imageio.*;
 
import javax.swing.event.*;
import java.awt.image.*;
import java.awt.event.*;
import javax.swing.*;
import java.util.*;
import java.awt.*; 
import java.io.*;
  
public class Main extends JFrame
{
   JProgressBar progressBar;
   BufferedImage background = null;
  
   public Main() {
      addWindowListener(new WindowAdapter() {
         public void windowClosing(WindowEvent we) {
            System.exit(1);
         }
      });
 
      progressBar = new JProgressBar(0, 100);
 
      getContentPane().setLayout(new BorderLayout());
      getContentPane().add(BorderLayout.NORTH, progressBar);
    }
 
   public void loadBackgroundImage(String filename) throws Exception {
      Iterator readers = ImageIO.getImageReadersByFormatName("png");
      ImageReader reader = (ImageReader) readers.next();
 
      IIOReadProgressListener listener = new MyReadProgressListener();
      reader.addIIOReadProgressListener(listener);
 
      ImageInputStream iis = ImageIO.createImageInputStream(new File(filename));
      reader.setInput(iis, true);
      background = reader.read(0);
   }
 
   public static void main(String []args) throws Exception {
      Main main = new Main();
      main.setSize(400, 150);
      main.setVisible(true);
  
      main.loadBackgroundImage("fruit.png");
   }
 
   public void paint(Graphics g) {
      System.out.println(background);
      if (background != null) {
         g.drawImage(background, 0, 0, getWidth(), getHeight(), this);
      }
   }
 
   class MyReadProgressListener implements IIOReadProgressListener {
 
	public MyReadProgressListener() {}
 
        public void imageProgress(ImageReader source, final float percentageDone) {
           System.out.println("imageProgress: " + percentageDone);
 
           SwingUtilities.invokeLater(new Runnable() {
              public void run() {
                 progressBar.setValue((int) percentageDone);
              }
           });   
        }
 
        public void imageComplete(ImageReader source) {
           SwingUtilities.invokeLater(new Runnable() {
              public void run() {
                 try {
                    // wait for a bit until bufferedimage is assigned by reader
                    Thread.sleep(50);
                 }
                 catch(InterruptedException e) { }
                 repaint();
              }
           });              
        }
 
        public void imageStarted(ImageReader source, int imageIndex)  { }
        public void readAborted(ImageReader source)                   { }
        public void sequenceComplete(ImageReader source)              { }
        public void sequenceStarted(ImageReader source, int minIndex) { }
        public void thumbnailComplete(ImageReader source)             { }
        public void thumbnailProgress(ImageReader source, float percentageDone) { }
        public void thumbnailStarted(ImageReader source, int imageIndex, int thumbnailIndex) { }
   }
}

Loading a class with the classloading mechanism in JDK1.2

When the JRE needs to load a new class, it consults following locations:

- bootstrap classes: the core API, rt.jar and i18n.jar
- installed extentions: all jars in lib/ext of JRE_HOME
- system classes: classes specified in the classpath
- download extensions: classes specified in the classpath header of installed extension jars, classpath jars, or previously downloaded download extensions.

1.2 has a delegation model for loading a class. Before loading a class with the current class loader, it is first delegated to the parent to check whether it can be loaded from there. For example, you could define your own package java.util and create a class Vector. Your class would be in the classpath and part of the system class loader, but this one delegates the request first to its parent, the bootstrap class loader which finds the class and loads it from there. This prevents a user from overriding security restrictions by replacing a class in the core API by an own version of the class.

You can create your own class loader by extending from java.lang.ClassLoader and you can specify a parent class loader. If you don’t specify the parent (null), then the system class loader will be its parent.

Filling up an array

Since JDK1.2, the utility class Arrays in the java.util package provides useful
array manipulation methods such as fill, binary search and sort.

You can easily fill up an array with a for loop:

      int values[] = { 5, 74, 23, 99, 6, 0, -2, -60 };
 
      for (int i=0; i<values.length; i++)
         values[i] = 69;

You could also use the Arrays.fill method defined for arrays of type byte[], char[],
double[], float[], int[], long[], object[].

Eg.

      Arrays.fill(values, 69);

It doesn’t work any faster than writing the for loop yourself, it does exactly
the same (contains a for loop), except that it does some range checking.
So, theoretically using Arrays.fill is slower, but your code looks a lot cleaner.
Range checking is necessary if you want to fill up only part of the array using
fill(array, fromvalue, tovalue, value).

      Arrays.fill(values, 1, 4, 69);  yields in the array { 5, 69, 69, 69, 6, 0, -2, -60 }