Devoxx – Day 4
The day started with a second keynote in room 8. Stephan Janssen talked for a few minutes and asked everyone who hasn’t voted to vote on the whiteboards for Java 7 features. Then Joshua Bloch started his talk by showing some optical illusions and he said that, like optical illusions, things in Java are not what they seem to be sometimes. He then explained what i new in his Effective Java book.
What new in effective java
- chapter 5: generics
- chapter 6: enums and annotations
- one or more changes on all other java 5 language features
- threads chapter renamed concurrency
Generics are invariant, this means that a List<String> is not a subtype of a List<Object>. It’s good for compile time safety, but inflexible. That’s why the added wildcards. It’s easy to use wildcards if you remember the PECS – Producer Extends Consumer Super
- For a T producer, use Foo<? extends T>
- For a T consumer, use Foo<? super T>
This only applies to input parameters. Don’t use wildcards for return types. Of course there are rare exceptions to this rule.
For the rest of his talk Joshua went through some examples from his Effective Java book and explained the gotchas o the seemingly easy to understand code.
Next one on was Mark Reinhold which talked about the modular Java platform. He started by explaining why a “Hello World” programme in python is faster than a “Hello World” programme in Java. the answer is simple, Java needs to load 332 classes (it needs to resolve all reference, do the verification etc) in order to run the “Hello World”. By modularising the JDK will force the separate components to identify themselves and reduce the number of classes that are needed to be loaded, thus reducing loading and run time.
Then he talked about the JSR 294 (and also mentioned that JSR 277 is not dead, it’s just on hold). The rest of the time was spent on talking about the project jigsaw.
The requirements of a perform module system
- integrate with jvm
- integrate with the language
- integrate with native packaging
- support multi-module packages
- support “friend: modules
In the JDK there will be added new features from Sun and other parties.
Big features from Sun
- JSR 294 + jigsaw
- JSR 292 (VM support for dynamic languages)
- JSR 203 (more new IO APIs)
- JSR TBD: small language changes.
- forward-port 6u10 features
- java kernel, quickstarter, new plug-in, etc
- safe re-throw
- null-dereference expressions (this one he thinks is already in)
Small featues from Sun
- SCTP (Stream Control Transmission Protocol)
- Sockets Direct Protocol
- upgrade class-loader architecture
- method to close a UrlClassLoader
- unicode 5.0 support
- XRender pipeline for Java 2D
- swing updates
- JXLayer, DataPicker, CSS styling – maybe
Fast features from sun
- Yet more HotSpot run-time compiler enhancements
- G1 garbage collector
- compressed-pointer 64-bit VM
- MVM-lite – maybe (MVM – Multiple Virtual Machines)
Features from other:
- JSR 308: annotations on java Types (allows you to put annotation in more places than today) (see photo for example)
- Prof. Michael Ernst. Mahmood Ali
- concurrency and collections updates
- Doug Lee, John Bloch et al
- Fork/Join framework
- Phasers – Generalized barriers
- LinkedTransferQueue – Generalized queue
- Fences – Fine-grained read/write ordering
Features not in 7 (at least some of them)
- other language features
- reified generic types
- operator overloading
- BigDecimal syhtax
- First-class properties
- JSR 295: beans binding
Jdk 7 will be released early 2010
The talk started with Brian Goetz explaining what a virtual machine is; a software implementation of a specific computer architecture. This computer architecture could be a real hardware architecture or a fictitious one.
there are several system virtual amchines that emulate a complete computer system (CMWare, VirtualBox, VirtualPC, Parallels)
Virtual machines isolate the hosted application from the host system (a virtual machine appears as an ordinary process in the host system)
Virtual machines isolate the host system from the hosted application (a virtual machine acts as an intermediary between hosted application and host system)
Virtual macines provide a higher level of abstraction
- sensible layer for portability across underlying platforms
- abstracts away low-level architctural considerations
- size of register set, hardware word size
- 1990s buzzword ANDF
Nowadays virtual machines win as compilation targets
- Today it is silly for a compiler to target actual hardware
- much more effective to target a vm
- writing a native compiler is a lots more work
- languages need runtime support
- C runtime is tiny and portable (and wimpy)
- more sophisticated language runtimes need
- memory management
If a virtual machine doesn’t provide the feature you need you have to either write it yourself or do without them. If the virtual machine does provide them you will use them which is less work for you and makes your programming language better (eg gc makes the programmign easier and better).
Targeting existing vistual machines also reuses libraries and tools, debugegers, IDE, profilers, management tools etc.
Vistual machine-based facilites become common across languages (Java code can call JRuby code, Java objects and Jython objects are garbage-collected together).
The best reason to target a virtual machine as a compilation target is the HotSpot JIT compiler. The compiler can generate bytecode and feed it to hotspot. A lot of optimisation that the dynamic compiler can do is harder than the standard compiler since it has to go through loads more info that’s not available to standard compilers. A dynamic compiler can use adaptive and speculative techniques (compile optimistically, deoptimise when proven necessary). Targeting a VM allows compilers to generate “dumb” code and let the dynamic compiler to optimise it (the VM will optimise it better at runtime anyway).
There are loads of VMs out there (Java VM, .NET CLR, SmallTalk, Perl, Python, YARV, Valgrind, Lua, Dalvik, Flash, Zend etc). There are so many because each one was designed to solve specific problem.
- stack-based programmes representation and execution
- core instructions
- data types: objects, arrays, eight primitive types
- object model: single inheritance with interfaces
- dynamic linking
- untrusted code from the web motivates static typechecking (at load-time)
- symbolic resolution dynamically (base classes are not fragile in the JVM)
We see some common patterns in a JVM like objects, signed integers, single inheritance, static typechecking etc. These features can actully form a VM for many programming languages, many of them unknow to most people (phobos, Piccola, SALSA, ObjectScript, FScript, Anvil, Smalltalk etc). Early enough (1997) in the JVM specification they stated that the JVM does not know anything about the Java programming language but only about the bytecode.
Some features are easy to implement for a universal VM (like checked exceptions in Java) but some others are very dicfficult to implement effectively (open classes in Ruby, alternate numeric towers a la Scheme).
JSR 292 often called the “invokedynamic” JSR because it originally proposed a specific bytecode for method invocation but the scope has widened since then. The work curently that goes into JSR 292 includes
invokedynamic bytecode (allows the language runtime to work hand in had with the jvm on method selection), method handles (many languages have constructs like closures, classe are too heavy as container for a single block of code), interface injection (add new methods and types to existing classes).
Virtual method invocation in java
- the only dynamism for the method invocation is for the receiver
- different implementation os size() for ArrayList vs LinkedList
- this is called single dispatch. Java;s method selection algorithm doesn’t (and can’t) consider the runtime types of arguments given
- invokevirtual Foo.bar: (int)int
- the jvm looks for bar: (int) int in the class of the receiver (the receiver is reference dform the stack)
- if the receiver’s class doesn’t have this method, the JVM recurses up to its superclass…
- repeated recursive method lookup makes invocation slow
- fortunatelly, this can often be heavilly optimized
- divirtualize monomorphic methods
- if vm can prove there is only one target method body, then invocation turns into a single jump
- can then inline the mehod call avoiding invocation overhead
- bigger basic blok enables further optimizaroins
- inline cachng
- figure out th emost like receiver type for a call site and cache it
- optimizes for th emost likely case(s)
But compiling dynamic languages directly to JVM is tricky. Many dynamic languages have no receiver type, no static argument type and maybe the return type isn’t even boolean (in the code below), maybe it’s the type of x or y.
function max(x, y)
if x > y then x else y;
Dynamic typed method invocation
- dynamic is a magic type
- no such type in the jvm today
- but if the jvm had Dynamic, invokeinterface is almost flexible
How can a language runtime manage dynamic invocation?
- creative solutions have been proposed
- could define an interface for each possible method signature
- complex, fragile, expensive
- could define an interface for each possible method signature
- could use reflection for everything
- use “inline caching” trick to cache method objects for specific combinations of argument types
- but heavyweight and slow if you use it for every method call
- it’s easy to conclude “the jvm isn’t a match for dynamic languages”
A little help goes a long way
- it turns out that the static type checking is closer to the surface than it first appears
- the big need: first-class language specific method resolution
- so the lanfiage can identify the call target
- but then get out of the VM’s way
- this is the rationale behind invokedynamic
The first time the jvm sees an
invokedynamic instruction it calls a bootstrap method which does all the work. Bootstrap chooses the ultimate method to be called. The vm associates that method with the
invokedynamic instruction. The next time the jvm sees the instruction it jumps oto the previously chosen method immediately.
Putting it all together
- jvm method invocatio is still sttically typed
- the ultimate method invoked is arbitrary
- depends on the language rules
- could even have a different name than in the instructions
method handles are composable
- and adapter method handle takes another method handle and executes code before and after invoking it.
- endless applications!
- coercing types of individual arguments
- java.lang.String -> org.juby.RubyString (different encodign)
- boxing all argument sinto a boxing array
- pre-allocating stack frames
- prepare thread-specific context
- dynamically typed programs look like self modifying code
- generally, self modifying code is dangerous and hard to optimize
- idea: don’t restructure classes, just relabel themselves
- interface injection: the ability to modify old classes just enough for them to implement new interfaces
- superinterfaces are cheap for jvm object
- invokeinterface is fast these days
- if an interface-dependent operation is about to fall, call a static injector method to bind an interface to the object and provide MethodHandles for the interface’s methods.
- one change only for the injector to say yes!
In this session the room was literally full. There were people sitting on the corridor and on the floor near the speaker. Unfortunatelyl I didn’t find a place to sit and I was standing (at some point I sat down) therefore I didn’t get any notes. Things I remember from the session:
don’t do premature optimization, even if it’s very tempting. Never do it. Never take care of performance at an early stage, only do it at a later stage.
Good programmers write good performing code. They might be functional bugs, this is acceptable, but there shouldn’t be many performance problems.
Performance management is diffcult because it’s difficult to find performance problems. performance is a moving target, it works today but it might not work tomorrow. Even testing does not prevent you from having performance problems.
I met Frank at the jug leaders and speakers dinner on Tuesday and I really wanted to see his talk.
Frank talked about his pushTotest tool which is an open source tool sthat helps you test web services and web applications. With pushToTest you can surface issues quickly, you can create automated functional tests and have SLA compliance monitoring and provides an integrated environment.
The reasons behind having an integrated environment are simple
- organizations require test and operational management
- Ajax commerical testing tools not keeping up
- where is the test tool for GWT, YUI, Dojo, Appcelarator?
- organisations benefit from integration test and operational management
- repurpose tests among developers, QA, ops
- makes build + test-first possible
- very agile, very rapid, bvery inexpensive
Then a demo followed with some screenshots and a walkthrough some source code.
Some otes I wrote down
benefits of type qualifiers
- improve documentation
- find bugs in programmes
- guarantee the absence of errors
- @NonNull: null dereference
- @Internal: incorrect equality tests
- @ReadOnly: incorrect mutation and side-effects
- Many other simple checkers
- security, encryption, access control
- format/encoding, SQL
- checkers designed as compiler plugins and use familiar error messages
A nullness and mutation demo followed
Checkers are fearful:
- full type systems, assignment, overriding
- polymorphic (Java generics)
- flow sensitive type qualifier inference
Checkers are effective
- scales to > 200.000 LOC
- each checker found errors in each code base it ran on
Checkers are usable:
- tool support javac, Ant, Eclipse, NetBeans
- not too verbose
- @NonNull: 1 annotation per 75 lines
- @Interned: 124 annotation in 220 KLOC revealed 11 errors
- fewer annotations in new code
- inference tools: nullness, mutability
Another demo followed at this point.
- pluggable type checkers
- featureful, effective and usable
- programmers can
- find and prevent bugs
- obtain guarantees that program isfree of certain errors
- create custom qualifiers and type checkers
If you want to learn more have a look here: http://pag.csail.mit.edu/jsr308