Chronicle of a ConcurrentModificationException Foretold
In a somewhat feverish mid-conference dream last night, I invented a new Java complexity metric. It is quite simple: the number of calls to methods which either return void or take no arguments or both, including calls to no-argument constructors.
As a quick example, you can see that any usages of the bean "pattern" will cause this count to shoot upwards rather quickly.
The metric is called the code's "omen".
Posted at 11:33AM Jun 04, 2009 by jglick in Sun | Comments[0]
Hudson support in NetBeans
NetBeans 6.7 M3 includes the first version of a new integrated support for the Hudson build engine.
Posted at 10:38AM Mar 23, 2009 by jglick in Sun | Comments[4]
Many annotations are referentially @Opaque
Often Java elements (such as classes or methods) have meaning beyond their "denotational semantics": the name (or, occasionally, just presence) of the element itself is significant to how the application runs, beyond simple references from other Java source code. For example, a field marked with @javax.persistence.Column cannot be freely renamed or shuffled around according to traditional refactoring tools.
It would be great if there were a consistent way to mark these kinds of annotations. Authors of Java frameworks could then indicate to tools that Java elements marked with them need to be treated conservatively.
My suggestion is to introduce a meta-annotation (i.e. annotation placed on other annotations): @Opaque. Here is source code for the annotation and some possible example usages.
Posted at 08:27PM Sep 24, 2008 by jglick in Sun | Comments[2]
Update of framework for declarative registration through annotations
I have committed an update to SezPoz, a library letting you register elements of an application (such as menu items in a GUI) declaratively using nothing but Java-language annotations.
The update provides support for JSR 269 in addition to JDK 5's APT; now you can use SezPoz with no special build steps so long as you compile under JDK 6's javac (or another 269-compatible compiler). In addition, it provides better support for incremental builds.
I would be interested in feedback from anyone who has been looking for a lightweight framework for registering features in a modular application.
Posted at 09:25PM Apr 17, 2008 by jglick in Sun | Comments[1]
TeamWare to Mercurial history conversions
Since Google shows no options for converting TeamWare workspaces to Mercurial (beyond an OpenSolaris-specific incremental tool), and I had some scripts sitting around that can be used for this purpose, I am sharing them in the hopes that someone will find them useful. These scripts are by no means polished, and may or may not work for you as is.
Here is roughly what you need to do:
/tmp/project-tw.sudo apt-get install cssc, and add /usr/lib/cssc to your $PATH.sccs2exploded.plsccs2exploded.pl --indir /tmp/project-tw --outdir /tmp/project-explodedexploded2cvs.plcvs -d /tmp/project-cvs initexploded2cvs.pl --indir /tmp/project-exploded --outdir /tmp/project-cvs/modulecvs -d /tmp/project-cvs co modulehg convert module project-hgproject-hg, your new Mercurial workspace. You may need to hg up -r tip -C to get to the "tip" revision. If there are some branches imported from TeamWare, you may need to see what they are using hg heads and resolve them using hg merge.Good luck! I have run this procedure on Ubuntu on a small TeamWare workspace successfully, but for big projects there could well be some complications. Features and limitations:
deleted_files) should be correctly imported.Posted at 02:32PM Jan 19, 2008 by jglick in Sun | Comments[1]
No more uninformative Issuezilla page titles
Are you a Firefox user? Using Greasemonkey you can fix netbeans.org Issuezilla to display issue summaries in the page title, not just the issue numbers. Much nicer when using tabbed browsing and opening a lot of issues at once. Download and install the attachment from:
#57291
Currently only works when you are logged in.
Update: this and other tools are now hosted elsewhere.
Posted at 12:47PM Oct 10, 2006 by jglick in Sun | Comments[1]
BOF-0220 ("Test Patterns in Java") follow-up
Some people who came to BOF-0220 ("Test Patterns in Java") were asking about slides, demo sources, and/or the NB-JUnit library used in the demonstrations. You can find these things, plus a longer exposition of the ideas summarized in the BOF, on the NetBeans website:
Posted at 11:46PM May 18, 2006 by jglick in Sun | Comments[0]
Pick a target JDK for a freeform project in NetBeans
I know, I know, long overdue, but here it is anyway: a little tool to assist you in building and running a "freeform" project (existing Ant script) using a different JDK from what NetBeans is running on. Ant tasks like javac and the like have long supported selecting a particular JDK executable to use (means they must fork to run the tools), but few people would want to remember to set these attributes consistently. Instead, this tool uses the magic of presetdef to do it for you. The upshot is that freeform projects behave a little more like other projects.
Download the Freeform Project Extras 1.5 NBM (NetBeans 5.0+ compatible)
If you were really paranoid you could make your test target run all your unit tests in turn on each supported JDK...without leaving the IDE. But that's for you to write.
Posted at 07:42PM Feb 19, 2006 by jglick in Sun | Comments[5]
jrunscript in a target VM
Mustang's jrunscript is cool, but it just launches a new VM and runs your script. Sometimes you want to find out what is going on in an existing process, or control it somehow, using JavaScript. Now you can!
Download
jrunscriptin.jar
and run with
java -jar jrunscriptin.jar(on Mustang) for usage information, quoted here for your convenience:
Usage: java -jar jrunscriptin.jar <PID>Sourceswhere <PID> is as in jps java -jar jrunscriptin.jar <match> <JavaScript> where <match> is some substring of the text after a PID visible in jps -lm Example using NetBeans IDE (quoting as in Bourne Shell, adapt as needed): java -jar jrunscriptin.jar netbeans \ 'Packages.org.openide.awt.StatusDisplayer.getDefault().setStatusText("Hello from abroad!"); \ java.lang.System.out.println("OK!")' Requires Mustang (JDK 6) for both this tool and the target VM.
Posted at 02:11PM Feb 15, 2006 by jglick in Sun | Comments[4]
Mustang agents can be used to probe running NB instances for data
Just thinking about how to extract useful information from a running NB platform instance. Not so hard to do using Mustang, it seems. You can use an API (supported in the Sun JDK at least) to connect to VMs running NB on the same machine and run some code in that VM, which can with a little work make use of NB APIs:
project ZIP
The API:
com.sun.tools.attach
A little annoying to develop such an agent incrementally because you can't reload the same agent classes in a given target VM, and Mustang seems to also reject attempts to call loadAgent twice with the same JAR. A workaround is to rename both the agent JAR and agent main class each time you test it. Probably this could be automated somehow, or you could have a "stub" agent which you never change, which just loads a named JAR in a fresh class loader and runs it.
Next stop: figuring out how to use this as a stepping-stone to set up a regular JMX client connection. The rub is that jconsole has a nice UI to let you pick a VM to attach to from among locally running VMs, but then shows a generic JMX browser. I want to write a domain-specific JMX GUI client that (in the spirit of requiring zero configuration) will by default display all VMs running on the local machine matching some pattern. The goal is a general-purpose NB runtime inspector:
#69773
Posted at 11:39AM Feb 15, 2006 by jglick in Sun | Comments[0]
Continuations supersede SwingWorker and Foxtrot
SwingWorker is a pretty complete approach to off-event-queue execution, but clumsy syntactically:
http://download.java.net/jdk6/docs/api/javax/swing/SwingWorker.html
FoxTrot improves the API a bit for the simple cases but relies on the funky trick of pushing a new event thread:
http://foxtrot.sourceforge.net/docs/worker.php
Turns out that using continuations you can make the simple cases even simpler. Try running the following using Mustang's jrunscript -f demo.js:
function cont() {
return new Continuation();
}
function offEQ(execsvc) {
var c = cont();
if (c instanceof Continuation) {
execsvc.submit(
new java.lang.Runnable({
run:
function() {
c();
}
})
);
return true;
} else {
return false;
}
}
function onEQ() {
var c = cont();
if (c instanceof Continuation) {
java.awt.EventQueue.invokeLater(
function() {
c();
});
return true;
} else {
return false;
}
}
function showThread() {
print(java.lang.Thread.currentThread());
}
var swing = Packages.javax.swing;
var frame = new swing.JFrame("Demo");
frame.setLayout(java.awt.FlowLayout());
var button = new swing.JButton("Start");
var es = java.util.concurrent.Executors.newSingleThreadExecutor();
button.addActionListener(
function(event) {
field.setText("clicked");
button.setEnabled(false);
for (var i = 0; i < 10; i++) {
field.setText("sleeping #" + i);
showThread();
if (offEQ(es)) return;
showThread();
java.lang.Thread.sleep(1000);
if (onEQ()) return;
showThread();
}
field.setText("done");
button.setEnabled(true);
});
frame.add(button);
var field = new swing.JTextField(20);
frame.add(field);
field.setText("idle");
field.setEditable(false);
frame.setDefaultCloseOperation(3);
frame.pack();
frame.setVisible(true);
java.lang.Thread.sleep(9999999);
Unfortunately continuations are not available in Java itself, only in the bundled Rhino JavaScript. Some day...
Posted at 12:00AM Feb 05, 2006 by jglick in Sun | Comments[5]