What I Learnt about JavaFX Today

2 Comments

In case you haven’t heard, JavaFX 2 is the new Desktop / web / client framework for Java. It’s had a considerable overhaul since JavaFX 1 (which was frankly not that impressive). Out has gone the custom scripting language, and instead you can write it using standard Java and an XML-based language for the actual UI presentation.

So today, a friend and I got together at one of our places to teach ourselves a bit of JavaFX. Here’s what we learned, starting with some of the yak-shaving we had to do:

  1. First of all, install the JavaFX developer preview – get it here
  2. You have to unzip it, and place the resulting directory somewhere sensible, chown’d to root.
    • I put it in /usr/local/javafx-sdk2.1.0-beta/
  3. Next, you’ll want an IDE to go with that
    • Netbeans is the IDE which is the most advanced and usable with JavaFX 2
    • You want Netbeans 7.1 RC2
  4. To get this to install on a Mac, you need JavaForMacOSX10.7.dmg – no lower version of official Apple Java will do, and an OpenJDK build won’t work either (even if it’s the correct version or higher)
  5. Once it’s installed, Netbeans will work fine with other JREs (I was mostly running it against the Java 7 Developer Preview)
  6. To start new JavaFX projects, you need to tell NetBeans where to find JavaFX. For this, you need to create a new JavaSE platform profile, and add the JavaFX dependencies in manually.

Once it was installed, we started working with JavaFX properly. Our project for the day was to try to replicate some of Victor Grazi’s concurrency animations in JavaFX – both to teach ourselves the JavaFX technology, and also create some teaching tools as outputs.

  • JavaFX uses Application as the main class to subclass
  • The API docs are here

If you’ve done any Flex development, JavaFX will seem very natural. E.g.

  1. The FXML file provides the UI and layout
  2. The top level FXML element has a fx:controller attriubte, which defines the Control for this View
  3. FXML elements are bound to members contained in the controller class which have been annotated with the @FXML annotation
  4. The fx:id property is used to define the name of the member that is being bound to the FXML element
  5. Binding also occurs to methods. E.g. buttons bind use an onAction handler, like this: onAction="#isFutureDone"
  6. The #methodName syntax is used to say which method should be called when the button is pressed.

From this it’s very easy to get started with building up a basic application. Some things that we found:

  1. The UI thread can be quite easy to tie up. Don’t ever call a blocking method directly from the Control object, as triggering this code path on the UI thread will cause the display to hang.
  2. Be careful of exception swallowing.
  3. If you have a method in an object which is updating a UI element, but which is not annotated with @FXML, then you seem to need to call requestLayout() on the UI element after updating it. We’re not sure we got to the bottom of why – please enlighten us if you know why.
  4. The framework seems to use custom classloading to transform the FXML file into a “scene graph” of objects, seemingly a bit like how Spring does it.

On the whole, we were quite impressed with our short hack session. The APIs seem clean, and the overall design of the framework seems sound. There were a few stability issues, but this is bleeding-edge tech on Mac – both the JDK and the JavaFX runtime are Developer Previews.

We’ll definitely be back to do some more with JavaFX, and look forward to seeing it mature and become a fully-supported OSS framework for client development in Java.

Did you like this? Share it:

The OpenJDK as the default Java on Linux

7 Comments

Hi All,  (this post is x-posted from Martijn’s personal blog and the ljc blog)

Recently I’ve received a bunch of private correspondence from people confused/worried over the change in the default Java packaging for Linux. For many Linux distributions, the official Sun/Oracle version of Java has been packaged up as the default Java for the platform. However, due to a recent licensing change, this will no longer be the case! So, is this a positive or a negative thing for the Java and open source ecosystem? Read on for my take on it :-)  

Background

Dalibor Topic announced that With Java SE 7 and JDK 7 being released, and with OpenJDK as the official Java SE 7 reference implementation, that it was finally time to retire the non open source “Operating System Distributor License for Java” (DLJ).

What does it mean for me?

The knock on effect of this is that Linux distributions will on longer package Oracle’s Java (== OpenJDK wrapped up in some proprietary bits and pieces) as the default Java. This can/will cause problems for some Java users initially as there are a smattering of bugs (especially in the Swing UI libs) still left in the OpenJDK that affect programs like PCGen. However, some Linux distributions had already taken this path some years ago, most notably Ubuntu and the last remaining bugs are being cleaned up pretty quickly.

Positive or Negative?

Overall, I think this is a positive step in the right direction for free and open Java on Linux platforms. This sentiment was welcomed by well known open source advocate Simon Phipps in a twitter post. The fact the the OpenJDK is now the reference implementation (combined with efforts to open up the issue tracker for the OpenJDK) means that means that a vast host of Java/Linux end users can now directly improve ‘official Java’ for all of us.

I want the Oracle version!
Linux users who need to use the proprietary parts of the Oracle JDK 6 or Oracle JDK 7 binaries can of course as usual simply get the gratis download at http://oracle.com/java under the same terms as users on other platforms. However, if it is due to a ‘bug’ that is discovered I strongly encourage those users to submit a bug report to the OpenJDK project, so that any issues can be fixed for all of us.


Opinions and further comment is welcome!

Did you like this? Share it:

Manipulating Files in Java 7

7 Comments

Manipulating Files in Java 7

The following is a modified snippet from a draft of The Well-Grounded Java Developer. It gives you a quick taster of how much easier it is to manipulate files in Java 7 than in previous versions. By using the new Files class and its many utility methods, you can perform the following operations on files with only a single line of code:

  • Create
  • Delete
  • Copy
  • Move/Rename

TIP A quick note on Path. This post assumes you have some passing familiarity with the new Java 7 Path class, if not here’s a quick introduction! Path is the logical abstraction of a location on the file system, e.g.  c:\ is a Path as is ../foobar.txt

Let’s start by looking at the creation and deletion of files.

Creating and Deleting files

By using the simple helper methods in the Files class you can create files and delete them easily as well.

TIP If you are running the code snippets in this section, replace the actual paths with ones that match your file system!

The following code snippet shows basic file creation, using the Files.createFile(Path target) method.

Path target = Paths.get("D:\\Backup\\MyStuff.txt");
Path file = Files.createFile(target);

More often than not you want to specify some file attributes on that file for security purposes as well as knowing whether the file is being created for the purpose of  reading and/or writing and/or executing. As this is file system dependent, you need to utilise a file system specific file permissions class and its helper.

For example, PosixFilePermission and PosixFilePermissions for a POSIX compliant file system. An example of setting read/write for the owner-group-all in a POSIX file system is as follows.

Path target = Paths.get("D:\\Backup\\MyStuff.txt");
Set<PosixFilePermission> perms
    = PosixFilePermissions.fromString("rw-rw-rw-");
FileAttribute<Set<PosixFilePermission>> attr
    = PosixFilePermissions.asFileAttribute(perms);
Files.createFile(target, attr);

The java.nio.file.attribute package contains a list of provided FilePermission classes. File attribute support is also covered in further detail in chapter 2 of The Well-Grounded Java Developer.

WARNING When creating files with specific permissions, do be aware of any umask restrictions or restrictive permissions that the parent directory of that file is enforcing. For example, you may find that even though you specify rw-rw-rw for your new file, it is actually created as rw-r–r– due to these restrictions.

Deleting a file is a bit simpler and is performed by the simple Files.delete(Path) method.

Path target = Paths.get("D:\\Backup\\MyStuff.txt");
Files.delete(target);

Next up a quick overview on copying and moving files in a file system.

Copying and Moving files

By using the simple helper methods in the Files class you can perform your copy and move operations with ease. The following code snippet showcases a basic copy, using the Files.copy(Path source, Path target) method.

Path source = Paths.get("C:\\My Documents\\Stuff.txt");
Path target = Paths.get("D:\\Backup\\MyStuff.txt");
Files.copy(source, target);

More often than not you want to specify some options with the copy operation. In Java 7 you can use the StandardCopyOption enum to specify these options. The next example uses an overwrite (that is, replace existing) option.

import static java.nio.file.StandardCopyOption.*;

Path source = Paths.get("C:\\My Documents\\Stuff.txt");
Path target = Paths.get("D:\\Backup\\MyStuff.txt");
Files.copy(source, target, REPLACE_EXISTING);

Other copy options include COPY_ATTRIBUTES (copies over the file attributes) and ATOMIC_MOVE (ensures that both sides of a move operation succeed or the operation gets rolled back).The move operation is very similar to the copy operation and is executed using the atomic Files.move(Path source, Path target) method.

Again you typically want some copy options to go with that move, so you can use the Files.move(Path source, Path target, CopyOptions...) method (note the use of varargs).

In this case we want to keep the attributes of the source file when we move it as well as overwriting the target file (if it exists).

import static java.nio.file.StandardCopyOption.*;

Path source = Paths.get("C:\\My Documents\\Stuff.txt");
Path target = Paths.get("D:\\Backup\\MyStuff.txt");
Files.move(source, target, REPLACE_EXISTING, COPY_ATTRIBUTES);

As you can see, the new NIO.2 API for file manipulation is simple to use, we hope you enjoyed this little taster and our apologies for the long wait between posts!

Did you like this? Share it:

Why Ben has been nominated for the Java SE/EE Executive Committee

No Comments

As many of you will have heard, Ben will be representing the London Java Community as a nominee for one of the open seats on the Java SE/EE executive committee!

This is a great opportunity for a Java User Group to have a direct say in the future of Java 8, 9 and the overall ecosystem. I know Ben will be a great representative for the LJC and for all Java developers around the world.

The LJC is trying to get all questions/responses in one place, so for more more details see http://bit.ly/mEv7YQ

Cheers,
Martijn

Did you like this? Share it:

Ben and Martijn are interviewed at Javaworld

No Comments

The interview is live here

Did you like this? Share it:

Some insights from Oracle on the their plans for Java

No Comments

Ben Evans and I recently spoke at the Scandinavian Developers Conference on Java 7 and polyglot programming on the JVM. We also had a fun afternoon on a panel discussing “Whether the community or the corporations will control Java in the future”. That discussion probably deserves it own blog post, but more interestingly we spent a long time talking to Henrik Stahl from Oracle.

Henrik is Oracle’s director of Java platform strategy – and an official spokesperson from Oracle, able to pronounce on behalf of Oracle regarding Java. Henrik was able to give us the following insights (some of which you may have heard before):

  • Oracle is very committed to Java and sees it as essential to their future.
  • An open, vibrant community is an essential part of that future, in fact it’s the community that’ll determine what standard technologies and techniques should go into the std platform (SE/EE).
  • The JVM will remain open and free forever, and additional technologies will be incorporated and open-sourced as appropriate.
  • Oracle is looking for willing partners in the community to engage and be part of the conversation – and they are listening.

Some other points:

  • Oracle is a much larger company than Sun and will not rush out any communication which is “half-baked”. This leads to much longer response times, and so the community should not jump to conclusions just because Oracle hasn’t responded yet. They’re aware of the problem here and are trying to fix it.
  • Oracle are trying to unify the licensing position around all Java products. This is taking time because Oracle do not have as many lawyers per capita as Sun did. Sun used several different licenses and disentangling is hard. Oracle are trying to simplify and be more open. The fun quote here was that “Oracle does not have enough Lawyers.”
  • Oracle wants the JCP to evolve – the current form is being revised. There are some new JSRs coming which alter the JCP itself. For example, one of the changes that’s already been announced is that Expert Group discussions (except for the procedural arrangements of who’s free at what time / place for physical meetings) must be conducted in public.
  • A lot of *really* neat JRockit technology is coming to OpenJDK. It’s going to take time, but some of the stuff which is coming is going to make the VM better than ever.
  • Oracle are hiring in a number of areas, including people to work on the core language, VM and overall strategy.

Hopefully that helps you understand some of Oracle’s strategy going forward.

If you’re London based:

We’re hoping to get Patrick Curran (JCP Chair) to come and speak at an LJC event and kick off a practical program where _you_ can get involved in determining the future of Java and its ecosystem and help influence Oracle to make decisions that will benefit all of us in our working careers. Patrick will be able to speak specifically about the JCP in more detail – as that’s his specific area.

Cheers,

Martijn & Ben

Did you like this? Share it:

Official Java 7 for Mac OS X – Status

7 Comments

Hopefully, by now, everyone knows that Apple joined the OpenJDK project last year. What does that mean?

  • Apple will contribute the code that they used for their private Mac Java builds as GPL code to OpenJDK
  • Oracle will take over the stewardship of the Mac port of Java
  • Over time, the Mac platform will become a completely first-class citizen in the Java world

This is good news for Java developers who want to develop on Mac. It’s also good news for Mac users – as it means that, for example, the native Aqua look-and-feel will continue to be supported – so Java desktop apps on Mac will look lovely. I, for one, can’t wait to see what Nimbus look-and-feel will look like under native Aqua.

Over the last few days, there have been some developments – for example this wiki page, detailing the progress of the Mac port, has appeared. Buried at the bottom of the page is a link to a page where the open bugs for the Mac port are being publicly tracked (as they’re ported across from Apple’s internal system).

Development is focused around JDK 7 – the basic idea is to take a fork of the community-maintained BSD port, and add Apple’s code to it, to produce a Mac-specific port. Relevant bug fixes should be able to go both ways between the two related ports, where possible.

All of this is likely to take time, however. The official line from Oracle is that JDK 7 will GA with Windows, Linux and Solaris as first-class supported operating systems, and the Mac will release as soon as possible after, with the hope that at some point in the future updates for the Mac version will be released at the same time as other OSes.

This applies to the Oracle-supplied binary builds. Of course, the OpenJDK code (which Oracle regard as the reference implementation) will be available (and GPL) for anyone who wants to build their own binary.

Here at java7developer.com, we think that we could be looking at roughly a 3 month gap between Java 7 GA and a Mac release – so maybe October 2011 if all goes well. For now, we’re pretty happy running the community-provided OpenJDK builds. There are occasional problems with non-fatal X11-related exceptions clogging up standard out – due to some of the Mac’s uniqueness, but on the whole, it’s not bad at all for a pre-release product.

Have you tried any of the community builds? Let us know what you think in the comments.

Did you like this? Share it:

Project Coin: the try-with-resources lock support debate

6 Comments

If you have recently been following Project Coin’s mailing list , you will have spotted an interesting discussion regarding the inclusion of lock management inside the scope of a try-with-resources (TWR) code block.

The Initial Idea

The idea was initiated by Gernot Neppert who proposed a class java.util.concurrent.AutoLockable which would implement AutoCloseable, and therefore be eligible for usage with TWR:

package java.util.concurrent.locks;

public abstract class AutoLockable implements AutoCloseable
{
  public static AutoLockable locked(final Lock lock)
  {
    lock.lock();
    return new AutoLockable()
    {
      @Override
      public void close() {
        lock.unlock();
      }
    };
  }

  public abstract void close();
}

Its usage would be something like this:

try(AutoLockable locked = AutoLockable.locked(lock))
{
  // Do something in locked scope
}

This proposed idea certainly has merit, however the sharp eyed amongst you will notice a performance issue in creating a new object each time you perform a lock. Additionally, you would also have to have an extra method to acquire the lock (the locked(...) method in the above example). So what else could be tried?

An Alternative Idea

Dr Heinz M. Kabutz posted a link to a newsletter where he describes an interesting way of using JDK 7′s TWR to automatically unlock Java 5 locks. Long story short, the main idea is to build a wrapper class around a Lock, which implements AutoCloseable and manually unlocks in the close() method. The wrapper along with usage of static imports would bring verbose code like:

lock.lock();
try
{
  printLockStatus();
}
finally
{
  lock.unlock();
}

… to a more readable form:

try (lock(lock))
{
  printLockStatus();
}

However, as the author himself mentioned, the problem of creating extra objects every time you perform a lock still remains. Moreover, as David Holmes signaled in the mailing list, the spec has been updated to prohibit usage of resources as general expressions in the TWR argument and only allow passing them with an accompanying explicit variable declaration.

Why TWR (as it stands) can’t support this

Among the reasons for this update were difficulties encountered by the parser which was not always able to distinguish between the start of an expression and the start of a type:

try(i < j // Ternary operator on variables i and j
                 ? new Resource1() :
                 new Resource2()) {...}

… compared to code like

try(Box < Resource // Simple generic wrapper around a resource
 > resourceBox = Box<>(new Resource1())) {...}

Another reason for change was the use case of managing an existing variable which changes its value inside the try block. The example presented on the update site is the following:

public class TwrExamples implements AutoCloseable
{
  public static void main(String... args)
  {
    TwrExamples twrEg1 = new TwrExamples();
    System.out.println(twrEg1.hashCode());

    try(twrEg1)
    {
      twrEg1 = new TwrExamples();  // Mutating the variable!
      System.out.println(twrEg1.hashCode());
    }
  }

  @Override
  public void close()
  {
    System.out.println(hashCode());
  }
}

.. where close() will be called on the first twrEg1 instance, not on the one pointed to at the time the try block finishes. Thus, output results after running a TWR having a TwrExamples resource as argument, may look like this:

1607576787
1051296202
1607576787

The documentation of the Project Coin features posted on March 1st 2011 by Joe Darcy further strengthens the rule of requiring variables to declare a resource in detriment of using general expressions:

“A resource specification declares one or more local variables; the type of each variable must be a subtype of AutoCloseable or a compile-time error occurs.”

However, assigning a new variable to an already existing one referring to the lock just because TWR prohibits identifiers seems troublesome. There is a section in the JSR 334 spec changelog stating that:

“One potential future extension is to allow a resource to be specified as an expression that is a final or effectively final variable. Such a restricted expression form would remove the need to declare a resource variable for the sole purpose of aliasing an existing variable while avoiding pathologies stemming from the resource variable being modified within the body of the |try|-with-resources statement.”

Joe Darcy states in the mailing list that even though this change is too late to be applied to JDK 7, it would be a nice addition to JDK 8.

Some Extra Analysis

Another heads-up in this direction is related to constructs such as try (Resource r = getResource()), where methods such as getResource() are not expected to fail. Some workarounds are proposed by Reinier Zwitserloot in coin-dev, for example not considering the expression Resource r = getResource() as part of the try, and do something like this try (Resource r = ...) { try { ..... }} . Another solution would be setting r to null if the exception that triggers the catch block is resulted from getResource() method. The example from the mailing list is :

try (Resource r = getResource())
{
  /*.... */
}
catch (Exception e)
{
  icon = Icons.DEFAULT_ICON;
  logger.log("App icon resource " + r.getURL() + " is not available", e);
}

In this case we would prefer obtaining a NullPointerException in the log, rather than a core dump.

Your Thoughts?

We’re curious to find out any opinions the readers of this blog might have regarding this ongoing topic discussion on coin-dev. Do you think automatic TWR lock support might be useful to you?

Did you like this? Share it:

Conservativism in Language Design

11 Comments

One of the most interesting things about the development of Java 7 has been the open debate around language features.

However, one of the side-effects of that discussion has been a certain amount of visible frustration from some quarters about the pace of change. The process has been criticized for being too timid, too slow, too conservative by some people. There has also been rather a lot of vitriol over the scope or non-inclusion of specific features.

Language design is hard. It’s hard to think about all possible use cases for a feature up front. It’s even worse to try to think about how your language features will interact. Very smart people get this wrong. A lot.

Now stop and think for a minute about how successful a language Java is. It’s everywhere. There are at least 1 billion Java runtimes in the world today. Millions of companies deploying Java technology and 7-8 million Java developers worldwide. Stability and backwards compatibility is a huge deal.

Consider a largeish company with, say 100-1000 developers, which is introducing a new technology platform. Empirical / anecdotal data suggests this platform will probably be in use for 7+ years. Once enterprises start using a technology, it can be very difficult to get it out again. That same company will probably also spend around $2-3 million on tooling, support, etc over the lifetime of the platform within the company. Multiplying that up by the tens of thousands of such companies that exist, gives some idea of the dollar value of the corporate Java ecosystem.

Putting all of this together, and we can easily see how bad it would be if a misfeature in the language design was allowed to escape into the wild. Once a language feature is out there, the Java community basically has to live with it forever.

This is why the caretakers of the Java language tend to take the view that Java is not the right place for language feature experimentation. Every new feature interacts with the existing “feature surface” of the language, and often in surprising ways. The place we see this the clearest in Java is with the type system.

Looking at the changes in Project Coin, the new multicatch and diamond syntax features are the places where the type system is most deeply involved, and in the formal spec for each contains a large screed of type theory.

Once those features are out in the wild, any further change will now have to deal with the larger amount of type theory that now forms part of the language standard. This acts as a constraint on further language innovation.

All of this leads to a situation whereby change has to proceed slowly and calmly. Features aren’t added lightly – and the engineers who create them aren’t idiots.

Finally – if a new feature isn’t exactly as you expect, then stop, think, take a deep breath. Think about the reasons why the feature may not be precisely tuned for your use case – and about the inevitable compromises that the new feature may represent.

Language design, like legislation, can be more about tradeoffs, compromises and the art of the possible than is sometimes recognised. When combined with the engineering and project management constraints common to all software projects, the fact that we manage to get important new features out at all starts to look like a triumph.

There’s always scope for improvement, and the JCP could use more individual end user and JUG members. If you have strong opinions about new features, or want to be more involved – then this is a great time. With Java 7 just around the corner, and the work already underway for SE 8 and EE 7, this is your chance to make your views known. Early feedback from end users on proposed features is highly prized – you just need to get involved and start contributing.

Did you like this? Share it:

A glimpse at MethodHandle and its usage

3 Comments

MethodHandles are covered in full in our The Well-Grounded Java Developer title

Due to Java’s Reflection API we have been able to inspect and alter program execution at runtime. In particular, we can observe interfaces/classes/methods and fields at runtime without knowing their names at compile time.

JDK 7 introduces a new player to this dynamic/runtime inspection, the method handle (i.e. a subclass of the abstract class java.dyn.MethodHandle). Method handles gives us unrestricted capabilities for calling non-public methods, e.g. it  can be formed on a non-public method by a class that can access it. Compared to using the Reflection API, access checking is performed when the method handle is created as opposed to every time the method is called.

Suppose we have a class which needs to allow controlled access to one of its private methods. Below is the class defining this method and describing two ways (Reflection / MethodHandle) to access it.

public class MethodAccessExampleWithArgs {
    private final int i;

    public MethodAccessExampleWithArgs(int i_) {
        i = i_;
    }

    private void bar(int j, String msg) {
        System.out.println("Private Method \'bar\' successfully accessed : "
                                          + i +", "+ j +" : "+ msg +"!");
    }

    // Using Reflection
    public static Method makeMethod() {
        Method meth = null;

        try {
            Class<?>[] argTypes =
                new Class[] { int.class, String.class };

            meth = MethodAccessExampleWithArgs.class.
                            getDeclaredMethod("bar", argTypes);

            meth.setAccessible(true);
        } catch (IllegalArgumentException e) {
            e.printStackTrace();
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        } catch (SecurityException e) {
            e.printStackTrace();
        }

        return meth;
    }

    // Using method handles
    public static MethodHandle makeMh() {
        MethodHandle mh;

        MethodType desc = MethodType.methodType(void.class, int.class, String.class);

        try {
            mh = MethodHandles.lookup().findVirtual(MethodAccessExampleWithArgs.class, "bar", desc);
            System.out.println("mh="+mh);
        } catch (NoAccessException e) {
            throw (AssertionError)new AssertionError().initCause(e);
        }
        return mh;
      }
  }

Following, is a class meant to test the two approaches of accessing the private method “bar” :

public class MethodAccessMain {

    private static void withReflectionArgs() {
        Method meth = MethodAccessExampleWithArgs.makeMethod();

        MethodAccessExampleWithArgs mh0 =
            new MethodAccessExampleWithArgs(0);
        MethodAccessExampleWithArgs mh1 =
            new MethodAccessExampleWithArgs(1);

        try {
            System.out.println("Invocation using Reflection");
            meth.invoke(mh0, 5, "Jabba the Hutt");
            meth.invoke(mh1, 7, "Boba Fett");
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (IllegalArgumentException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        }
    }

    private static void withMhArgs() {
        MethodHandle mh = MethodAccessExampleWithArgs.makeMh();

        MethodAccessExampleWithArgs mh0 =
            new MethodAccessExampleWithArgs(0);
        MethodAccessExampleWithArgs mh1 =
            new MethodAccessExampleWithArgs(1);

        try {
            System.out.println("Invocation using Method Handle");
            mh.invokeExact(mh0, 42, "R2D2");
            mh.invokeExact(mh1, 43, "C3PO");
        } catch (Throwable e) {
            e.printStackTrace();
        }
    }

    public static void main(String[] args) {
        withReflectionArgs();
        withMhArgs();
    }
}

How to run the code – JDK7 b129 and Netbeans 7.0 Beta 2

The above code has been tested with build 129 of JDK 7, under Netbeans IDE 7.0 Beta 2 and for it to work, it required the following extra VMOptions: -XX:+UnlockExperimentalVMOptions -XX:+EnableMethodHandles -XX:+EnableInvokeDynamic under Run >> Set Project Configuration >> Customize >> VMoptions in order to make use of InvokeDynamic and MethodHandle without receiving a runtime exception.

Issues with JDK7 b131 and Netbeans 7.0 Beta 2

If you’ve upgraded to the latest build – 131 – the outcome starts to be dependent of the circumstances under which you compile and run your code. More specifically, the Netbeans IDE 7.0 Beta 2 outputs the following:

run:
Invocation using Reflection
Private Method 'bar' successfully accessed : 0, 5 : Jabba the Hutt!
Private Method 'bar' successfully accessed : 1, 7 : Boba Fett!

java.dyn.WrongMethodTypeException: (ILjava/lang/String;)V cannot be called as ([Ljava/lang/Object;)Ljava/lang/Object;
mh=bar(MethodAccessExampleWithArgs,int,String)void
Invocation using Method Handle
    at ben.example.MethodAccessMain.withMhArgs(MethodAccessMain.java:46)
    at ben.example.MethodAccessMain.main(MethodAccessMain.java:55)

BUILD SUCCESSFUL (total time: 0 seconds)

Issues with JDK7 b131 and Eclipse 3.6.2

The example has been further tested on Eclipse 3.6.2 Helios with the same parameters -XX:+UnlockExperimentalVMOptions -XX:+EnableMethodHandles -XX:+EnableInvokeDynamic mentioned under Run>>Run Configurations>>Arguments>>VM arguments, but we have been provided with an identical output.

From the exception we have been prompted with, we can see that our method which was expected to be called with an int (I), a string (Ljava/lang/String) and return a void (V), is instead called with an array of Object, and returns an Object. This shows that there are some issues with the compiler used from within the IDE (which may be different from the command-line compiler).

Running the code JDK7 b131 on the command line

If you happen to have a post-129 JDK7 build on your computer and want to run the afore-mentioned examples without any problems, you should probably stick to compiling (javac) and running ( java -XX:+UnlockExperimentalVMOptions -XX:+EnableMethodHandles -XX:+EnableInvokeDynamic com.wgjd.MethodHandleExample.MethodAccessMain) your MethodHandle code from the command line.

Fix for JDK7 b131 and IDEs

Currently there is no set date of when we will be able to run method handles without the extra VMOptions overhead, but should you want to keep up with the latest developments of the Da Vinci Machine Project which concerns itself with the implementation of dynamic invocation, make sure you subscribe to its mailing list.

It is also worth mentioning that from the previously mentioned mailing list, we find out that there is a complex change which consolidates the multi-package code into a single package and consists of preparing for a clean rename from java.dyn to java.lang.invoke. This is required to fix some defects in the API which arise from dependencies between multiple packages.

MethodHandles are covered in full in our The Well-Grounded Java Developer title

Did you like this? Share it:

Older Entries