Thursday January 31, 2008
Obfuscation
Today I was asked about obfuscation. In fact, the question was "how to obfuscate code in NetBeans". Well, code in NetBeans is like any other Java code anywhere else. And others have had the same need. I looked into it and came up with the following:
- Download ProGuard.
- In your build.xml, add the target outlined in this handy FAQ: Can I obfuscate a module? Just make sure to replace ${proguard.jar.path} with the full path to the proguard.jar, which can be anywhere. Also remove the dependency on init target, in the obfuscate target outlined in the above FAQ.
- Build your application. When you do so, the Output window shows that ProGuard writes a new folder with your own module's obfuscated classes:
- Look in the folder indicated above and there's the 'obfuscated' folder with the obfuscated classes:
Next I tried to decompile the classes, but all 3 of the decompiler plugins in the Plugin Portal failed me. But, if one wanted to decompile, there are many decompilers out there that could be used. The point is that obfuscation is not difficult to achieve, via the handy Ant target above. And, it's clear that if you have some top secret code that you need to obfuscate, there's a well trodden path that you can follow.
Jan 31 2008, 06:07:59 PM PST Permalink
JTop on the NetBeans Platform
Charlie Hunt, one of Sun's performance gurus, is in town (where "town" equals "Prague, Czech Republic") and we've been studying the JDK's JTop plugin for JConsole, with a view to porting it to a NetBeans module. Let me tell you, it was not easy to figure out, at least initially. JTop consists of a class that extends JConsolePlugin, which integrates with JConsole, as well as a JPanel, which provided the actual user interface. We ended up dumping the JConsolePlugin class completely. There was nothing we needed from it.
Then we moved most of the content from the sample's other class, i.e, the JPanel, into a TopComponent, which integrates with the NetBeans Platform. We initially simply wanted to call the JPanel from the TopComponent and then add it to the TopComponent. I think that probably failed because the JPanel might have been getting instantiated (at least) twice. So we moved everything into the TopComponent, ran the NetBeans Platform, and there it was:
We also installed it into the Visual VM:
...and into NetBeans IDE:
In the latter case, we encountered a lot of problems because, as we eventually discovered, the Visual Web Pack has a security manager that conflicts with the security manager set in the tools.jar, which is where the JConsole API is located. We tried in vain to set security policies in various places before we discovered the culprit and then simply excluded the Visual Web Pack from the IDE. Then the JTop plugin worked without a problem.
And, because the original JTop plugin uses the cool new JDK6 SwingWorker class, the TopComponent is updated automatically in the background and the thread information is continuously current. Hurray!
Jan 30 2008, 02:01:39 PM PST Permalink
Creating Visual Java Applications
My excellent colleague Sun evangelist Chuk Munn Lee wrote me an e-mail in response to my description yesterday of the JConsole plugin: "I did not know that the visual library can be used outside of NetBeans. Do you need a special build of the library? Do I need to build it myself or is there a standalone version that I can download?"
This is a good question and the answer is illustrative of how interwoven NetBeans IDE is with the NetBeans Platform. Look in your NetBeans installation folder and you'll find a folder called "platform7", with this content:
In other words, literally, the content of the folder above is the NetBeans Platform. Many of the JARs that make up the NetBeans Platform can be used outside a NetBeans Platform application. Last October I wrote about this, in a blog entry entitled NetBeans APIs Outside of the NetBeans Platform. Follow the steps in that tutorial and you'll have a standard Java application that makes use of some of the typical JARs from the NetBeans Platform.
In other words, several typical scenarios developed on the NetBeans Platform can also be developed outside of it. Another similar scenario is illustrated in my blog yesterday, where the Visual Library API is used to inject some graph functionality into the JConsole. And so, in response to Chuk's questions "Do you need a special build of the library? Do I need to build it myself or is there a standalone version that I can download?", the answer is: "No, you don't." Download NetBeans IDE, take the two JARs that are highlighted in the screenshot above, put them on your app's classpath, and you're ready to create visual Java applications:
Let's get started for real now. To create visual applications, you need some kind of Swing container within which you need a JScrollPane. Then you create your visual "scene" within that JScrollPane. There are several interesting classes that you can extend to make your visual application. Have a look at the Javadoc or take a stroll through the tutorial, though not all of the tutorial is intended for use outside of the NetBeans Platform.
Now that you have a Swing container with a JScrollPane, create a new Java class that extends GraphScene. Fill it out as follows:
package demo;
import java.awt.Image;
import java.awt.Point;
import java.util.Random;
import javax.swing.ImageIcon;
import org.netbeans.api.visual.graph.GraphScene;
import org.netbeans.api.visual.widget.LayerWidget;
import org.netbeans.api.visual.widget.Widget;
import org.netbeans.api.visual.widget.general.IconNodeWidget;
import org.openide.util.Utilities;
public class DemoGraphScene extends GraphScene {
private LayerWidget mainLayer;
private Image image;
private Random r = new Random();
public DemoGraphScene() {
mainLayer = new LayerWidget(this);
addChild(mainLayer);
image = Utilities.icon2Image(new ImageIcon(getClass().getResource("/demo/chuk.png")));
addNode("Chuk");
}
@Override
protected Widget attachNodeWidget(Object arg0) {
IconNodeWidget widget = new IconNodeWidget(this);
widget.setImage(image);
widget.setPreferredLocation(new Point(10, 20));
mainLayer.addChild(widget);
return widget;
}
@Override
protected Widget attachEdgeWidget(Object arg0) {
return null;
}
@Override
protected void attachEdgeSourceAnchor(Object arg0, Object arg1, Object arg2) {
}
@Override
protected void attachEdgeTargetAnchor(Object arg0, Object arg1, Object arg2) {
}
}
Most of the above code is self-explanatory, I believe. You have a LayerWidget which you add to the scene. Then you add an IconWidget, which you add to the layer. One interesting thing to note is how the icon is converted to an image, via a utility method from the NetBeans Utilities API, which you have already put on your classpath, together with the Visual Library API. In other words, there's a bunch of stuff that NetBeans Platform developers use that can also be used in your own smaller Java applications, as is the case here.
To wrap up, we need to instantiate the GraphScene class from our JFrame and then set the JScrollPane so that its port view will contain the "scene". Here's how we do that, nice and easy via the JFrame constructor:
private DemoGraphScene scene = new DemoGraphScene();
public DemoVisualFrame() {
initComponents();
jScrollPane1.setViewportView(scene.createView());
}
Next, I added a pic of Chuk to my app's source structure and then ran the application. And here's the result:
Next, let's turn Chuk into a movable object. The user should be able to drag and drop him with their mouse. Hmmm. That will mean a lot of coding, right? Wrong. Here's all I needed to add, i.e., just the line in bold:
protected Widget attachNodeWidget(Object arg0) {
IconNodeWidget widget = new IconNodeWidget(this);
widget.setImage(image);
widget.setPreferredLocation(new Point(10, 20));
widget.getActions().addAction(ActionFactory.createMoveAction());
mainLayer.addChild(widget);
return widget;
}
And now, when I run my app, I can use my mouse to drag Chuk to a different location:
A MoveAction can only mean one thing, i.e., it can only mean that you want to move the widget. However, other actions could be implemented in a variety of ways, hence there is no default. You need to provide the content of the action yourself, as in the case of the LabelTextFieldEditor. Here, we begin by defining a class-level LabelTextFieldEditor:
private WidgetAction editorAction = ActionFactory.createInplaceEditorAction(new LabelTextFieldEditor());
Next, we define out LabelTextFieldEditor, extending the TextFieldInplaceEditor class:
private class LabelTextFieldEditor implements TextFieldInplaceEditor {
public boolean isEnabled(Widget widget) {
return true;
}
public String getText(Widget widget) {
return ((LabelWidget) widget).getLabel();
}
public void setText(Widget widget, String text) {
((LabelWidget) widget).setLabel(text);
}
}
Finally, we add a label to our widget. We also assign the editor action defined above to our widget. Here we go:
@Override
protected Widget attachNodeWidget(Object arg0) {
IconNodeWidget widget = new IconNodeWidget(this);
widget.setImage(image);
widget.setPreferredLocation(new Point(10, 20));
widget.setLabel("Chuk");
widget.getLabelWidget().getActions().addAction(editorAction);
widget.getActions().addAction(ActionFactory.createMoveAction());
mainLayer.addChild(widget);
return widget;
}
That's it. Let's run our app again. You now have a label which you can click and then it is editable:
When you press Enter, the label is changed.
But what's the point of having just Chuk in our application? Let's add another evangelist, Gregg Sporar:
private Image CHUK = Utilities.icon2Image(new ImageIcon(getClass().getResource("/demo/chuk.png")));
private Image GREGG = Utilities.icon2Image(new ImageIcon(getClass().getResource("/demo/gregg.png")));
Next, we'll create a hash table, so that we can manipulate them more effectively:
private final Hashtable mapping;
{
mapping = new Hashtable();
mapping.put("Chuk", CHUK);
mapping.put("Gregg", GREGG);
}
Then, we'll add them both, rather than just one:
public DemoGraphScene() {
mainLayer = new LayerWidget(this);
addChild(mainLayer);
addNode("Chuk");
addNode("Gregg");
getActions().addAction(editorAction);
}
We'll need to rewrite our earlier method just a bit, so that it is more generic, because now it will have to handle both Chuk and Gregg:
@Override
protected Widget attachNodeWidget(Object node) {
Image image = (Image) mapping.get(node);
if (image != null) {
return createNewWidget(node, image);
}
throw new IllegalArgumentException(node.toString());
}
And we move all the code from the previous implementation of the above method to a new one:
protected Widget createNewWidget(Object label, Image image) {
IconNodeWidget widget = new IconNodeWidget(this);
widget.setImage(image);
widget.setPreferredLocation(new Point(10, 20));
widget.setLabel(label.toString());
widget.getLabelWidget().getActions().addAction(editorAction);
widget.getActions().addAction(ActionFactory.createMoveAction());
mainLayer.addChild(widget);
return widget;
}
Run the app again and now you'll have two evangelists in your "scene", instead of just one, with the same properties because they're both the same widget, as you can see from the code above:
You might now think about connecting them together, which we can look at in a future blog entry. In general, there's a lot more that can be done, of course, and the documentation on all of this goes into it all. Here's the homepage of the library. I also highly recommend Fabrizio Giudici's Creative use of the NetBeans Visual Library: the Light Table.
In summary, you don't even need to like NetBeans IDE to benefit from its graph library. Just download the IDE, get the two JARs specified above, and then add them to your classpath. That's all. And then code in whatever IDE has your preference.
Jan 29 2008, 09:22:19 AM PST Permalink
Visualizing Threads in the JConsole
While reading Beginning Java SE 6 Platform: From Novice to Professional, I discovered for the first time that the JConsole is pluggable, since Java SE 6. That's maybe not exactly news, if you're a friend of JConsole and have followed its adventures over the past years. Personally, I'm more interested in JConsole's pluggability than JConsole itself.
The JDK provides a set of demos, some of which are helpful in understanding how plugins work in relation to JConsole. Go to demo/management in the JDK's installation folder and you'll find them. Especially JTop is helpful in showing how a new panel can be added to the JConsole. The panel is simply a JPanel. In addition to the JPanel, you need a class that extend JConsolePlugin, which uses its getTabs method to retrieve the JPanel. From page 245 of the abovementioned book, you get a brilliant exposition of everything related to the JConsole's pluggability. (Here's hoping that the same author will get to write the book on Java SE 7.) Mandy Chung's blog, which is also referenced in the book above, is also great in its discussion of the JConsole and its pluggability.
In my first experiment, I added a web browser to JConsole. That was kind of fun, though I wasn't interacting with any of the data provided by the JConsole. Here is my second experiment, which is more interesting, providing a visual thread window in the JConsole:
The visual part of the above JConsole plugin is provided by the NetBeans Visual Library API. Whenever I detect a thread name, I create a new node on the canvas. When I detect a new state or a new ID, I create a pin, which is the info below the thread name in the screenshot above. Here's the code for that part:
void setThreadList(List<Entry<Long, ThreadInfo>> list, DemoGraphScene scene, MBeanServerConnection server) {
threadList = list;
for (int i = 0; i < threadList.size(); i++) {
String text = threadList.get(i).getValue().getThreadName();
String state = threadList.get(i).getValue().getThreadState().name();
Long threadId = threadList.get(i).getValue().getThreadId();
createNode(scene, (int) (300), (int) (300), text, "Value", null);
createPin(this, text, text + ":" + state, "State: " + state, null);
createPin(this, text, text + ":" + threadId, "Id: " + threadId, null);
}
this.moveTo(null);
}
Here are the three methods used for creating the nodes and pins, as well as the movement which positions the nodes on the canvas:
private String createNode(DemoGraphScene scene, int x, int y, String name, String type, java.util.List<Image> glyphs) {
String nodeID = name;
if (!scene.getNodes().contains(nodeID)) {
VMDNodeWidget widget = (VMDNodeWidget) scene.addNode(nodeID);
widget.setPreferredLocation(new Point(x, y));
widget.setNodeProperties(null, name, type, glyphs);
}
return nodeID;
}
private static void createPin(DemoGraphScene scene, String nodeID, String pinID, String name, String type) {
if (!scene.getPins().contains(pinID)) {
((VMDPinWidget) scene.addPin(nodeID, pinID)).setProperties(name, null);
}
}
private void moveTo(Point point) {
int index = 0;
for (String node : getNodes()) {
getSceneAnimator().animatePreferredLocation(findWidget(node), point != null ? point : new Point(100, ++index * 100));
}
}
All of the above is in a class that extends VMDGraphScene. And that's most of the plugin, the rest is pretty much the same as the JTop demo plugin that you can find in the JDK's installation folder. It's pretty cool that one can now extend the JConsole, gives you a lot of room to manouevre.
Once you've created a JAR that contains your plugin, you need to start the JConsole together with the --pluginpath command line argument. And the value of the argument is the location of the JAR. I normally start up the JConsole from an Ant script that overrides the application's Run target. The application isn't able to run anyway, since it is a plugin, so the Run target is useless. So, I've given it some purpose by using it to start JConsole, together with my plugin:
<target name="run">
<exec dir="../../../bin" executable="jconsole">
<arg value="-pluginpath"/>
<arg value="..demo/management/VMDDemoPlugin/dist/VMDDemoPlugin.jar"/>
</exec>
</target>
Then, because you've created a META-INF/services folder, as shown in the JTop sample, and because of the abovementioned class that extends JConsolePlugin, a new tab is added to the JConsole, as defined by your JPanel.
Jan 28 2008, 09:30:41 AM PST Permalink
Several JDK Samples are NetBeans Projects
Did you know that the JDK comes with a rather massive amount of demos and samples... and that several of those are NetBeans projects? Until today, I didn't know that. I'm pretty sure that most people I know don't know that either, because otherwise we'd have published some kind of document or something similar about it, somewhere.
Here's the evidence. Below, everything with an orange icon is a NetBeans project. So, you can open the entire directory of demos and the entire directory of samples in NetBeans IDE. Plus, you can open some of the samples themselves, which you can then run right away from the IDE.
Pretty cool, I reckon.
Jan 26 2008, 04:07:18 AM PST Permalink
Brand New Book on the NetBeans Platform
Another extremely significant moment in the lifecycle of the NetBeans Platform. This morning I received the German-language book NetBeans Platform 6: Rich-Client-Entwicklung mit Java, by Heiko Bock, which was published during the past month. As co-author of Rich Client Programming: Plugging into the NetBeans Platform, I can say without any hesitation that Heiko's book is better.
The book covers many areas of the NetBeans 6 APIs, such as the Visual Library API, areas that we didn't cover in our book because at the time those APIs did not exist yet or were not "official" yet. Also, the book progresses very systematically, with many diagrams, and lots and lots of code throughout.
Here are some pics to give you an impression of the book's look and feel:
In the back of the book you'll find a CD, with Examples (Beispiele), which are all self-contained NetBeans modules and NetBeans module suites, as well as all this:
If you want a sneak preview, of the introductions, the table of contents, one of the chapters, and the index, click here. I highly recommend this book, even if you don't understand German. You understand Java, don't you?
Jan 25 2008, 05:17:13 AM PST Permalink
Wizard Driven Web Framework Plugin Development
Despite all the discussions that have been held about the many web frameworks that have enriched the world, about their contrasts and similarities, there are two things that are undeniably true but that I have never heard mentioned—probably because most people don't look at web frameworks from the perspective of tooling in general, or IDEs in particular. The first general observation from a tooling point of view is—all frameworks are pretty similar, despite their differences. From a tooling perspective, each web framework comes with a set of JARs that need to be put on an application's classpath, each web framework has certain expectations regarding the source structure of an application, each web framework needs one or more file templates, and most, but probably not all, have some kind of configuration file, be it XML, Java, or otherwise. So, from a tooling perspective, there's not much difference.
The second general observation is that those who know most about a web framework are typically not the same as those who know most about how to provide tooling. For example, you may have created a fantastic web framework, but chances are that you don't know all the Eclipse APIs, or NetBeans APIs, or whatever tool's APIs, necessary for creating the tooling support in question, assuming you want your tools to be integrated into one of the existing IDEs.
Both these general observations point to a rather obvious conclusion—since tooling for web frameworks is fairly regular and since those who know most about the framework don't necessarily know (nor should they be expected to know) much about how to integrate the framework into an IDE, it would be cool if an IDE would provide a wizard that the web framework provider would be able to click through, to create a plugin that wraps their JARs, creates some ui for the end user to select the JARs, and so on. At the end of the wizard, the web framework provider would then have a plugin, which could potentially be extended. But, at least the basis of the web framework plugin would be complete.
Today I created exactly this wizard. Here's how it works, in this case for Geert Bevin's RIFE. So, now I'm pretending I'm Geert Bevin, ignorant of all the wonders of the NetBeans APIs, but very eager to bring my web framework closer to the end user (i.e., by creating a NetBeans IDE plugin for them):
- I started out by going to the RIFE site and downloading their JAR.
- Next, I create a plugin source structure, by going to File | New Project, choosing NetBeans Modules | Module, and then clicking Next. I type "RIFESupport" as the Project Name. I click Next and then I click Finish.
- I now have my plugin's source structure. Now I right-click the project node and choose New | Other. I choose NetBeans Module Development | Web Framework Support (which is the name of the new wizard) and I click Next. I click Manage Libraries and then I use the Library Manager to create a library called RIFE. I click Add JAR/Folder and then the RIFE JAR is available. I click OK to exit the Library Manager.
- Now I select the RIFE library from the drop-down list and... I check the magical "Use in New Web Framework" checkbox, as shown below:
- I click Next. I leave all the defaults unchanged, so that RIFE will be used as the prefix for the classes and files that will be generated. I click Finish. And now what do I have? All of this:
The plugin is good to go. Module dependencies have been set, the framework has been registered in the layer, the bundle has been populated with new entries, and the Java classes are all compilable. No post processing in any shape or form is needed.
- Now I can right-click the project node and choose "Create NBM". The NBM is a binary file that I can then distribute to my users. I can say to them: "Use the Plugin Manager to install this NBM file. Then create a new web application and you will see a new entry in the final panel of the Web Application wizard." This is what it looks like, by the way:
And when the user clicks Finish above, the JAR is visible in the Libraries node, indicating it is on the application's classpath and the user can start using the framework right away:
It is not hard to imagine extensions to the above wizard, such that the wizard would generate some templates and provide other artifacts that the framework might require. The Web Framework Support wizard would let Geert Bevin select the artifacts on his disk, i.e., pick and choose the files that he wants to make available to the users of his plugin.
Then, the basis being laid, the plugin would be ready for distribution. More likely is the scenario where the plugin provider would want to tweak some parts of the plugin or provide some customizations that are relevant for the particular framework. And most frameworks have some very particular demands on an IDE's editor, such as hyperlinking from one artifact to another. (Though even there wizards could be used to generate the basic source code.)
At the end of the day, clearly, without typing a single line of code, Geert Bevin (and all the other Geert Bevins out there) would be able to use this wizard to provide their users with a plugin for their web framework. I am cleaning up some of the underlying code, but want to make the plugin that provides the wizard available soon.
Jan 24 2008, 01:32:59 PM PST Permalink
Control the Build Script Output
I've heard in various places that various people consider it a significant annoyance to see all the Ant output in the Output window when, for example, a build is performed:
Firstly, it's worth pointing out that you don't see ALL the Ant output. That's because ALL the Ant output includes the output produced by Ant targets that have names that start with a hyphen, although the Output window (as shown above) excludes all these targets. These are targets that can only be called by other targets, and not independently. In fact, if you were to see ALL the Ant output, the Output window above would have this content:
-pre-init -init-private -init-user -init-project -init-macrodef-property -do-init -post-init -init-check -init-macrodef-javac -init-macrodef-junit -init-macrodef-nbjpda -init-debug-args -init-macrodef-debug -init-macrodef-java -init-presetdef-jar init: deps-jar: -pre-pre-compile Created dir: /home/geertjan/NetBeansProjects/JavaApplication5/build/classes -pre-compile -compile-depend -do-compile Compiling 1 source file to /home/geertjan/NetBeansProjects/JavaApplication5/build/classes -post-compile compile: -pre-jar -pre-pre-jar Created dir: /home/geertjan/NetBeansProjects/JavaApplication5/dist -do-jar-with-manifest -do-jar-without-manifest -do-jar-with-mainclass -do-jar-with-libraries Building jar: /home/geertjan/NetBeansProjects/JavaApplication5/dist/JavaApplication5.jar Not copying the libraries. To run this application from the command line without Ant, try: java -jar "/home/geertjan/NetBeansProjects/JavaApplication5/dist/JavaApplication5.jar" -post-jar jar: BUILD SUCCESSFUL (total time: 0 seconds)
Secondly, to exclude EVERYTHING (i.e., ALL the targets), the org.apache.tools.ant.module.run.StandardLogger class would need to be rewritten to change this (possibly with an option in the Options window to toggle Ant output being printed/not printed).
Thirdly, however, today I came across an e-mail by Tom Wheeler to the dev@openide.netbeans.org mailing list, where he points to this FAQ that he recently wrote:
How can I override an instance in the Lookup?
I tried that exact same approach, to mask out the org.apache.tools.ant.module.run.StandardLogger. Guess what? It worked. In META-INF/Services, I have a file called org.apache.tools.ant.module.spi.AntLogger. It contains exactly this content:
org.netbeans.supersilentmode.NewLogger #-org.apache.tools.ant.module.run.StandardLogger
Now, the standard logger will not be used. Instead, I have my own new logger, in a module called org.netbeans.supersilentmode which now provides the output, which could possibly simply be a happy little tune (or a sad one, for failed builds), as shown yesterday.
Jan 23 2008, 09:00:07 AM PST Permalink
Ode to Build Scripts
I was reading the Code to Joy blog today because of an interesting blog entry about Groovy and JFugue, who are two of my friends in the programming world. It's very cool to see how they relate: simplified Java with simplified Midi! The best of both worlds. In the comments Guillaume from Groovy writes: "A couple years ago, I played with the idea of an Ant build listener that played JFugue little tunes when certain targets were started and finished, to have an audible indication of what was going on."
And then I remembered my recent explorations of the org.apache.tools.ant.module.spi.AntLogger class. That, according to the Javadoc is "a pluggable logger that can listen to AntEvents during one or more AntSessions". So, inspired by Guillaume, here is my JFugified Antlogger:
public class SuccessfulBuildLogger extends org.apache.tools.ant.module.spi.AntLogger {
@Override
public boolean interestedInSession(AntSession session) {
return true;
}
@Override
public boolean interestedInAllScripts(AntSession session) {
return true;
}
@Override
public void buildFinished(AntEvent event) {
Throwable t = event.getException();
Player player = new Player();
if (t != null) {
//There is an exception, so write message and play notes:
event.getSession().println(t.toString(), true, null);
Pattern pattern1 = new Pattern("I[60] E E F G");
player.play(pattern1);
} else {
//Play different notes when there is no exception:
Pattern pattern2 = new Pattern("I[60] G F E D");
player.play(pattern2);
}
}
}
The above implies I have a suite, which contains a library wrapper for JFugue, together with a functionality module that provides the above class. I've extended the module so that the user can use the NetBeans IDE Options window to type in a different pattern of JFugue notes (even with syntax coloring and code completion, in a JEditorPane), but I encountered a problem with JFugue that I'm trying to get fixed first. Something about a sequencer not being found. I think in the past that meant that I needed to restart, or something like that, or maybe my disk is full, or something like that.
Anyway, I now hear one pattern when the build succeeds and another when it fails, for every project in NetBeans IDE. Hurray!
Jan 22 2008, 09:40:49 AM PST Permalink
Server Plugin Framework for NetBeans IDE 6.0
Some years ago, Stepan Herold (who no longer works here) created a server skeleton as the basis of all server implementations, since all implementations have the same basic infrastructure. He even wrote the outline of a tutorial for this skeleton. Petr Hejl upgraded it to 6.0 a few months ago and today I finished fixing the tutorial so that the sources in the server skeleton match the description in the tutorial. Here's the updated 6.0 tutorial:
NetBeans Server-Skeleton Module Tutorial
The tutorial shows how to build the basis of a server plugin for NetBeans IDE. Once you have the basis, you need to add all the server-specific code on top of the basis. As far as I am aware, someone (or a group of someones) is working on a NetBeans server plugin for Jetty, Geronimo, and JOnAS (at least, I've been in touch or heard rumors in relation to all three of these). Therefore, if you're thinking about creating a server plugin for NetBeans IDE, the first thing you should do is write to dev@openide.netbeans.org to check that someone isn't already working on the server plugin in question. Then you could join in with someone else's work rather than reinventing the wheel and then pulling your hair out afterwards.
If you follow the tutorial above, you'll be pointed to a new plugin in the Plugin Portal:
http://plugins.netbeans.org/PluginPortal/faces/PluginDetailPage.jsp?pluginid=5274
The plugin provides the skeleton that you build via the tutorial. So, one approach would be to get the plugin and then use the tutorial to begin understanding how all the pieces fit together. Once you've installed the plugin, this is where you'll find the server skeleton:
Open issues in the tutorial:
- I can't find the related Javadoc.
- I don't know why several methods in MyDeploymentManager.java do not, according to the inline comments, need to be implemented. (If they're there, why should they not need to be implemented?)
- Which server implementation in the NetBeans sources can be used as "next steps" screenshot? Put the "Adding Server-Specific Code" back once it is clear what needs to go here. (In the previous version of the tutorial, there was a screenshot of the JBoss server sources, as an indication of the kind of source structure one would have at the end of the whole process, i.e., the server skeleton plus one server-specific implementation on top of it.)
- Some kind of diagram is needed to illustrate how all the pieces in the skeleton fit together.
Jan 21 2008, 10:27:11 AM PST Permalink
Stripes in NetBeans IDE
I've been meaning to try out the NetBeans support for the Stripes web framework for a while. Jocke Eriksson created a plugin for it recently and published it in the Plugin Portal. Go here to get it. (I found I needed a post-6.0 development build, instead of NetBeans IDE 6.0 final build, to install the plugin.)
The plugin extends the Frameworks panel of the New Web Application wizard:
When you click the "Example" checkbox, you get, in addition to the JARs, the sources of a Calculator application in Stripes:
It is important to note that you MUST add the commons-logging.jar to the Libraries node. It is not provided by the plugin. If you don't have your own, you can get it from the enterprise cluster in the NetBeans installation directory.
The "Example" checkbox results in the following at deployment:
While the "Layout-definition" checkbox will give you the source structure needed for the following layout at deployment:
Very nice work, I think. Great job, Jocke!
Jan 20 2008, 02:43:22 AM PST Permalink
ItsNat in NetBeans IDE
I don't know much about the new ItsNat web framework, but enough to know that it is very friendly to NetBeans IDE. When you download and unzip the distro, you'll find you have a NetBeans project. You can then open it in the IDE and deploy it, which will result in a long list of samples being available from the browser.
One of ItsNat's strengths is its IDE agnosticism (same as Wicket). In other words, there are no special artifacts, it simply uses standard Java EE artifacts such as JSP, or HTML, or servlets, or general Java classes. (And no ItsNat-specific servlet or filter needs to be registered in web.xml.) Hence, there's no actual need for a plugin for this framework. However, it would be handy if one, on completion of the web application wizard, would have all the ItsNat JARs (just 4 of them are needed) on the application's classpath.
This absolutely minimal need is interesting enough to create a plugin around, to show the simplest imaginable implementation of the NetBeans API WebFrameworkProvider class, in the context of everything else that is needed to implement it.
- Set dependencies on the following:
- Dialogs API
- External Libraries
- File System API
- Java Project Support
- Project API
- Swing Layout Extensions Integration
- UI Utilities API
- Utilities API
- Web APIs
- Create a class called ItsNatWebFrameworkProvider that extends WebFrameworkProvider . Even though ProjectClassPathExtender is deprecated, it seems to be the only way of getting the job done. Below is the whole class:
public class ItsNatWebFrameworkProvider extends WebFrameworkProvider { private ItsNatWebModuleExtender panel; //Constructor sets framework name and tip //in the Frameworks panel: public ItsNatWebFrameworkProvider() { super("ItsNat", "ItsNat"); } //You'll need to test somehow whether the //application supports the framework, for the //Project Properties dialog. For now, set to true: @Override public boolean isInWebModule(WebModule arg0) { return true; } //This method will be called from the panel. //It is the method that adds the library to the //application's classpath: public Set extendImpl(WebModule wm) { FileObject fo = wm.getDocumentBase(); Project project = FileOwnerQuery.getOwner(fo); //Name of the library that must be in the Library Manager (see step 3 below): Library lib = LibraryManager.getDefault().getLibrary("ItsNat"); if (lib != null) { ProjectClassPathExtender cpExtender = (ProjectClassPathExtender) project.getLookup().lookup(ProjectClassPathExtender.class); if (cpExtender != null) { try { cpExtender.addLibrary(lib); } catch (IOException ioe) { Exceptions.printStackTrace(ioe); } } else { Logger.getLogger("global").log(Level.INFO, "WebProjectClassPathExtender not found in the project lookup of project: " + project.getProjectDirectory().getPath()); } } return null; } //This method used to return "ConfigurationPanel", //but now returns "WebModuleExtender", which is the //lower section of the Frameworks panel. Currently, //this can't be null, even though we don't actually //need it in this case: @Override public WebModuleExtender createWebModuleExtender(WebModule wm, ExtenderController arg1) { panel = new ItsNatWebModuleExtender(this); return panel; } //In this case, no configuration files are needed //by the framework, but if they were, such as //struts-config.xml, this method would be where you //handle this: @Override public File[] getConfigurationFiles(WebModule arg0) { return null; } } - Use the "Java SE Library Descriptor wizard" to add the 4 ItsNat JARs to the module. You'll have to go to the ItsNat site and download the distribution, then add the JARs to the Library Manager so that you can use the "Java SE Library Descriptor wizard" to wrap them in the module.
This wizard will end up causing the ItsNat JARs to be installed in the Library Manager when the module is installed. Since the same module that adds the class above will also add the JARs to the Library Manager, the extendImpl method (defined above) will correctly find the library.
- Create a class called ItsNatWebModuleExtender that extends WebModuleExtender. Here is all the code:
public class ItsNatWebModuleExtender extends WebModuleExtender { private ItsNatVisualPanel component; private final ItsNatWebFrameworkProvider framework; public ItsNatWebModuleExtender(ItsNatWebFrameworkProvider framework) { this.framework = framework; getComponent(); } //Call the method in the frameworkprovider class //that will add the library to the classpath: @Override public Setextend(WebModule webModule) { return framework.extendImpl(webModule); } //Return the panel, which is done from the //constructor above: @Override public JComponent getComponent() { if (component == null) { component = new ItsNatVisualPanel(); } return component; } @Override public HelpCtx getHelp() { return null; } @Override public boolean isValid() { return true; } @Override public void update() {} @Override public void addChangeListener(ChangeListener arg0) {} @Override public void removeChangeListener(ChangeListener arg0) {} } - Use the "Wizard wizard". Make it a "Custom" and "Static" wizard, with 1 panel. Click Next and use "ItsNat" as the classname prefix. Click Finish. Refactor the generated classes to rename them to "ItsNatVisualPanel" and "ItsNatWizardPanel". Since we don't need to have the user configure anything, we can just leave these classes untouched. However, since currently null can't be returned (which would make more sense in this case), add a JLabel to the visual panel and then set the text to "No configuration needed." At least this way there'll not be nothing at all under the "ItsNat Configuration" label in the Frameworks panel.
NB: You can delete the "ItsNatWizardPanel". Why? Because there's no longer integration with the Wizard API. Instead of using the Wizard wizard, it is better to use the JPanel wizard, because all you need is a JPanel here, unlike before in the 5.5 version of the WebFrameworkProvider API class. This is a very good improvement, in my opinion. (For other changes in the 6.0 version of the WebFrameworkSupport class, click here).
- Register the framework provider class that you created in the first step above:
<folder name="j2ee"> <folder name="webtier"> <folder name="framework"> <file name="org-netbeans-modules-itsnatframeworksupport-ItsNatWebFrameworkProvider.instance"/> </folder> </folder> </folder>
Install the module. Create a new web application. In the Frameworks panel, you'll have an entry for "ItsNat". Complete the wizard... and the ItsNat JARs will be found within the Libraries node.
Jan 19 2008, 01:38:26 PM PST Permalink
Update Center for NetBeans "Contrib" Module
Register this update center in the Plugin Manager:
http://deadlock.netbeans.org/hudson/job/javadoc-nbms/lastSuccessfulBuild/artifact/nbbuild/nbms/updates.xml.gz
My understanding is that that is the update center for the "contrib" module. Or, that the "contrib" module is included, together with other update centers. Either way, the "contrib" module is included. (That's the module containing community contributed modules, often in "alpha" state, so caveat emptor.) You can then... install modules called "DocBook Projects" and "Docbook XML". Then you have a new project type (as well as templates and other features, such as HTML generation for a DocBook project and a cool image insertion feature, via a related module that is automatically installed) for DocBook (as used when writing the "Rich Client Programming: Plugging into the NetBeans Platform" book).
Another one that I found that I like is called "Project Minder":
It didn't work for me when I installed it in NetBeans IDE 6.0. But when I installed in a development build, I could use the keystroke described above, which made the editor tabs flash for documents that belong to the same project as the current document. That can be quite handy.
And if you install a module called "Extra Update Centers", you'll find yourself with many update centers, all containing modules worth exploring:

In the list above, deadlock.netbeans.org is the update center that I referred to at the start of this blog entry, so if you just install "Extra Update Centers", you'll get this one too.
Jan 18 2008, 11:56:38 AM PST Permalink
Visualizing HTML Files
I found an interesting idea in the comments to my blog entry yesterday: dabar suggests "a netbeans plugin that can allow one to preview HTML files within Netbeans so that as I edit in Netbeans, I can click on a button and then a tab showing the preview of my HTML opens that uses the DJ component internally. Any such thing in perspective soon?"
Well, I haven't managed to get that DJ Native swing project set up on Ubuntu, but sometime ago I played around with the commercial WebRenderer embedded component. I played with it some more and ended up with something that seems to be what dabar asked for. First, as in the visualizer shown yesterday, you choose a menu item called "Visualize", in an HTML file:
And then it's opened in the IDE, using the embedded WebRenderer component:
The scenario above is totally different to the one from yesterday, because here the Visual Library API isn't used at all. Still, if you're going to visualize an HTML file, the above is probably the most useful way of doing so. Go here in the NetBeans Wiki if you want to see how seriously Sun is talking about getting an embedded component into NetBeans IDE.
By the way, the above is the Connecting to a MySQL Database tutorial, which I cannot recommend highly enough.
Jan 17 2008, 09:43:35 AM PST Permalink
Source File Visualizers
The history of source file visualizers on the NetBeans Platform consists, in addition to the UML, Visual Web, and Mobility support, of three significant moments—Vadiraj Deshpande's Part 3 - XML Multiview + Visual Library, Toni Epple's A Visual Datbase Explorer for NetBeans, and Damir Tesanovic's
DDL Visualizer - Visualize sql script with NetBeans.
Of them all, I've looked most closely at the latter of the three, recently. The basic framework of a visualizer can be extracted from that blog entry. Then one needs to incorporate some way of parsing the source in question. For HTML, you'd need some kind of HTML parser, etc. (By the way, the NetBeans APIs provide an HTML parser too, did you know that? See the HTML Lexer API, and the isHyperlinkPoint class in the NetBeans Hyperlink Navigation Tutorial.) If you want to parse XML files, see the NetBeans XML Editor Extension Module Tutorial, because that tutorial includes complete code for an XML parser. For parsing Java source files, the NetBeans Java Language Infrastructure Tutorial is incredibly useful. By combining the code from that tutorial with the information from Damir Tesanovic's blog entry, I made a visualizer for Java source files:
The visual scene shows information about the constructor, methods, and fields of a class. The scene is created when you right-click inside a Java source file and choose "Visualize". Then a new TopComponent opens, with a Visual Library API scene created within it, and then the nodes are added to the scene, with the pins added to the nodes.
If you are creating a visualizer, I recommend working backwards through the three blog entries listed above. Start with the one by Damir Tesanovic, then the one by Toni Epple, and then look through the one by Vadiraj Deshpande.
Jan 16 2008, 12:16:23 AM PST Permalink


