The book I should have had as a child
Illustrated Guide to Home Chemistry Experiments: All Lab, No Lecture
Did you ever notice how, well, dull modern chemistry textbooks are? Chapter after chapter of theory. Hardly a single mention of an actual chemical in them. You could be forgiven for taking years of classes and not knowing what is in your gasoline tank. Compare this (1883), which fortunately I did have as a child:
The iodide is a black powder, which explodes with a loud report even when touched with a feather, emitting fumes of hydriodic acid and purple vapor of iodine...
...The osmium alloy is extremely hard and has been used to tip the points of gold pens. When a grain of it happens to be present in the gold which is being coined, it often seriously injures the die. When the platinum ore is treated with aqua regia, this alloy is left undissolved, together with grains of chrome-iron ore and titanic iron. ...
When the oil of bitter almonds is distilled over, it is accompanied by the hydrocyanic acid formed at the same time, and it is this which renders the ordinary commercial oil so powerful a poison, for if it be purified by distillation with a mixture of lime and ferrous chloride (see Prussian blue), which retains the hydrocyanic acid, it becomes comparatively harmless. ...
Phosphoric acid is obtained from bone-ash by decomposing it with sulphuric acid, so as to remove as much of the lime as possible in the form of sulphate, which is strained off, and the acid liquid neutralized with ammonium carbonate, which precipitates any unchanged calcium phosphate, and converts the phosphoric acid into ammonium phosphate. ...
A bit eclectic, perhaps, but something a less-than-adult might actually read voluntarily. And which might impress on the reader what the chemical is really like: not just physical properties, but its essential behaviors, its manufacture, its use to people.
Posted at 10:05PM May 14, 2008 by jglick in Personal | Comments[0]
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[0]
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[0]
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.
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[3]
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]
Popcorn Soup
Seems creamy though technically it is not. * 1 1/2 c popcorn kernels * 1 medium yellow onion, chopped * 2 tbsp ground mild red chili (or hot paprika) * 2 tbsp ground sunflower seeds * 3 tbsp vegetable oil * 2 celery stalks, thinly sliced * 1/2 jalapeno, seeded & minced * 1 tbsp capers, minced * 1/2 tomato, chopped * 2 tbsp red miso paste * 1 tbsp nutritional yeast * salt to taste Cook onion in oil with ground chili and sunflower seeds over high heat with a little water until starting to soften. Add more water and bring to a boil, adding remaining vegetables. Pop popcorn and stir into broth in batches. Cook under high pressure for 30 minutes. Release pressure, puree with hand blender (optionally strain), and stir in miso, yeast, and salt. Serve hot.
Posted at 10:16AM Feb 13, 2006 by jglick in Personal | Comments[5]
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]