Monday, 1 September 2008

Java semantics

As part of learning Scala, I have recently gone back and looked at Java semantics. I am amazed at how complicated things have become. I seem to recall that at the time that I first learned Java, there was:

  • java.lang.Object
  • java.lang.Class

and some ugly runts called primitives (byte, short, int, long, float, double, boolean, char) which had big brother equivalents. Objects had fields, methods, and contstructors. Any of these could be public, private, or protected. Fields and methods could be static. There was some syntax for dealing with:

  • java.lang.reflect.Array

In fact, the situation was more complicated that this but to write a program that would generate stubs of a class file, the above was sufficient.

Today matters are more complicated. java.lang.Class is now a typed (java.lang.class<T>) and implements:

  • java.lang.reflect.Type
  • java.lang.reflect.AnnotatedElement
  • java.lang.reflect.GenericDeclaration

Type has four subinterfaces

  • java.lang.reflect.GenericArrayType
  • java.lang.reflect.ParameterizedTypee
  • java.lang.reflect.TypeVariable<D extends GenericDeclaration>
  • java.lang.reflect.WildcardType

There is syntactic sugar both for enumerations (which have the initially confusing declaration ENUM<E extends Enum<E>>) and for java.lang.annotation.Annotation which has implementing classes

  • BindingType
  • ConstructorProperties
  • Deprecated
  • DescriptorKey
  • Documented
  • Generated
  • HandlerChain
  • Inherited
  • InitParam
  • MXBean
  • Oneway
  • Override
  • PostConstruct
  • PreDestroy
  • RequestWrapper
  • Resource
  • Resources
  • ResponseWrapper
  • Retention
  • ServiceMode
  • SOAPBinding
  • SOAPMessageHandler
  • SOAPMessageHandlers
  • SupportedAnnotationTypes
  • SupportedOptions
  • SupportedSourceVersion
  • SuppressWarnings
  • Target
  • WebEndpoint
  • WebFault
  • WebMethod
  • WebParam
  • WebResult
  • WebService
  • WebServiceClient
  • WebServiceProvider
  • WebServiceRef
  • WebServiceRefs
  • XmlAccessorOrder
  • XmlAccessorType
  • XmlAnyAttribute
  • XmlAnyElement
  • XmlAttachmentRef
  • XmlAttribute
  • XmlElement
  • XmlElementDecl
  • XmlElementRef
  • XmlElementRefs
  • XmlElements
  • XmlElementWrapper
  • XmlEnum
  • XmlEnumValue
  • XmlID
  • XmlIDREF
  • XmlInlineBinaryData
  • XmlJavaTypeAdapter
  • XmlJavaTypeAdapters
  • XmlList
  • XmlMimeType
  • XmlMixed
  • XmlNs
  • XmlRegistry
  • XmlRootElement
  • XmlSchema
  • XmlSchemaType
  • XmlSchemaTypes
  • XmlTransient
  • XmlType
  • XmlValue

Oh my.

Posted by james at 2:47 PM in Java

Friday, 2 November 2007

Java closures

Over at Neal Gafter's blog, there is a first prototype of what closures in Java. Neat!

I thought I would give it a try and initially started doing this with arrays but ended up in a world of pain with the generics. I realize that it would have cost significant backward compatibility problems but I begin to wonder if generics should have been integrated into the class structure (e.g. Set<String> the same as Set); then again I do not have a large code base to maintain. Anyway, here is a silly example inspired by Lisp.

import java.util.List;
import java.util.LinkedList;

public class Mapcar {
    public static <T,S> List<S> mapcar(Iterable<T> domain, {T=>S} block)
    {
	List<S> range = new LinkedList<S>();
	for (T x: domain) {
	    range.add(block.invoke(x));
	}
	return range;
    }

    public static <T,S> List<S> mapcar(T[] domain, {T=>S} block)
    {
	List<S> range = new LinkedList<S>();
	for (T x: domain) {
	    range.add(block.invoke(x));
	}
	return range;
    }

    public static void main(String args[]) {
	for (String x:mapcar(args, {String x => "string "+x+" has length "+x.length()})) {
	    System.out.println(x);
	}
    }
}

Note that the first instance is not actually called... I just put it in for completeness. I guess the fact that T[] does not implement Iterable<T> is part of generics not in the class structure issue.

There are some very nice examples of closures at Ricky's technical blog.

Posted by james at 4:04 PM in Java

Tuesday, 30 October 2007

Java Surprises

It has been said that you can write Fortran in any language. After writing Java program for more year than I care to remember, I've been going back and looking at some of the details. In particular

  • How are anonymous inner classes different from true closures?
  • Are continuations possible?
  • Are lambda functions possible via generics?

These are all features that I dearly miss from Scheme. Anyway, here is my latest surprise.

net.unsyntax.factory.Foo

package net.unsyntax.factory;

public class Foo {
	public String name="Foo     ";

	public Foo() {}
	
	public static Foo create() {
		return new Foo();
	}
}

net.unsyntax.factory.SonOfFoo

package net.unsyntax.factory;

public class SonOfFoo extends Foo {
	public String name="SonOfFoo";
	
	public SonOfFoo() {}

	public static Foo create() {
		return new SonOfFoo();
	}
}

net.unsyntax.factory.TestFoo

package net.unsyntax.factory;

public class TestFoo {
	private static void report(Foo foo) {
		System.out.println("in call "+foo.getClass().getName()+" has name "+foo.name);
	}

	public static void main(String[] args) {
		{
			Foo foo = SonOfFoo.create();
			System.out.print("locally name is " + foo.name +" but ");
			report(foo);
		}
		{
			SonOfFoo foo = (SonOfFoo) SonOfFoo.create();
			System.out.print("locally name is " + foo.name +" but ");
			report(foo);
		}
	}
}

Result

$ java  net.unsyntax.factory.TestFoo
locally name is Foo      but in call net.unsyntax.factory.SonOfFoo has name Foo     
locally name is SonOfFoo but in call net.unsyntax.factory.SonOfFoo has name Foo     
$ 

Huh?

Posted by james at 5:57 PM in Java

Friday, 22 June 2007

Servlet deployment with ant

I recently was trying to ant to deploy a servlet with little success. In the end it turned out to be that the tomcat user on my machine did not have permission to read my home directory. It have the error "FAIL - Failed to deploy application at context path". As I was hunting down the problem, I was struck with the lack of complete examples of how to do this. There are many bits and pieces but if something is going wrong it is hard to find a complete example that should work.

Here is a tarball of a complete project with a HelloWorld servlet (only the password and user account have been changed to protect the innocent). After deployment, it should be available at http://localhost:8080/example/HelloWorld (assuming tomcat is running on localhost:8080).

Posted by james at 10:04 PM in Java

Friday, 9 March 2007

Parallel assignment in Java 1.5

I have often been frustrated by the lack of parallel assignment in Java. The introduction of generics in Java 1.5 permits a version of this capability although there is no way to add syntax to support the feature.

We begin by defining a pair type (though the method works for n-tuples)

package net.unsyntax.util;

public class Pair <T1, T2> {
    private T1 first;
    private T2 second;

    public Pair(T1 first, T2 second) {
        this.first = first;
        this.second = second;
    }

    public T1 getFirst() {
        return this.first;
    }

    public T2 getSecond() {
        return this.second;
    }
}

which we can then use as follows

package net.unsyntax.util;

public class PairTest {
	public Pair<String,Integer> foo() {
		return new Pair<String, Integer>("Heaven",17);
	}
	
	public void main (String argv[]){
		Pair<String,Integer> foo = foo();
		
		System.out.println(foo.getFirst());
		System.out.println(foo.getSecond());
	}
}

Note that the example also shows the Java 1.5 autoboxing feature.

Posted by james at 10:35 AM in Java
« January »
SunMonTueWedThuFriSat
    123
45678910
11121314151617
18192021222324
25262728293031