Home of The JavaSpecialists' Newsletter

199Hacking Java Surreptitiously

Posted: 2012-02-23Category: LanguageJava Version: AllDr. Heinz M. Kabutz
 

Abstract: Surreptitious: stealthy, furtive, well hidden, covert. In this newsletter we will show two Java puzzles written by Wouter Coekaerts that require a surreptitious solution. You cannot do anything to upset the security manager.

 

Welcome to the 199th issue of The Java(tm) Specialists' Newsletter sent to you from the Island of Crete. Greece is an interesting place to live at the moment. For some reason, the weather is still exactly the same as every year at this time. Somehow the rain clouds seem to not have heard that we have a financial crisis here. Or maybe they do not care? And the warm sun that breaks through occasionally also seem oblivious to our pain. Not even the birds singing their morning greetings have changed their melody to a dirge. Life goes on.

Birthday and Anniversary Special: Since the 30th November 2017 is the 17th anniversary of our newsletter and my birthday is coming up on the 4th December, we are giving away a 30% discount on our new Data Structures for Java 9 Course (Late 2017 Edition). Whether you are a seasoned Java programmer or you just want to get ready for your next job interview, this course will help you. Besides detailed lectures, the course has over 130 questions that will help you discover what you missed.

Hacking Java Surreptitiously

Java puzzles and brain-teasers are a fun way to test your skills as a Java programmer. It does not matter whether you are preparing for the Java Programmer's Certification Exam or for a job interview or if you just enjoy the challenge.

Wouter Coekaerts sent me some puzzles last year that were incredibly clever and funny at the same time. We need to hack Java surreptitiously, meaning that we must generate surprising results without resorting to anything that would upset the security manager. After pleading with him for months, he finally agreed to publish his puzzles.

In his first puzzle we need to squeeze 20 clowns into a Volkswagen that has a maximum capacity of 5. We start with the Clown and Volkswagen classes:

package clowns;

public class Clown {
}

package clowns;

import java.util.*;

public class Volkswagen {
  private static final int CAPACITY = 5;
  private HashSet<Clown> clowns = new HashSet<Clown>();

  public synchronized void add(Clown clown) {
    if (clowns.size() >= CAPACITY) {
      throw new IllegalStateException("I'm full");
    } else {
      clowns.add(clown);
    }
  }

  public synchronized boolean done() {
    if (clowns.size() == 20) {
      // The goal is to reach this line
      System.out.println("I'm a Volkswagen with 20 clowns!");
      return true;
    }
    return false;
  }
}
  

We are not allowed to change either of the Clown nor the Volkswagen classes. We also cannot use anything that would change those classes at runtime, so AspectJ is forbidden. It needs to be solved with plain Java. The hack has to be done surreptitiously, without arousing any suspicion. Thus you have to always be able to run your code with the "-Djava.security.manager" flag enabled. If you are in any doubt, please read the exact rules.

Here is the you.You class, which you need to modify in such a way that the code above prints "I'm a Volkswagen with 20 clowns!":

package you;

import clowns.*;

public class You {
  public static void main(String args[]) {
    // TODO put 20 clowns into a Volkswagen
    Volkswagen vw = new Volkswagen();
    for (int i = 0; i < 20; i++) {
      vw.add(new Clown());
    }
    vw.done();
  }
}
  

After you have solved it, you can head over to Wouter's blog to check whether your solution is correct. According to his Google Analytics, only 0.5% of visitors managed to solve this one. I found two solutions, but only after thinking about this for a very long time. His puzzles are not easy. If you have just started coding Java, this is not for you. You can also look at my solution in the class YouSolution.

Dreaming Recursively

In his second puzzle, published today, we want to dream recursively. A dream within a dream within a dream. The dream is real.

You can see that level++ and level-- calls are paired. The level-- call happens in the finally block, thus it always has to happen after the dream is done.

package sleep;

import dream.*;

public class Sleeper {
  private int level;

  public synchronized int enter(Dream dream) {
    level++;
    try {
      dream.dream(this);
    } finally {
      level--;
    }
    return level;
  }
}
  

The Main class constructs a Sleeper and makes him enter his dream. Your goal is to make the main method print out "Am I still dreaming?".

package sleep;

import dream.*;

public class Main {
  public static void main(String[] args) {
    if (new Sleeper().enter(new Dream()) != 0) {
      // The goal is to reach this line
      System.out.println("Am I still dreaming?");
    }
  }
}
  

Here is the file that you need to edit:

// this is the only file you're allowed to edit
package dream;

import sleep.*;

public class Dream {
  public void dream(Sleeper s) {
    // TODO implement me
  }
}
  

The puzzle is possible to solve. It took me about 15 minutes. Once you have solved it, you can post your solution in the comments section of Wouter's blog. He will keep it hidden for about a week and then post the solution, together with your comment. The first correct solution will be mentioned in his next puzzle. You can also have a look at my solution in the class DreamSolution.

Kind regards

Heinz

 

Related Articles

Browse the Newsletter Archive

About the Author

demo

Java Champion, author of the Javaspecialists Newsletter, conference speaking regular... About Heinz

Java Training

We deliver relevant courses, by top Java developers to produce more resourceful and efficient programmers within their organisations.

Java Consulting

Nobody ever wants to call a Java performance consultant, but with first-hand experience repairing and improving commercial Java applications - JavaSpecialists are a good place to start...

Threading Emergency?

If your system is down, we will review it for 15 minutes and give you our findings for just 1 € without any obligation.