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

Read a JPG image, rescale it, and write it back to disk

This example shows how to read, scale and rewrite all jpeg images from the current directory.

Main.java:

import com.sun.image.codec.jpeg.*;
import java.awt.event.*;
import java.awt.image.*;
import java.awt.geom.*;
import javax.swing.*;
import java.awt.*;
import java.io.*;
 
public class Main
{
   private final static float JPG_QUALITY = 1f;   // keep original JPEG quality
  
   public static void main(String []args) throws Exception {
      if (args.length != 2) {
         System.err.println("Usage: java Main scalex scaley");
         System.err.println("Scales all .jpg and .gif images to scalex, scaley");
         System.exit(1);
      } 
 
      int scalex = Integer.parseInt(args[0]);
      int scaley = Integer.parseInt(args[1]);
 
      File f = new File(".");
      String[] fileList = f.list();
 
      for (int i=0; i<fileList.length; i++) {
         if (fileList[i].endsWith(".jpg")) {
            System.out.print("Rescaling " + fileList[i] + "...");  
            readScaleWrite(fileList[i], scalex, scaley);
            System.out.println(" done.");
         }
      }
 
      System.exit(1);
   }
 
   public static void readScaleWrite(String filename, int scalex, int scaley) 
                                                           throws Exception {
      Image img = new javax.swing.ImageIcon(filename).getImage(); 
      BufferedImage bi = toBufferedImage(img);
      BufferedImage scaledBi = new BufferedImage(scalex, scaley, bi.getType());
 
      AffineTransform at = new AffineTransform();
      at.scale((double) scalex / bi.getWidth(), (double) scaley / bi.getHeight());
 
      Graphics2D g2d = scaledBi.createGraphics();
      g2d.drawImage(bi, at, null);
      g2d.dispose();
 
      FileOutputStream fos = new FileOutputStream(filename);
      if (filename.endsWith(".jpg")) {
         JPGWrite(scaledBi, fos);
      }
      fos.close();
   }
 
   public static void JPGWrite(BufferedImage bi, OutputStream out) throws IOException {
      JPEGImageEncoder encoder = JPEGCodec.createJPEGEncoder(out);
      JPEGEncodeParam param = encoder.getDefaultJPEGEncodeParam(bi);
      param.setQuality(JPG_QUALITY, true);
      encoder.encode(bi, param);
   }
 
   public static 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;
   }
}

Converting an InputStream to a Reader

An InputStream is byte oriented. A Reader is Character oriented. To hook up an InputStream to a Reader and have the conversion done automatically for you, use the class InputStreamReader.

Main.java:

import java.io.*;
 
public class Main {   
   public static void main(String[] args) throws Exception {
      byte[] b = new byte[] { 65, 66, 67 };
 
      ByteArrayInputStream bais = new ByteArrayInputStream(b);
      InputStreamReader isr = new InputStreamReader(bais);
      int k;
      while ((k = isr.read()) > -1) {
         System.out.println((char) k);
      }
   }
}

outputs:

A
B
C

Using a PipedReader and PipedWriter

A pipe is a communication channel between two threads. It is typically used in producer-consumer systems where one thread produces data (producer) necessary for the other thread (consumer) to operate. In Java, a pipe is implemented by connecting a PipedReader instance to a PipedWriter instance:

   PipedWriter producer = new PipedWriter();
   PipedReader consumer = new PipedReader(producer);

All data written to producer will be stored in a pipe (buffer) until the consumer reads it.

In this example, a thread mimics the behavior of scores for 10 contestants coming in by generating random numbers between [0, 10[. Another thread keeps track of the total votes per contestant.

Main.java:

import java.util.*;
import java.io.*;
 
public class Main {   
   public static void main(String[] args) throws Exception {
      PipedWriter producer = new PipedWriter();
      PipedReader consumer = new PipedReader(producer);
 
      NumberProducer np = new NumberProducer(producer);
      NumberConsumer nc = new NumberConsumer(consumer);
 
      np.start();
      nc.start();
   }
}
 
class NumberProducer extends Thread
{
   BufferedWriter bw;
 
   public NumberProducer(Writer w) {
      this.bw = new BufferedWriter(w);
   }
 
   // thread continually produces random votes
   public void run() {
      try {
         Random r = new Random();
         while (true) {
            String vote = "" + Math.abs((r.nextInt() % 10));
 
            bw.write(vote);
            bw.newLine();
            bw.flush();
 
            sleep(10);
         }  
      }   
      catch(IOException e) {
         System.err.println(e);
      }
      catch(InterruptedException e) {
         System.err.println(e);
      }      
   }
}
 
class NumberConsumer extends Thread
{
   BufferedReader br;
   int[] votes = new int[10];
  
   public NumberConsumer(Reader r) {
      br = new BufferedReader(r);
   }
 
   public void run() {
      try {
         String line;
         int count = 0;
         while ((line = br.readLine()) != null) {
            int contestant = Integer.parseInt(line);
            votes[contestant]++;
 
            count++;
            if (count % 100 == 0) 
               printVotes();
         }      
      }   
      catch(IOException e) {
         System.err.println(e);
      }
   }
 
   public void printVotes() {
      for (int i=0; i<votes.length; i++) {
         System.out.println("Contestant #" + i + ": " + votes[i]);
      }
      System.out.println("——————");
   }
}

outputs:

Contestant #0: 7
Contestant #1: 8
Contestant #2: 10
Contestant #3: 15
Contestant #4: 5
Contestant #5: 11
Contestant #6: 4
Contestant #7: 15
Contestant #8: 16
Contestant #9: 9
------------------
Contestant #0: 22
Contestant #1: 22
Contestant #2: 26
Contestant #3: 21
Contestant #4: 11
Contestant #5: 18
Contestant #6: 13
Contestant #7: 26
Contestant #8: 26
Contestant #9: 15
------------------
Contestant #0: 32
Contestant #1: 29
Contestant #2: 37
Contestant #3: 30
Contestant #4: 29
Contestant #5: 31
Contestant #6: 22
Contestant #7: 35
Contestant #8: 34
Contestant #9: 21
------------------
. . .

Generating a mouse event programatically in Swing

In JDK 1.3, you can use the Robot class, very useful for testing purposes. The following example creates a JFrame with a button and left clicks in the center.

Main.java:

import java.awt.event.*;
import java.awt.image.*;
import javax.swing.*;
import java.awt.*;
  
public class Main extends JFrame
{
   public Main() throws Exception {
      JButton button = new JButton("This button will be clicked");
      getContentPane().add(button);
      pack();
 
      button.addActionListener(new ActionListener() {
         public void actionPerformed(ActionEvent evt) {
            System.out.println("Button was clicked!");
         }
      });
  
      addWindowListener(new WindowAdapter() {
         public void windowClosing(WindowEvent e) {
            System.exit(0);
         }
      });
   }
 
   public void generateClickEvent() throws Exception {
      Robot robot = new Robot();
      robot.mouseMove((int) (getSize().getWidth() / 2), (int) (getSize().getHeight() / 2));
      robot.mousePress(InputEvent.BUTTON1_MASK);
      robot.mouseRelease(InputEvent.BUTTON1_MASK);
   }
  
   public static void main(String args[]) throws Exception {
      Main main = new Main();
      main.show();
      try { Thread.sleep(1000); } catch(InterruptedException e) { } 
      main.generateClickEvent();
   }
}

Finding out the classloader that loaded a particular class

You can have your classes loaded by several distinct classloaders. For example, you may have a URLClassLoader that loads your classes over the network.

To determine what ClassLoader loaded a particular class, you can invoke getClassLoader on the Class object of that class. This method returns null if the default system classloader was used to load the class.

Main.java:

public class Main {
   public static void main(String args[]) throws Exception {
 
      System.out.println(Main.class.getClassLoader());
      System.out.println(A.class.getClassLoader());
      System.out.println(String.class.getClassLoader());
   }
}
 
class A 
{
}

outputs:

sun.misc.Launcher$AppClassLoader@81012801
sun.misc.Launcher$AppClassLoader@81012801
null

Returning multiple values from a method

Strictly speaking you cannot return multiple values from a method call. A method can only return a single primitive value or Object.

Since however, you can return an Object you can always create a new class that contains the values you want to return and simply return a single Object of that class which contains the values needed.

Here we’re trying to get the first and last names of a user with a single call to the User object.

public class User {
   protected String ivFirstName = "Java";
   protected String ivLastName  = "Developer";

   /**
    * This isn't really what you want, since the two values
    * are merged together.
    */
   public String getName() {
      return ivFirstName+" "+ivLastName;
   }
}

Here, we use a new class called UserName that can hold the two values in question.

public class UserName {
   protected String ivFirstName, ivLastName;
 
   public UserName(String first, String last) {
      ivFirstName = first;
      ivLastName  = last;
   }
 
   public String getFirstName() {
      return ivFirstName;
   }
 
   public String getLastName() {
      return ivLastName;
   }
}
 
public class User {
   protected String ivFirstName = "Java";
   protected String ivLastName  = "Developer";
 
   /**
    * This is returning a single Object, which contains
    * multiple values.
    */
   public UserName getName() {
      return  new UserName(ivFirstName, ivLastName);
   }
}

It’s better in general to just return a single value. There are some rare instances where multiple values need to be returned, but these are the exception, and can be dealt with by the preceeding example.

public class User {
   protected String ivFirstName = "Java";
   protected String ivLastName  = "Developer";
 
   /**
    * This is better practice all around.
    */
   public String getFirstName() {
      return ivFirstName;
   }
 
   /**
    * This is better practice all around.
    */
   public String getLastName() {
      return ivLastName;
   }
}