Java Deep

Pure Java, what else

Do all business logic on the client using JavaScript?

History look

The first applications were running on “the” computer. There was nothing like “client” and “server”. There was the computer and the punch card input, printer output. Later the mainframe came and the clients were terminals. Looking back, we can say that this was a two tier architecture with lightweight clients. This was practically the same with the mini computers (PDP, VAX and their clones) until the PC was introduced.

The PC architecture introduced the two tier paradigm that contained a fat client and file server or database server. Three tier architecture was supposed to replace the two tier architecture to have a no-so-fat client, server supporting business logic and storage on the third tier. Then came the web and the browser and the client was replaced by web page. Thin client was invented. At least the terminology was born that time. And during the last 20 years the web technology evolved and with HTML5 we have something on the client side that is very powerful and in functionality and in capability comparable to the thick client of the early PC era. If we consider the memory and CPU power we currently have an HTML5 capable browser fairly overcomes any early PC fat client.

Time to think about what is implemented in what tier. As we see the functionality, storage and code were dangling back and forth between the client and various server components. The optimal distribution of functionality was determined by the distribution and availability of CPU power in the different tiers, storage capabilities and network latency as well as bandwidth. Technology evolving changing the ratio between these changed where we put parts of the functionality.

Today

Today clients are so powerful that we are tempted to put everything on the client. It is not only the available top-notch client, which is so powerful. We can also expect good cpu power, memory and bandwidth on the average client. Why not to put all functions on the client? Could we do all business logic on the client? Almost. There are some features, not mentioned above, that a client does not implement and is not likely to implement in the near future with the current architectures. Some of these are features like:

  • persistence
  • search
  • transactions
  • trust

Let us look at these features.

Persistence

You can not store data reliably on the client. Backup, archive, audit logging are functions that are naturally live on a server. If ever any of these are implemented on a client machine that machine is operated as a server some way. If not impossible then probably expensive to do it on a client. Individual clients can not simply backed up and they have to communicate with each other to see the same state of the data that reflects the actual state of the modeled world.

Search

Search is also something not likely to be implemented on the client. Search needs the data to search in. In some cases the data set can be copied to the client and thus the search can be implemented on the client, but in most of the cases the client will work only with a subset of the data, therefore search is implemented on the server.

Transaction

Transactions are tied to data. If you sell airplane tickets you may not want to have a system that asks all other client terminals if the seat A in row 13 is still free on a certain line. That would be a total noise like a room full of people. Perhaps something like the old stock trading rooms may resemble to that.

Trust

Clients are owned by the person having physical access to the machine. Steve Halls’ talking moose said: “Never trust a computer you can not lift.” When it comes to physical security it is crucial the other way around: Never trust a computer somebody else can lift. In an application you can not trust any communication that comes from a certain client unless you established some trust. Password, card access whatever. But the trust to maintain is up to the server, which some bad guy can not nick.

Where does it come?

Single page applications contain static HTML, CSS and JavaScript. The server communicates with the client using Ajax, REST, JSON. The users identify themselves using some authentication, probably OAuth. After that the client application displays whatever the functionality of the application needs and the server provides only data functionality. All the server should do is CRUD with access control. Whenever a client wants to access some data the server has to check if the said user has the rights to read and/or to write the data. Other than that the server need not know anything about the business functionality.

Persistence services, like MySQL or MongoDB (to name one of SQL and NoSQL) are providing REST interface and the interfaces obviously do require authentication. However the authorization scheme of these interfaces are very weak. The usual approach is: if you authenticate you are authorized. There is no document or record level access control, which I see will come in the future. First we will have applications that work as a front-end to these persistence applications that check the authorization and based on that let or deny the operation to perform. However this solution is not optimal from the performance point of view. The logical implementation of such logic is where the data is: in the database.

If and when the databases will support such a record level authorization schema we can write all our code, or almost all code in JavaScript running on the client. Applications will be developed in JavaScript. Java will only remain for enterprise integration, connection handling to legacy systems. Java will be what Cobol is today. Will it?

When null checking miserably fails

Disclaimer

Before going on I have to state that the techniques described in this article serve no practical purpose when we program Java. It is like a crossword or puzzle. It may train your brain in logical thinking, may develop your Java language knowledge or even your thinking skills. It is like a trick a magician performs. At the end you realize that nothing is what it looks like. Never do such tricks in real life programming that you may need to apply to solve this mind twister.

The Problem

I recently read an article that described the debugging case when

if(trouble != null && !trouble.isEmpty()) {
  System.out.println(“fine here: ” + trouble);
  }else{
  System.out.println(“not so fine here: ” + trouble);
}

was printing out

fine here: null

The actual bug was that the string contained “null”, a.k.a. the characters ‘n’, ‘u’, ‘l’ and ‘l’. May happen in real life especially when you concatenate strings without checking the nullity of a variable.

Then I started to think about other similar strange code and debug situation. Could I make it so that the variable is not only “null” string with these characters but really null? Seems to be crazy? Have a look at the code:

package com.javax0.blog.nullisnotnull;

public class NullIsNotNull {

	public static void troubled(){
		String trouble = new String("hallo");
		Object z = trouble != null && !trouble.toString().isEmpty() ? 
                                                          trouble.toString() : "";
		if (z == null) {
			System.out.println("z is really " + z + "?");
		}
	}
}

Will it ever print out the

z is really null?

question. The fact is that you can create a Java class containing a public static void main() so that starting that class as a Java application the sentence will be printed when main() invokes the method troubled(). In other words: I really invoke the method troubled() and the solution is not that main() prints the sentence.

In this case the variable z is not only printed as “null” but it really is null.

Hints

The solution should not involve

  • reflection
  • byte code manipulation
  • calling JNI
  • special class loaders
  • java agent
  • annotation processor

These are too heavy tools. You do not need such armory for the purpose.

Hint #1

If I change the code so that the variable z is String it does not even compile:

This is what I see in Eclipse

This is what I see in Eclipse

If it confused you even more, then sorry. Read on!

Hint #2

In the Java language String is an identifier and not a keyword. The Java Language Specification section 3.9 may give more information on the significance of this.

Hint #3

The method toString() in class Object has a return type java.lang.String. You may want to read my article about the difference between the name, simple name and canonical name of a class. It may shed some light and increase the hit count of the article.

Hint #4

To use a class declared in the same package you need not import that package.

Solution

The solution is to create a class named String in the same package. In that case the compiler will use this class instead of java.lang.String. The ternary operator in the code is simple magician trick. Something to diverge your attention from the important point. The major point is that String is not java.lang.String in the code above. If you still can not find out how to create the trick class, click on the collapsed source code block to see it in all glory:

package com.javax0.blog.nullisnotnull;

class String {
	private java.lang.String jString;
	private boolean first = true;

	public String(java.lang.String s) {
		jString = s;
	}

	public boolean isEmpty() {
		return jString.isEmpty();
	}

	@Override
	public java.lang.String toString() {
		if( first ){
			first = false;
			return jString;
		}
		return null;
	}

	public static void main(java.lang.String[] args) {
		NullIsNotNull.troubled();
	}
}

Do not use immutable in your API

Why should an API define methods that accept Guava Immutable collection types? It should not. The intent of the author of such an API is clear: she wants to declare and be safe that the method does not modify the collection that the caller passes. The problem is that it forces the caller to use Guava immutable collections and the caller can not just pass a hash or tree map, a hash set or whatever is a matching type for the actual collection. I know that this is not a big deal to convert a map or set to the immutable counterpart, but let me, as a user of a library have the freedom to decide if I want to do that.

It does not mean that I do not need guarantee. When an API documents that a collection that the caller passes will not be altered, I expect the implementation (a.k.a. library) not to do that. I expect it working just like any other feature, which is documented. However, the implementation is the internal responsibility of the library and has to be well coded during development time. It simply should not call any of the mutating methods. To assess that the development time tools have to be used. Unit tests. Code analysis.

If the library wants to be on the safe side, it can use the Guava library to “copy” the value passed as argument to the API from a collection interface to the appropriate immutable implementation. Or it can use the JDK built in Collections.unmodifiableXXX methods. Whether it does it or not is implementation detail. The API, the declaration of the classes, methods, arguments are the “interface”. The API user should only face the interface and not the implementation details.

Therefore I say: do not use immutable implementations in the method parameter list. Use them in the implementation only.

Why to use String

Recently I was tutoring juniors during a training session. One of the task was to write a class that can dwarwle maps based on some string key. The result one of the juniors created contained the following method:

	void dwarwle(HashMap<String,Dwarwable> mapToDwarwle, String dwarwleKey){
		for( final Entry<String, Dwarwable> entry : mapToDwarwle.entrySet()){
			dwarwle(entry.getKey(),entry.getValue(),dwarwleKey);
		}
	}

The code was generally ok. The method to dwarwle an individual dwarwable entry using the actual key it is assigned to in the hash map and the dwarwle key is factored to a separate method. It is so simple that I do not list here. The variable names are also meaningful so long as long you know what actually dwarwling is. The method is short and readable, but the argument list expects a HashMap instead of a Map. Why do we want to restrict the caller to use a HashMap? What if the caller has a TreeMap and for good reason. Do we want to have separate method that can dwarwle TreeMap? Certainly not.

Expect the interface, pass the implementation.

The junior changed the code replacing HashMap to Map but after five minutes or so this clever lady raised her hand and had the following question:

“If we changed HashMap to Map, why did not we change String to CharSequence?”

It is not so easy to answer a question like that when it comes out of the blue. The first thing that came up in my mind is that the reason is that we usually do it that way and that is why. But that is not a real argument, at least I would not accept anything like that and I also except my students not to accept such answer. It would be very dictator style anyway.

The real answer is that the parameter is used as a key in a map and the key of a map should be immutable (at least mutation should be resilient to equals and hashcode calculation). CharSequence is an interface and an interface in Java (unfortunately) can not guarantee immutability. Only implementation can. String is a good, widely known and well tested implementation of this interface and therefore can be a good choice. There is a good discussion about it on stackoverflow.

In this special case we expect the implementation because we need something immutable and we “can not” trust the caller to pass a character sequence implementation that is immutable. Or: we can, but it has a price. If a StringBuilder is passed and modified afterwards our dwarwling library may not work and a blame war may start. When we design an API and a library we should also think about not only the possible but also about the actual, average use.

A library is as good as it is used and not as it could be used.

This can also be applied to other products, not only libraries but this may lead too far (physics and weapon).

Autoboxing

Autoboxing is clear for all Java developers since Java 1.5 Well, I may be too optimistic. At least all developers are supposed to be ok with autoboxing. After all there is a good tutorial about it on the page of ORACLE.

Autoboxing is the phenomena when the Java compiler automatically generates code creating an object from a primitive type when it is needed. For example you can write:

Integer a = 42;

and it will automatically generate JVM code that puts the value int 42 into an Integer object. This is so nice of the compiler to do it for us that after a while we, programmers just tend to forget about the complexity behind it and from time to time we run against the wall.

For example we have double.class and Double.class. Both of them are objects (as being a class and each class itself is an object in permgen or just on the heap in post-permgen version of JVM). Both of these objects are of type Class. What is more: since Java 1.5 both of them are of type Class<Double>.

If two objects have the same type, they also have to be assignment compatible aren’t they. Seems to be an obvious statement. If you have object O a and object O b then you can assign a = b.

Looking at the code, however we may realize being oblivious instead of obvious:

public class TypeFun {
    public static void main(String[] args) {
        // public static final Class<Double>   TYPE = (Class<Double>)Class.getPrimitiveClass("double");
        System.out.println("Double.TYPE == double.class: " + (Double.TYPE == double.class));
        System.out.println("Double.TYPE == Double.class: " + (Double.TYPE == Double.class));
        System.out.println("double.class.isAssignableFrom(Double.class): " + (double.class.isAssignableFrom(Double.class)));
        System.out.println("Double.class.isAssignableFrom(double.class): " + (Double.class.isAssignableFrom(double.class)));
    }
}

resulting

Double.TYPE == double.class: true
Double.TYPE == Double.class: false
double.class.isAssignableFrom(Double.class): false
Double.class.isAssignableFrom(double.class): false

This means that the primitive pair of Double is double.class (not surprising). Even though one can not be assigned from the other. We can look at the source at least of the one of the them. The source of the class Double is in the RT.jar and it is open source. There you can see that:

public static final Class<Double>	TYPE = (Class<Double>) Class.getPrimitiveClass("double");

Why does it use that weird Class.getPrimitiveClass("double") instead of double.class? That is the primitive pair of the type Double.

The answer is not trivial and you can dig deep into the details of Java and JVM. Since double is not a class, there is nothing like double.class in reality. You can still use this literal in the Java source code though and this is where the Java language, compiler and the run-time has some strong bondage. The compiler knows that the class Double defines a field named TYPE denoting the primitive type of it. Whenever the compiler sees double.class in the source code it generates JVM code Double.TYPE. (Give it a try and then use javap to decode the generated code!) For this very reason the developer of the RT could not write

public static final Class<Double>	TYPE = double.class;

into the source of the class Double. It would compile to the code equivalent:

public static final Class<Double>	TYPE = TYPE;

How is autoboxing going on then? The source

Double b = (double)1.0;

results

         0: dconst_1      
         1: invokestatic  #2                  // Method java/lang/Double.valueOf:(D)Ljava/lang/Double;
         4: astore_1 

however if we replace the two ‘d’ letters:

double b = (Double)1.0;

then we get

         0: dconst_1      
         1: invokestatic  #2                  // Method java/lang/Double.valueOf:(D)Ljava/lang/Double;
         4: invokevirtual #3                  // Method java/lang/Double.doubleValue:()D
         7: dstore_1    

, which ineed explains a lot of things. The instances of the class double.class the class Double.class are not assign compatible. Autoboxing solves this. Java 4 was a long time ago and we, luckily forgot it.

Your homework: reread what happens related to autoboxing when you have overloaded methods that have arguments of the “class” type and the corresponding primitive type.

A classloading mystery solved

Facing a good old problem

I was struggling with some class loading issue on an application server. The libraries were defined as maven dependencies and therefore packaged into the WAR and EAR file. Some of these were also installed into the application server, unfortunately of different version. When we started the application we faced the various exceptions that were related to these types of problems. There is a good IBM article about these exceptions if you want to dig deeper.

Even though we knew that the error was caused by some double defined libraries on the classpath it took more than two hours to investigate which version we really needed, and what JAR to remove.

Same topic by accident on JUG the same week

A few days later we participated the Do you really get Classloaders? session of Java Users’ Society in Zürich. Simon Maple delivered an extremely good intro about class loaders and went into very deep details from the very start. It was an eye opening session for many. I also have to note that Simon works Zero turnaround and he evangelizes for JRebel. In such a situation a tutorial session is usually biased towards the actual product that is the bread for the tutor. In this case my opinion is that Simon was absolutely gentleman and ethic keeping an appropriate balance.

Creating a tool, to solve mystery

just to create another one

A week later I had some time to hobby program that I did not have time for a couple weeks by now and I decided to create a little tool that lists all the classes and JAR files that are on the classpath so investigation can be easier to find duplicates. I tried to rely on the fact that the classloaders are usually instances of URLClassLoader and thus the method getURLs() can be invoked to get all the directory names and JAR files.

Unit testing in such a situation can be very tricky, since the functionality is strongly tied to the class loader behavior. To be pragmatic I decided to just do some manual testing started from JUnit so long as long the code is experimental. First of all I wanted to see if the concept is worth developing it further. I was planning to execute the test and look at the log statements reporting that there were no duplicate classes and then executing the same run but second time adding some redundant dependencies to the classpath. I was using JUnit 4.10 The version is important in this case.

I executed the unit test from the command line and I saw that there were no duplicate classes, and I was happy. After that I was executing the same test from Eclipse and surprise: I got 21 classes redundantly defined!

12:41:51.670 DEBUG c.j.c.ClassCollector - There are 21 redundantly defined classes.
12:41:51.670 DEBUG c.j.c.ClassCollector - Class org/hamcrest/internal/SelfDescribingValue.class is defined 2 times:
12:41:51.671 DEBUG c.j.c.ClassCollector -   sun.misc.Launcher$AppClassLoader@7ea987ac:file:/Users/verhasp/.m2/repository/junit/junit/4.10/junit-4.10.jar
12:41:51.671 DEBUG c.j.c.ClassCollector -   sun.misc.Launcher$AppClassLoader@7ea987ac:file:/Users/verhasp/.m2/repository/org/hamcrest/hamcrest-core/1.1/hamcrest-core-1.1.jar
...

Googling a bit I could discover easily that JUnit 4.10 has an extra dependency as shown by maven

$ mvn dependency:tree
[INFO] Scanning for projects...
[INFO]                                                                         
[INFO] ------------------------------------------------------------------------
[INFO] Building clalotils 1.0.0-SNAPSHOT
[INFO] ------------------------------------------------------------------------
[INFO] 
[INFO] --- maven-dependency-plugin:2.8:tree (default-cli) @ clalotils ---
[INFO] com.verhas:clalotils:jar:1.0.0-SNAPSHOT
[INFO] +- junit:junit:jar:4.10:test
[INFO] |  \- org.hamcrest:hamcrest-core:jar:1.1:test
[INFO] +- org.slf4j:slf4j-api:jar:1.7.7:compile
[INFO] \- ch.qos.logback:logback-classic:jar:1.1.2:compile
[INFO]    \- ch.qos.logback:logback-core:jar:1.1.2:compile
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 2.642s
[INFO] Finished at: Wed Sep 03 12:44:18 CEST 2014
[INFO] Final Memory: 13M/220M
[INFO] ------------------------------------------------------------------------

This is actually fixed in 4.11 so if I change the dependency to JUnit 4.11 I do not face the issue. Ok. Half of the mystery solved. But why maven command line execution does not report the classes double defined?

Extending the logging, logging more and more I could spot out a line:

12:46:19.433 DEBUG c.j.c.ClassCollector - Loading from the jar file /Users/verhasp/github/clalotils/target/surefire/surefirebooter235846110768631567.jar

What is in this file? Let’s unzip it:

$ ls -l /Users/verhasp/github/clalotils/target/surefire/surefirebooter235846110768631567.jar
ls: /Users/verhasp/github/clalotils/target/surefire/surefirebooter235846110768631567.jar: No such file or directory

The file does not exit! Seemingly maven creates this JAR file and then deletes it when the execution of the test is finished. Googling again I found the solution.

Java loads the classes from the classpath. The classpath can be defined on the command line but there are other sources for the application class loaders to fetch files from. One such a source is the manifest file of a JAR. The manifest file of a JAR file can define what other JAR files are needed to execute the classes in the JAR file. Maven creates a JAR file that contains nothing else but the manifest file defining the JARs and directories to list the classpath. These JARs and directories are NOT returned by the method getURLs(), therefore the (first version) of my little tool did not find the duplicates.

For demonstration purposes I was quick enough to make a copy of the file while the mvn test command was running, and got the following output:

$ unzip /Users/verhasp/github/clalotils/target/surefire/surefirebooter5550254534465369201\ copy.jar 
Archive:  /Users/verhasp/github/clalotils/target/surefire/surefirebooter5550254534465369201 copy.jar
  inflating: META-INF/MANIFEST.MF    
$ cat META-INF/MANIFEST.MF 
Manifest-Version: 1.0
Class-Path: file:/Users/verhasp/.m2/repository/org/apache/maven/surefi
 re/surefire-booter/2.8/surefire-booter-2.8.jar file:/Users/verhasp/.m
 2/repository/org/apache/maven/surefire/surefire-api/2.8/surefire-api-
 2.8.jar file:/Users/verhasp/github/clalotils/target/test-classes/ fil
 e:/Users/verhasp/github/clalotils/target/classes/ file:/Users/verhasp
 /.m2/repository/junit/junit/4.10/junit-4.10.jar file:/Users/verhasp/.
 m2/repository/org/hamcrest/hamcrest-core/1.1/hamcrest-core-1.1.jar fi
 le:/Users/verhasp/.m2/repository/org/slf4j/slf4j-api/1.7.7/slf4j-api-
 1.7.7.jar file:/Users/verhasp/.m2/repository/ch/qos/logback/logback-c
 lassic/1.1.2/logback-classic-1.1.2.jar file:/Users/verhasp/.m2/reposi
 tory/ch/qos/logback/logback-core/1.1.2/logback-core-1.1.2.jar
Main-Class: org.apache.maven.surefire.booter.ForkedBooter

$ 

It really is nothing else than the manifest file defining the classpath. But why does maven do it? Sonatype people, some of whom I also know personally are clever people. They don’t do such a thing just for nothing. The reason to create a temporary JAR file to start the tests is that the length of the command line is limited on some of the operating systems that the length of the classpath may exceed. Even though Java (since Java 6) itself resolves wildcard characters in the classpath it is not an option to maven. The JAR files are in different directories in the maven repo each having long name. Wildcard resolution is not recursive, there is a good reason for it, and even if it were you just would not like to have all your local repo on the classpath.

Conclusion

  • Do not use JUnit 4.10! Use something older or newer, or be prepared for surprises.
  • Understand what a classloader is and how it works, what is does.
  • Use an operating system that has huge limit for the maximum size of a command line length.
    Or just live with the limitation.

Something else? Your ideas?

Name of the class

In Java every class has a name. Classes are in packages and this lets us programmers work together avoiding name collision. I can name my class A and you can also name your class A so long as long they are in different packages, they work together fine.

If you looked at the API of the class Class you certainly noticed that there are three different methods that give you the name of a class:

  • getSimpleName() gives you the name of the class without the package.
  • getName() gives you the name of the class with the full package name in front.
  • getCanonicalName() gives you the canonical name of the class.

Simple is it? Well, the first is simple and the second is also meaningful unless there is that disturbing canonical name. That is not evident what that is. And if you do not know what canonical name is, you may feel some disturbance in the force of your Java skills for the second also. What is the difference between the two?

If you want a precise explanation, visit the chapter 6.7 of Java Language Specification. Here we go with something simpler, aimed simpler to understand though not so thorough.

Let’s see some examples:

package pakage.subpackage.evensubberpackage;
import org.junit.Assert;
import org.junit.Test;

public class WhatIsMyName {
	@Test
	public void classHasName() {
		final Class<?> klass = WhatIsMyName.class;
		final String simpleNameExpected = "WhatIsMyName";
		Assert.assertEquals(simpleNameExpected, klass.getSimpleName());
		final String nameExpected = "pakage.subpackage.evensubberpackage.WhatIsMyName";
		Assert.assertEquals(nameExpected, klass.getName());
		Assert.assertEquals(nameExpected, klass.getCanonicalName());		
	}
...

This “unit test” just runs fine. But as you can see there is no difference between name and canonical name in this case. (Note that the name of the package is pakage and not package. To test your java lexical skills answer the question why?)

Let’s have a look at the next example from the same junit test file:

	@Test
	public void arrayHasName() {
		final Class<?> klass = WhatIsMyName[].class;
		final String simpleNameExpected = "WhatIsMyName[]";
		Assert.assertEquals(simpleNameExpected, klass.getSimpleName());
		final String nameExpected = "[Lpakage.subpackage.evensubberpackage.WhatIsMyName;";
		Assert.assertEquals(nameExpected, klass.getName());
		final String canonicalNameExpected = "pakage.subpackage.evensubberpackage.WhatIsMyName[]";
		Assert.assertEquals(canonicalNameExpected, klass.getCanonicalName());		
	}

Now there are differences. When we talk about arrays the simple name signals it appending the opening and closing brackets, just like we would do in Java source code. The “normal” name looks a bit weird. It starts with an L and semicolon is appended. This reflects the internal representation of the class names in the JVM. The canonical name changed similar to the simple name: it is the same as before for the class having all the package names as prefix with the brackets appended. Seems that getName() is more the JVM name of the class and getCanonicalName() is more like the fully qualified name on Java source level.

Let’s go on with still some other example (we are still in the same file):

	class NestedClass{}
	
	@Test
	public void nestedClassHasName() {
		final Class<?> klass = NestedClass.class;
		final String simpleNameExpected = "NestedClass";
		Assert.assertEquals(simpleNameExpected, klass.getSimpleName());
		final String nameExpected = "pakage.subpackage.evensubberpackage.WhatIsMyName$NestedClass";
		Assert.assertEquals(nameExpected, klass.getName());
		final String canonicalNameExpected = "pakage.subpackage.evensubberpackage.WhatIsMyName.NestedClass";
		Assert.assertEquals(canonicalNameExpected, klass.getCanonicalName());		
	}

The difference is the dollar sign in the name of the class. Again the “name” is more what is used by the JVM and canonical name is what is Java source code like. If you compile this code, the Java compiler will generate the files:

  • WhatIsMyName.class and
  • WhatIsMyName$NestedClass.class

Even though the class is named nested class it actually is an inner class. However in the naming there is no difference: a static or non-static class inside another class is just named the same. Now let’s see something even more interesting:

	@Test
	public void methodClassHasName() {
		class MethodClass{};
		final Class<?> klass = MethodClass.class;
		final String simpleNameExpected = "MethodClass";
		Assert.assertEquals(simpleNameExpected, klass.getSimpleName());
		final String nameExpected = "pakage.subpackage.evensubberpackage.WhatIsMyName$1MethodClass";
		Assert.assertEquals(nameExpected, klass.getName());
		final String canonicalNameExpected = null;
		Assert.assertEquals(canonicalNameExpected, klass.getCanonicalName());
	}

This time we have a class inside a method. Not a usual scenario, but valid from the Java language point of view. The simple name of the class is just that: the simple name of the class. No much surprise.

The “normal” name however is interesting. The Java compiler generates a JVM name for the class and this name contains a number in it. Why? Because nothing would stop me having a class with the same name in another method in our test class and inserting a number is the way to prevent name collisions for the JVM. The JVM does not know or care anything about inner and nested classes or classes defined inside a method. A class is just a class. If you compile the code you will probably see the file WhatIsMyName$1MethodClass.class generated by javac. I had to add “probably” not because I count the possibility of you being blind, but rather because this name is actually the internal matter of the Java compiler. It may choose different name collision avoiding strategy, though I know no compiler that differs from the above.

The canonical name is the most interesting. It does not exist! It is null. Why? Because you can not access this class from outside the method defining it. It does not have a canonical name. Let’s go on.

What about anonymous classes. They should not have name. After all, that is why they are called anonymous.

	@Test
	public void anonymousClassHasName() {
		final Class<?> klass = new Object(){}.getClass();
		final String simpleNameExpected = "";
		Assert.assertEquals(simpleNameExpected, klass.getSimpleName());
		final String nameExpected = "pakage.subpackage.evensubberpackage.WhatIsMyName$1";
		Assert.assertEquals(nameExpected, klass.getName());
		final String canonicalNameExpected = null;
		Assert.assertEquals(canonicalNameExpected, klass.getCanonicalName());
	}

Actually they do not have simple name. The simple name is empty string. They do, however have name, made up by the compiler. Poor javac does not have other choice. It has to make up some name even for the unnamed classes. It has to generate the code for the JVM and it has to save it to some file. Canonical name is again null.

Are we ready with the examples? No. We have something simple (a.k.a. primitive) at the end. Java primitives.

	@Test
	public void intClassHasName() {
		final Class<?> klass = int.class;
		final String intNameExpected = "int";
		Assert.assertEquals(intNameExpected, klass.getSimpleName());
		Assert.assertEquals(intNameExpected, klass.getName());
		Assert.assertEquals(intNameExpected, klass.getCanonicalName());
	}

If the class represents a primitive, like int (what can be simpler than an int?) then the simple name, “the” name and the canonical names are all int the name of the primitive.

Just as well an array of a primitive is very simple is it?

	@Test
	public void intArrayClassHasName() {
		final Class<?> klass = int[].class;
		final String simpleNameExpected = "int[]";
		Assert.assertEquals(simpleNameExpected, klass.getSimpleName());
		final String nameExpected = "[I";
		Assert.assertEquals(nameExpected, klass.getName());
		final String canonicalNameExpected = "int[]";
		Assert.assertEquals(canonicalNameExpected, klass.getCanonicalName());
	}

Well, it is not simple. The name is [I, which is a bit mysterious unless you read the respective chapter of the JVM specification. Perhaps I talk about that another time.

Conclusion

The simple name of the class is simple. The “name” returned by getName() is the one interesting for JVM level things. The getCanonicalName() is the one that looks most like Java source.

You can get the full source code of the example above from the gist e789d700d3c9abc6afa0 from GitHub.

Named parameters in Java

Creating a method that has many parameters is a major sin. Whenever there is need to create such a method, sniff in the air: it is code smell. Harden your unit tests and then refactor. No excuse, no buts. Refactor! Use builder pattern or even better use Fluent API. For the latter the annotation processor fluflu may be of great help.

Having all that said we may come to a point in our life when we face real life and not the idealistic pattern that we can follow in our hobby projects. There comes the legacy enterprise library monster that has the method of thousands parameters and you do not have the authority, time, courage or interest (bad for you) to modify … ops… refactor it. You could create a builder as a facade that hides the ugly API behind it if you had the time. Creating a builder is still code that you have to unit test even before you write (you know: TDD) and you just may not have the time. The code that calls the monstrous method is also there already, you just maintain it.

You can still do some little trick. It may not be perfect, but still something.

Assume that there is a method

public void monster(String contactName, String contactId, String street, String district,
                    ...
                    Long pT){
...
}

The first thing is to select your local variables at the location of the caller wisely. Pity the names are already chosen and you may not want to change it. There can be some reason for that, for example there is an application wide naming convention followed that may make sense even if not your style. So the call

monster(nm, "05300" + dI, getStrt(), d, ... , z+g % 3L );

is not exactly what I was talking about. That is what you have and you can live with it, or just insert new variables into the code:

String contactName = nm;
String contactId = "05300" + dI;
String street = getStrt();
Street district = d;
...
Long pT = z+g % 3L;
monster(contactName, contactId, street, district, ... ,pT );

or you can even write it in a way that is not usual in Java, though perfectly legal:

String contactName, contactId, street, district;
...
Long pT;
monster(contactName = nm, contactId = "05300" + dI, street = getStrt(), district = d, ... ,pT = z+g % 3L );

Tasty is it? Depends. I would not argue on taste. If you do not like that, there is an alternative way. You can define auxiliary and very simple static methods:

static <T> T contactName(T t){ return T;}
static <T> T contactId(T t){ return T;}
static <T> T street(T t){ return T;}
static <T> T district(T t){ return T;}
...
static <T> T pT(T t){ return T;}

monster(contactName(nm), contactId("05300" + dI), street(getStrt()(, district(d), ... ,pT(z+g % 3L) );

The code is still ugly but a bit more readable at the place of the caller. You can even collect static methods into a utility class, or to an interface in case of Java 8 named like with, using, to and so on. You can statically import them to your code and have some method call as nice as

doSomething(using(someParameter), with(someOtherParameter), to(resultStore));

When all that is there you can feel honky dory if you answer the final question: what the blessed whatever* is parameter pT.

(* “whatever” you can replace with some other words, whichever you like)

Logical thinking…

“The fact that logical thinking is part of the job description of a programmer does not imply that others should not practice that.”

This was a very witty comment on a Hungarian newsletter focusing on Java. The actual issue was about how to handle a SOAP message that is 1.8GB and has to be handled once a day. The issue was around checking the correctness of the message against some predefined XSD and then parsing the content and do some functionality controlled by the content.

This is a nice task and though I had no practical experience with a SOAP message of that huge size I recommended to do some benchmark on a machine which fits more or less the size of the memory and CPU of the production machine no matter what software stack is selected. These days a machine with 16GB or more memory is not so rare and one may be able to handle the 1.8GB SOAP in memory even if the overhead of JVM and Java were huge. (Which I do not say is, but it could be. If you are interested: you can measure and publish an article about that, different story.)

Some of the commenters followed a different pattern. They, the cleverer ones, suggested that perhaps the developer has to ask the business analyst (BA) about the details. It may not necessarily be the best solution from the business point of view to transfer such huge beasts over SOAP. What was the business reason to use SOAP? What was the business reason to use XML? What is the business benefit? What are the business goals? Business goals are rarely related to SOAP or XML. They are tools one (several) level lower in the solution chain.

When the business analyst gets the requirements from the business people, she should not just blindly pass it on. We, developers expect them to think a bit of technology. They are the bridge between the business people and the developers. Some of the BAs are very experienced technically and are eager to learn. Probably they are the ones that are also eager to learn on the other side: how the business work. Some BAs are less technical but still do their job. A SOAP message of 1.8GB should ring the warning bell even for a BA? Or not?

Don not hit sysadmins with NPE!

My opinion is that having a null pointer exception and getting it into the log without catching, handling and re-throwing it in another exception is not inherently bad. If we can do nothing better then it should not be a problem. The thing is that in practice almost always there is a better way to handle the situation.

Recently I was pair programming and we debugged some web code. We could not get through the authentication filter on the development environment and the authentication was not really in scope for the debugging so we decided to switch that totally off for the time. The next thing was an NPE. We looked at the code and we saw at the line something like

principal = SecurityContextHolder.getContext().getAuthentication().getPrincipal();

It was obvious: since the authentication was switched off the result of getAuthentication() was null, and therefore calling getPrincipal() on null caused the NPE. Should we modify the code to check if there is authentication information and throw a different exception? What would be the benefit to do that? The code runs slower, gets bigger (and bigger code is harder to maintain). And the NPE and the code source together are obvious. There is no need to change.

On second thought the NPE may not be that obvious for a support guy operating the code somewhere at the other side of this rotating ball. He may not have handy access to the source code and may not understand easily that the root cause for the NPE was the misconfiguration of the authentication layer. He/she has to start the server, it does not work and calls the support, raises a ticket. You as a responsible developer being at the farthest end of the support line may woke up during your finest sleep just to tell him/her that the authentication layer was misconfigured. Than you regret that you could have told it in the logs and in the exception.

Authentication auth = SecurityContextHolder.getContext().getAuthentication();
if( auth == null ){
  throw new BadConfigurationException("The authentication layer is not properly configured SecurityContextHolder.getContext().getAuthentication() returned null."
}
principal = auth.getPrincipal();

Not that big deal and pays back on the long run.

Moral: What seems to be obvious for the developer during development may not be that easy for the system administrator. Admins are not familiar with the code, may not have access to source code, have less experience in programming. On the other hand they have great experience setting up and running systems. It is a hard work, they deserve proper log messages and talkative exceptions.

Follow

Get every new post delivered to your Inbox.

Join 935 other followers