Using the synchronized modifier

If you have more than one of your threads running at the same time that
access shared objects, it may cause your object to be in an inconsitent state.

The following example shows what strange behaviour may result from not thinking
carefully about the implications of thread programming.

class Person
{
   private String name;
 
   public Person() {
   }
 
   public void setName(String name) {
         this.name = name;
   }
 
   public void printName() {
      if (name.equals("alicia")) {
         // this should never happen, right?  ow!
         if (name.equals("joris")) {
            System.out.println(name);
         }
      }
   }
}
 
public class Main extends Thread
{
   private Person person = null;
   private String changeName = null;
 
   public Main(Person person, String changeName) {
      this.person = person;
      this.changeName = changeName;
   }
 
   public static void main(String args[]) {
      Person p = new Person();
      
      new Main(p, "alicia").start();
      new Main(p, "joris").start();
   }
 
   public void run() {
      while (true) {
         person.setName(changeName);
         person.printName();
      }
   }
}

It creates one object
Person and two threads that infinitely sets its member variable name to
respectively alicia and to joris. Then it goes ahead and calls
the printName method that contains some illogical code: print out the name
only if it contains the string alicia and it contains the string joris.
That should never happen, right?
Well, consider this. We use two threads that operate on the same person object.
Every thread gets to use the processor for a certain time slice. Suppose the time
slice of the first thread ends right after the statement if (name.equals(“alicia”)),
which validates to true. Then the second thread gets its chance to run and
calls setName(“joris”) on the same object. What happens now if the first thread gets
again control over the CPU? Right! The member name has the value joris
and will output so.

Java provides locks (also called monitors) to solve this problem. Making a
method synchronized will lock the object. This means that no other thread can call
a synchronized method on that object. In our example, you not only have to make
the method printName synchronized, but also setName or the problem
will still arise. If you don’t make setName synchronized, it may still be
called by the second thread, while the first thread is in the synchronized method
printName.

So remember: every method that accesses a critical shared resource should have
the synchronized modifier.

Solution:

class Person
{
   private String name;
 
   public Person() {
   }
 
   public synchronized void setName(String name) {
         this.name = name;
   }
 
   public synchronized void printName() {
      if (name.equals("alicia")) {
         // this should never happen, right?  ow!
         if (name.equals("joris")) {
            System.out.println(name);
         }
      }
   }
}
 
public class Main extends Thread
{
   private Person person = null;
   private String changeName = null;
 
   public Main(Person person, String changeName) {
      this.person = person;
      this.changeName = changeName;
   }
 
   public static void main(String args[]) {
      Person p = new Person();
      
      new Main(p, "alicia").start();
      new Main(p, "joris").start();
   }
 
   public void run() {
      while (true) {
         person.setName(changeName);
         person.printName();
      }
   }
}

Sometimes, you don’t want to synchronize the entire method, only the statements that
may modify shared resources (the “critical section”). You can achieve this kind of
functionality by using:

synchronized(this) {

}
or
synchronized(lock) {

}
where lock is an object whose lock is being used.

Getting the cos, sin or tan or a number

The hypotenuse is the longest side across from the right angle.
 
               b
              /|
             / |
 hypotenuse /  | opposite
           /   |
          /    |
       a ------- c
         adjacent
 
   sin of a = bc / ab = opposite / hypotenuse
   cos of a = ac / ab = adjacent / hypotenuse
   tan of a = bc / ac = opposite / adjacent

In Java, you can use the static methos in the Math class to determine the sin, cos and tan of an angle.
Here’s an example:

import java.math.*;
                           
public class Main
{  
   public static void main(String args[]) throws Exception {
      double angle = 0.23456;
 
      double sinAngle = Math.sin(angle);
      double cosAngle = Math.cos(angle);
      double tanAngle = Math.tan(angle);
 
      System.out.println("sin of " + angle + ": " + sinAngle);
      System.out.println("cos of " + angle + ": " + cosAngle);
      System.out.println("tan of " + angle + ": " + tanAngle);
   }
}

outputs:

sin of 0.68: 0.6287930240184686
cos of 0.68: 0.7775727187509279
tan of 0.68: 0.8086613751425653

Note: angles to the trigonometric math methods should be given in radians.
If you want to use degrees, you have to convert the radians first:

     360 degrees = 2 pi radians
 
     So, to convert radians into degrees, multiply by 180 / Math.PI
         to convert degrees into radians, multiply by Math.PI / 180

Rounding a BigDecimal

You can use one of the numerous rounding modes.

Main.java:

import java.math.*;
  
public class Main {
   public static void main(String args[]) {
      BigDecimal bd = new BigDecimal("3");          // 3/2=1.5
 
      System.out.println("ROUND_CEILINGt"   + bd.divide(new BigDecimal("2"), 
         BigDecimal.ROUND_CEILING));
      System.out.println("ROUND_DOWNt"      + bd.divide(new BigDecimal("2"), 
         BigDecimal.ROUND_DOWN));
      System.out.println("ROUND_FLOORt"     + bd.divide(new BigDecimal("2"), 
         BigDecimal.ROUND_FLOOR));
      System.out.println("ROUND_HALF_DOWNt" + bd.divide(new BigDecimal("2"), 
         BigDecimal.ROUND_HALF_DOWN));
      System.out.println("ROUND_HALF_EVENt" + bd.divide(new BigDecimal("2"), 
         BigDecimal.ROUND_HALF_EVEN));
      System.out.println("ROUND_HALF_UPt"   + bd.divide(new BigDecimal("2"), 
         BigDecimal.ROUND_HALF_UP));
      System.out.println("ROUND_UPt"        + bd.divide(new BigDecimal("2"), 
         BigDecimal.ROUND_UP));
      System.out.println("ROUND_UNNECESSARYt" + bd.divide(new BigDecimal("2"), 
         BigDecimal.ROUND_UNNECESSARY));
   } 
}

outputs:

ROUND_CEILING	2
ROUND_DOWN		1
ROUND_FLOOR		1
ROUND_HALF_DOWN	1
ROUND_HALF_EVEN	2
ROUND_HALF_UP	2
ROUND_UP		2
Exception in thread "main" java.lang.ArithmeticException: Rounding necessary
        at java.math.BigDecimal.divide(BigDecimal.java:344)
        at java.math.BigDecimal.divide(BigDecimal.java:403)
        at Main.main(Main.java:21)

Explanation:

ROUND_CEILING:        (always towards positive infinitive)
   0.3  rounds to  1, 
   -0.9 rounds to  0   
ROUND_DOWN:           (always rounds towards zero)
   0.3  rounds to  0, 
   0.9  rounds to  0, 
   -0.9 rounds to  0  
ROUND_FLOOR:          (always rounds towards negative infinity)
   0.3  rounds to  0
   0.9  rounds to  0
   -0.3 rounds to -1
ROUND_HALF_DOWN:      (rounds to the neirest distance, if .5: round to zero)
   0.3  rounds to  0
   0.9  rounds to  1
   -0.9 rounds to -1
   0.5  rounds to  0
   -0.5 rounds to  0
ROUND_HALF_EVEN:      (rounds to the neirest distance, if .5: round to neirest even)
   0.3  rounds to  0
   -0.9 rounds to -1
   0.5  rounds to  0
   -0.5 rounds to  0
   1.5  rounds to  2 
   -1.5 rounds to -2
   2.5  rounds to  2
   -2.5 rounds to -2
ROUND_HALF_UP:        (rounds to the neirest distance, if .5: round away from zero)
   0.3  rounds to  0
   0.9  rounds to  1
   -0.9 rounds to -1
   0.5  rounds to  1
   -0.5 rounds to -1
ROUND_UP:             (always round away from zero)
   0.3  rounds to  1
   -0.3 rounds to -1
   0.5  rounds to  1
   -0.5 rounds to -1

Encoding and decoding a URL

When working with the HTTP protocol, some type of encoding is necessary because certain characters that are communicated over the network have special meaning for webservers, like @ and ?. For example, if you create a FORM in HTML using the GET or POST method, the webserver needs to differentiate between the different elements available on the form, etc. URL encoding is the most popular encoding scheme used for these types of things. It’s MIME format is called “x-www-form-urlencoded”.

The scheme for encoding is very simple (from the API):

   - 'a' through 'z', 'A' through 'Z', and '0' through '9' remain unchanged;
   - ' ' is converted to '+'
   - all other chars are converted into a 3 characters &hx where hx is the the 
     hexadecimal representation of the the lower 8-bits of the character. 

Main.java:

import java.net.*;
  
public class Main
{
   public static void main(String []args) {
      String s = "Hello, world!?!#@$#%";
      System.out.println("unencoded:t" + s);
 
      String encoded = URLEncoder.encode(s);
      System.out.println("encoded:t" + encoded);
 
      String decoded = URLDecoder.decode(encoded);
      System.out.println("decoded:t" + decoded);
   }
}

outputs:

Unencoded:	Hello, world!?!#@$#%
encoded:	Hello%2C+world%21%3F%21%23%40%24%23%25
decoded:	Hello, world!?!#@$#%

Try changing the string “hello world” with a complex url!

Notice that the method URLDecoder.decode throws an Exception in JDK1.2.2 (but it actually never throws one). This was removed in 1.3 and may affect compiling older code, as you had to catch the exception before 1.3. See the bug at the link below.

Connecting to the echo port (7)

The echo port 7 will return a datagram that contains the exact contents of what was sent to it.
On many systems, this port is being disabled, fearing hackers may use it to perform a denial-of-service attack of some sort.

Just open a socket and write a line. If the port is enabled, the return will be the exact line.

EchoClient.java:

import java.util.*;
import java.net.*;
import java.io.*;
 
public class EchoClient {
   public static void main(String args[]) {
      if (args.length != 1) {
         System.out.println("java EchoClient <server>");
         System.exit(1);
      }
 
      try {
         Socket socket = new Socket(args[0], 7);    // 7 is echo port
         BufferedReader br = new BufferedReader(
                                new InputStreamReader(socket.getInputStream()));
 
         // true = autoflush
         PrintWriter pw = new PrintWriter(
                                new OutputStreamWriter(socket.getOutputStream()), true);  
 
         pw.println("Hello, world!");
 
         String ret = br.readLine();
         System.out.println(ret);
 
         socket.close();       
      }
      catch(Exception e) {
         e.printStackTrace();
      }
   }
}

java EchoClient www.compapp.dcu.ieoutputs:

Hello, world!

What is a message digest?

A messagedigest is a sortof a fingerprint for a chunk of data. If only one bit of that data has changed, the message digest algorithm would generate a different fingerprint. This allows you to determine if, for example during network transmission of data, that data has changed. You cannot deduce the original contents of a message from a message digest.

A common example is the use of a password system, where passwords are stored as messagedigests. When you logon to the system, it will compute a messagedigest of the password you’ve typed in and compare it with the messagedigest that is stored in the username/password file.

There are two popular types of message digest algorithms: MD5 and SHA.

For example, the MD5 message digest for the plaintext The sun is green and the grass shines is (in hex) 470DB3B23F9D445446DFCE291C9F17AB.

For information on how to generate a messagedigest in Java, look at this answer.

Encrypting/decrypting using RC2

RC2 stands for Rivest’s Code 2. More information can be found on the RSA Security site.

Main.java:

import javax.crypto.spec.*;
import java.security.*;
import javax.crypto.*;
 
public class Main
{
   public static void main(String []args) throws Exception {
      String toEncrypt = "The shorter you live, the longer you're dead!";
 
      System.out.println("Encrypting...");
      byte[] encrypted = encrypt(toEncrypt, "password");
 
      System.out.println("Decrypting...");
      String decrypted = decrypt(encrypted, "password");
    
      System.out.println("Decrypted text: " + decrypted);
   } 
 
   public static byte[] encrypt(String toEncrypt, String key) throws Exception {
      // create a binary key from the argument key (seed)
      SecureRandom sr = new SecureRandom(key.getBytes());
      KeyGenerator kg = KeyGenerator.getInstance("RC2");
      kg.init(sr);
      SecretKey sk = kg.generateKey();
 
      // create an instance of cipher
      Cipher cipher = Cipher.getInstance("RC2");
 
      // initialize the cipher with the key
      cipher.init(Cipher.ENCRYPT_MODE, sk);
 
      // enctypt!
      byte[] encrypted = cipher.doFinal(toEncrypt.getBytes());
 
      return encrypted;
   }
 
   public static String decrypt(byte[] toDecrypt, String key) throws Exception {
      // create a binary key from the argument key (seed)
      SecureRandom sr = new SecureRandom(key.getBytes());
      KeyGenerator kg = KeyGenerator.getInstance("RC2");
      kg.init(sr);
      SecretKey sk = kg.generateKey();
 
      // do the decryption with that key
      Cipher cipher = Cipher.getInstance("RC2");
      cipher.init(Cipher.DECRYPT_MODE, sk);
      byte[] decrypted = cipher.doFinal(toDecrypt);
 
      return new String(decrypted);
   }
}

(tested with the BouncyCastle JCE provider, http://www.bouncycastle.org)

Performing authentication with JAAS

Authentication

The authentication component of JAAS can determine who is executing code. It’s against useability to have a user on a system remember different passwords, one for each program where authentication is required. If a user on a system is used to identifying himself by means of a fingerprint device, the ideal situation would be to do the same for your new Java application that requires authentication. JAAS uses a pluggable architecture for authentication called PAM, Pluggable Authentication Module. This allows for integration of existing PAM-enabled authentication mechanisms with your program. So vendors can write authentication modules for different types of login systems. More information about PAM can be found here.

The following example will show how to build an authentication module. The following steps are executed in trying to authenticate a subject:

  1. Instantiate a LoginContext
  2. The LoginContext loads one or more LoginModules described in a Configuration
  3. login() is called on the instantiated LoginContext
  4. The LoginModules are consulted to see if the user can be authenticated and if so, principals and credentials are associated with the subject
  5. If the status of the login is positive, the subject can be retrieved. Otherwise, a LoginException is thrown.

Here is a small example that will ask a user for his username and password and consults a text file to determine if that user has the necessary permissions to continue.

First we create a “database” textfile that contains a list of user entries that can be successfully authenticated in the form username,password.
passwd:

johndoe,sdefujm
janedoe,yuymndee

Then we write our authentication module.

UsernamePasswordLoginModule.java:

import javax.security.auth.callback.*;
import javax.security.auth.login.*;
import javax.security.auth.spi.*;
import javax.security.auth.*;
import java.security.*;
import java.util.*;
import java.io.*;
 
public class UsernamePasswordLoginModule implements LoginModule {
   private Subject subject;
   private CallbackHandler callbackHandler;
 
   private String username;
   private char[] password;
   private boolean loginSucceeded = false;
   private boolean commitSucceeded = false;
  
   private Principal principal;
 
   public void initialize(Subject subject, CallbackHandler callbackHandler, 
                          Map sharedState, Map options) {
      System.out.println("LoginModule initialize()");
      this.subject = subject;
      this.callbackHandler = callbackHandler;
      username = null;
      clearPassword();
      loginSucceeded = false;
      commitSucceeded = false;
   }
 
   public boolean login() throws LoginException {
      System.out.println("LoginModule login()");
      if (callbackHandler == null) {
         throw new LoginException("No CallbackHandler!");
      }
 
      Callback[] callbacks = new Callback[2];
      callbacks[0] = new NameCallback("Username: ");
      callbacks[1] = new PasswordCallback("Password: ", false);
 
      try {
         callbackHandler.handle(callbacks);
         username = ((NameCallback) callbacks[0]).getName();
         char[] temp = ((PasswordCallback) callbacks[1]).getPassword();
         password = new char[temp.length];
         System.arraycopy(temp, 0, password, 0, temp.length);
 
         BufferedReader br = new BufferedReader(new FileReader("passwd"));
         String line;
         while ((line = br.readLine()) != null) {
            int comma = line.indexOf(',');
            String un = line.substring(0, comma);
            String pw = line.substring(comma+1);
 
            if (username.equals(un) && new String(password).equals(pw)) {
               // succeeded!
               loginSucceeded = true;
               return true;
            }
         }
      }
      catch(IOException e) {
         throw new LoginException(e.toString());
      }
      catch(UnsupportedCallbackException e) {
         throw new LoginException(e.toString());
      }
 
      username = null;
      clearPassword();
      loginSucceeded = false;
 
      throw new FailedLoginException("Incorrect Username/Password");
   }
 
   public boolean commit() throws LoginException {
      System.out.println("LoginModule commit()");

      if (loginSucceeded == false) {
         return false;
      }
 
      principal = new MyPrincipal(username);
      if (!(subject.getPrincipals().contains(principal))) {
         subject.getPrincipals().add(principal);
      }
 
      username = null;
      clearPassword();
      commitSucceeded = true;
       
      return true;
   }
  
   public boolean abort() throws LoginException {
      System.out.println("LoginModule abort()");

      if (!loginSucceeded) {
         return false;
      }
      else if (loginSucceeded && commitSucceeded) {
         loginSucceeded = false;
         username = null;
         clearPassword();
         principal = null;
      }
      else {
         logout();
      }
 
      return true;
   }
 
   public boolean logout() throws LoginException {
      System.out.println("LoginModule logout()");

      subject.getPrincipals().remove(principal);
      loginSucceeded = false;
      commitSucceeded = false;
      username = null;
      clearPassword();
      principal = null;
 
      return true;
   }
 
   private void clearPassword() {
      if (password != null) {
         for (int i=0; i<password.length; i++) {
            password[i] = ' ';
         }
         password = null;
      }
   }
}

This implementation of LoginModule contains the code to check whether a user is permitted to log in or not. You can provide multiple login modules, checking several sources for authentication. Our module checks whether a username and password exists in our database textfile passwd. Its task is to determine if a username/password pair (the subject) should be authenticated and if success it should add principals to that subject. When a user is asked to be authenticated, JAAS calls the methods in our LoginModule in a certain order. initialize() will be called with certain state information, most importantly the subject to be authenticated and an instance of CallbackHandler that is used later on to get the login information from the user.

  • login() first creates a set of Callbacks, one for the username and one for the password. After we call handle() on our CallbackHandler, the username/password pair should be filled in in both of these callback objects. In this case (see below), a Swing dialog will pop up and ask the user for his username and password. But it can be anything else to get the user’s info, for example by using the information on the currently logged in user on a Windows NT domain. After we get the username/password information from the user, we check whether they exist in the passwd file.
  • commit() will be called when login was successful. It should fill up the subject with the associated principals and credentials and clean up the state.
  • abort() will be called to abort the authentication procedure when either one of the login() or the commit() method fails.
  • logout() will be called when a user is ready to log out.

    For more information on how to write a LoginModule, check out JAAS LoginModule’s Developer’s Guide.

    Our Main program looks like this:

    Main.java:

    import com.sun.security.auth.callback.*;
    import javax.security.auth.login.*;
    import javax.security.auth.*;
    import java.security.*;
     
    public class Main {
       public static void main(String []args) throws Exception { 
          try {
             LoginContext loginContext = new LoginContext("MyAuthenticationComponents", 
                                                 new DialogCallbackHandler());
     
             // will throw a LoginException if it fails, falls through otherwise
             loginContext.login();
     
             Subject subject = loginContext.getSubject();
             System.out.println(subject);
     
             loginContext.logout();
          }
          catch(LoginException e) {
             System.out.println("Unauthorized user!");
          } 
     
          // stop AWT thread (DialogCallbackHandler)
          System.exit(0);
       }
    }

    You create an instance of LoginContext, a class able to authenticate subjects. You need to pass in a String that determines the LoginModules that will be used in authenticating a subject. In our example, we use MyAuthenticationComponents (look at the jaas.config file below). If no LoginException was thrown, the subject is printed out. Notice that we use the Sun undocumented class DialogCallbackHandler that will pop up a dialogbox to ask the user for a username and password.

    jaas.config:

    MyAuthenticationComponents {
       UsernamePasswordLoginModule required;
    };

    This configuration file specifies the module that should be used to authenticate the user. The required flag specifies that the result of the module must be successful in order for the entire login to succeed. You may specify several login modules with different flags. Other flags are Requisite, Sufficient and Optional. Check out this article for more information on these flags.

    Finally we have a MyPrincipal object that implements the Principal interface and encapsulates a subject’s identify.

    MyPrincipal.java:

    import java.security.*;
    import java.io.*;
     
    public class MyPrincipal implements Principal, Serializable
    {
       private String name;
    
       public MyPrincipal(String name) {
          this.name = name;
       }
      
       public String getName() {
          return name;
       }
      
       public int hashCode() {
          return name.hashCode();
       }
     
       public String toString() {
          return getName();
       }
     
       public boolean equals(Object obj) {
          if (obj == null) {
             return false;
          }
     
          if (!(obj instanceof MyPrincipal)) {
             return false;
          }
     
          MyPrincipal mp = (MyPrincipal) obj;
          if (name.equals(mp.getName())) {
             return true;
          }
     
          return false;
       }
    }

    To run this code, we need to specify the configuration file to be used. You can do that by specifying the System property java.security.auth.login.config at command line:

     c:jdk1.4binjava -Djava.security.auth.login.config==jaas.config Main

    Alternatively, it can be configured in the java.security properties file. Check out this reference for more information.

    Output with username=johndoe, password=sdefujm:

    LoginModule initialize()
    LoginModule login()
    LoginModule commit()
    Subject:
    	Principal: johndoe
    LoginModule logout()

    Output with username=johndoe, password=abcdefg:

    LoginModule initialize()
    LoginModule login()
    LoginModule abort()
    Unauthorized user!