Setting up and running NetBeans IDE 7.0 Beta 2 with JDK 7
Feb 22
Java 7 JDK 7, Netbeans IDE 7.0 Beta 2, NIO.2, Project Coin 11 Comments
Oracle has released NetBeans IDE 7.0 Beta 2! Some developers might be disappointed with the discontinuation of official Ruby support, or the fact that JUnit is no longer being bundled by default. Happily we have good news on both of those fronts with the Ruby community stepping up to support the Netbeans Ruby plugin, and the Oracle engineers cleverly getting around the JUnit legal stoush by prompting you to immediately download and install JUnit upon starting Netbeans for the first time.
Of course there’s one extra big reason to be cheerful with Beta 2 coming out, seamless JDK7 support. Beta 2 supports the latest JDK7 builds allowing you to try out the new JDK 7 features such as Project Coin:
- try-with-resource statements
- Simplified varargs method invocation
- Multi-catch and more precise rethrow
- Strings in switch
- and more!
For you bold explorers you can get further information on all of the JDK 7 features.
Download & Installation of Netbeans 7.0 Beta 2
A full detailed description of installing, uninstalling and troubleshooting instructions for this version of NetBeans can be found on the official website.
First and foremost navigate to the official download site, select your favourite IDE configuration and click on one of the “Download” buttons.
Before installing it, make sure you have at least JDK 6 installed (preferably update 24), as NetBeans IDE 7.0 Beta 2 cannot be installed using JDK 5. Should you have a recent JDK 7 build on your computer (from following our earlier blog post), then the installer will recognize it without any problems. If you install JDK 7 after Netbeans you can follow the instructions below to configure Netbeans 7.0 Beta 2 with JDK 7.
Configuring NetBeans to work with JDK 7
- Create a new Java Application project
- Right-click on the project root and select “Properties”
- Select “Libraries” on the left side and make sure “JDK 1.7” is selected at the Java Platform option. If not, click on “Manage Platforms” >> “Add Platform” then navigate to the installation folder of the JDK (e.g. in Debian it’s under /usr/lib/jvm/jdk1.7.0 ), then click “Next”, type a platform name unless it is not automatically detected, then press “Finish”
- Select “Sources” on the left side and make sure JDK 7 is selected under Source/Binary Format option
- Click OK and you’re good to go
Trying out new features of Java SE 7
You can go ahead and copy/paste the following code snippets directly in your IDE. They reflect some of the changes from the new Java specification.
Try-with-resources (TWR)
In the following example, the HTML content from an URL is read and written in a file. Notice that the TWR feature automatically handles closing of the FileOutputStream and InputStream resources.
URL url = new URL("http://www.java7developer.com/blog/?page_id=97");
try (FileOutputStream fos = new FileOutputStream(new File("output.txt"));
InputStream is = url.openStream())
{
byte[] buf = new byte[4096];
int len;
while ((len = is.read(buf)) > 0)
{
fos.write(buf, 0, len);
}
}
catch (IOException e)
{
e.printStackTrace();
}
Now as Alan Bateman (lead for the NIO.2 project) has kindly pointed out, the latest developer preview of JDK 7 (build130) makes the actual file I/O work much simpler. The above code can be reduced down to:
URL url = new URL("http://www.java7developer.com/blog/?page_id=97");
try (InputStream in = url.openStream())
{
Files.copy(in, Paths.get("output.txt"));
}
catch(IOException ex)
{
ex.printStackTrace();
}
The sharp eyed amongst you will also realise we haven’t dealt with the MalformedURLException either. We’d love to see your versions of the above code with that handling factored in, please do post in the comments or on our google group!
Strings in the switch statement
The next example shows a simple usage of the switch statement containing a String as argument. In Java 6 and previous versions only byte, char, short, int and enum constants (along with the Byte, Character, Short and Integer wrappers) are allowed as values for the cases, whereas JDK 7 adds support for String objects
public void printDay(String dayOfWeek)
{
switch (dayOfWeek)
{
case "Sunday": System.out.println("Dimanche"); break;
case "Monday": System.out.println("Lundi"); break;
case "Tuesday": System.out.println("Mardi"); break;
case "Wednesday": System.out.println("Mercredi"); break;
case "Thursday": System.out.println("Jeudi"); break;
case "Friday": System.out.println("Vendredi"); break;
case "Saturday": System.out.println("Samedi"); break;
default: System.out.println("Error: '" + dayOfWeek + "' is not a day of the week"); break;
}
}
Handling Several Different Exceptions
The code below shows the new approach to ‘catching’ exceptions in JDK 7 – two or more exceptions can be grouped in the same catch statement, provided that the error handling code treats the exception argument as the common supertype of the exceptions which are part of the catch statement.
public Configuration getConfig(String fileName_)
{
Configuration cfg = null;
try
{
String fileText = getFile(fileName_);
cfg = verifyConfig(parseConfig(fileText));
}
catch (FileNotFoundException | ParseException | ConfigurationException e)
{
System.err.println("Config file '" + fileName_ + "' is missing or malformed");
}
catch (IOException iox)
{
System.err.println("Error while processing file '" + fileName_ + "'");
}
return cfg;
}
As JDK 7 is more or less feature-complete (with API changes due to be halted at the end of April), you have the freedom of experimenting all its new functionalities, and using the NetBeans IDE 7.0 Beta 2 version will make your experience easier and more straightforward than before.
RSS
Twitter
Email
Facebook
Join our Early Access Program, read chapters now!
Feb 24, 2011 @ 08:36:12
Since this is JDK7 then the TWR example above could be written as:
try (InputStream in = url.openStream()) {
Files.copy(in, Paths.get(“output.txt”));
}
Feb 25, 2011 @ 09:31:39
Hi Alan,
Right you are! I’ll update that post in a few minutes. Thanks for stopping by
Feb 25, 2011 @ 10:50:33
I think that TWR feature is a very important feature, but not very well for the java
newbie that will not know what happens under the hood, but fortunally i don’t care.
Nice Example!
Feb 25, 2011 @ 14:49:28
In your I/O example above this statement:
catch (IOException ex) {
e.printStackTrace();
}
should be
catch (IOException ex) {
ex.printStackTrace();
}
Feb 26, 2011 @ 10:46:37
Hi Bruce, right you are! I’m updating the code and hopefully sorting out some formatting issues as well. Cool, fixed now
Mar 01, 2011 @ 22:49:19
While I am happy to see JDK 7 finally reaching acceptance testing, it seems like I have a bit of an incompatibility. I succesfully can use the try-with-resources functionality with the previous version of netbeans:
Product Version: NetBeans IDE Dev (Build nbms-and-javadoc-6381-on-101224)
Java: 1.7.0-ea; Java HotSpot(TM) Client VM 21.0-b02
System: Windows Vista version 6.0 running on x86; Cp1252; en_US (nb)
but the new version:
Product Version: NetBeans IDE 7.0 Beta 2 (Build 201102140001)
Java: 1.7.0-ea; Java HotSpot(TM) 64-Bit Server VM 21.0-b02
System: Windows Vista version 6.0 running on amd64; Cp1252; en_US (nb)
fails to recognize it correctly.
I will make it even more squirrely by saying, it won’t compile from the command line either! Just the old IDE….
Here is a copy of all the source code. It even runs from the old IDE just fine. I am so confused by this!
package jview2examples.autocloseable;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.ReentrantLock;
import mil.afrl.jview.engine.NonExceptionAutoCloseable;
/**
*/
public class Test {
public static void main(String args[]) {
AutoUnlockable resource1 = new AutoUnlockable();
AutoUnlockable resource2 = new AutoUnlockable();
try (SyncLocker.lock(resource1, resource2) ) {
// When this is done, release the resources
System.out.println(“Love try with resources!”);
}
}
}
class AutoUnlockable implements Lockable {
ReentrantLock lock = new ReentrantLock();
@Override
public ReentrantLock getLock() {
return lock;
}
}
class SyncLocker {
private static final ReentrantLock globalLock = new ReentrantLock(true);
private static final Condition access = globalLock.newCondition();
private SyncLocker() {}
public static NonExceptionAutoCloseable lock(final ReentrantLock … locks) {
lockImpl(locks);
return new NonExceptionAutoCloseable() {
@Override
public void close() {
SyncLocker.unlock(locks);
}
};
}
public static void lockImpl(ReentrantLock … locks) {
boolean obtainable = true;
try {
globalLock.lock();
while (true) {
// Check to see if all the locks are available
for (ReentrantLock lock : locks) {
if (lock.isLocked()) {
obtainable = false;
try {
access.await();
} catch (InterruptedException ie) {
// This needs to be thrown, perhaps a different
// method, that way the programmer can decide if they
// want the silent exception handling that this current
// implementation affords.
}
break;
}
}
// If all the locks are available
if (obtainable) {
for (ReentrantLock lock : locks) {
lock.lock();
}
return;
// Otherwise we need to try again
} else obtainable = true;
}
} finally {
globalLock.unlock();
}
}
public static void unlock(ReentrantLock … locks) {
globalLock.lock();
try {
for (ReentrantLock lock : locks) {
lock.unlock();
}
access.signal();
} finally {
globalLock.unlock();
}
}
public static NonExceptionAutoCloseable lock(final Lockable … lockables) {
lockImpl(lockables);
return new NonExceptionAutoCloseable() {
@Override
public void close() {
SyncLocker.unlock(lockables);
}
};
}
public static void lockImpl(Lockable … lockables) {
boolean obtainable = true;
try {
globalLock.lock();
while (true) {
// Check to see if all the locks are available
for (Lockable lockable : lockables) {
if (lockable.getLock().isLocked()) {
obtainable = false;
try {
access.await();
} catch (InterruptedException ie) {
// This needs to be thrown, perhaps a different
// method, that way the programmer can decide if they
// want the silent exception handling that this current
// implementation affords.
}
break;
}
}
// If all the locks are available
if (obtainable) {
for (Lockable lockable : lockables) {
lockable.getLock().lock();
}
return;
// Otherwise we need to try again
} else obtainable = true;
}
} finally {
globalLock.unlock();
}
}
public static void unlock(Lockable … lockables) {
globalLock.lock();
try {
for (Lockable lockable : lockables) {
lockable.getLock().unlock();
}
access.signal();
} finally {
globalLock.unlock();
}
}
public static ReentrantLock getLock() {
return globalLock;
}
}
interface Lockable {
public ReentrantLock getLock();
}
Mar 02, 2011 @ 10:27:47
Hi Jason,
Thanks for posting a full example. It seems a bit incomplete though – I just tried it out, and there are a few problems I found. E.g. NonExceptionAutoCloseable wasn’t supplied. Assuming it looks like this:
public interface NonExceptionAutoCloseable extends AutoCloseable {
void close();
}
Then the problem seems to be that SyncLocker etc all expect ReentrantLock… rather than Lockable…
In general, though, there’s been a lot of discussion on the coin-dev mailing list about the use of AutoCloseable with Lock. There’s an interesting thread which starts about here: http://mail.openjdk.java.net/pipermail/coin-dev/2011-February/003114.html and covers the reasons why people don’t think using locks is a good use case for this (basically, due to possible high volumes of object allocation).
Also, it’s worth noting than in recent drafts of the spec, the try(…) doesn’t accept simple expressions any more – it has to be an assignment, so your code won’t work on a production JDK7 build.
Mar 02, 2011 @ 14:21:29
Thanks Ben for the quick response. Sorry about forgetting to post that other piece. This example is incorporated in a MUCH larger project and I tried to pull it out on its own and apparently didn’t quite get it all!
class NonExceptionAutoCloseable implements AutoCloseable {
@Override
public void close() {
}
}
So why the change for the spec? I have to admit, this really….. sucks. We have been using this feature VERY effectively and it has ameliorated many problems for our users not having to manually release the locks. In our case, the lock allocation is fairly infrequent. We are implementing a graphics engine and in order to support atomic operations so the renderer doesn’t view incomplete data, we need a short lock with certain order guarantees.
So now the following code works, but is really nasty:
try (NonExceptionAutoCloseable crap = SyncLocker.lock(resource1, resource2) ) {
// When this is done, release the resources
System.out.println(“Love try with resources!”);
}
Ultimately, who can I “complain” to and is this change considered permanent?
Mar 06, 2011 @ 11:49:33
Hi Jason,
Sorry for not getting back to you sooner.
The discussion is taking place on coin-dev. I think the change to not allow simple expressions, only assignment is permanent, but Joe Darcy, who runs coin-dev is always interested in working examples from the field – so I would definitely join coin-dev and post about your use case – there’s also a post on that list about performance and the need to use Escape Analysis to get decent perf.
The sign-up page for coin-dev is here: http://mail.openjdk.java.net/mailman/listinfo/coin-dev and there’s a link to the archives where you can read the discussion to date.
I hope there’s a good solution for this – I can see the importance of this use case.