How Do NetBeans Extension Points Work?
One of the main benefits of the NetBeans Platform is its module system. Regardless of which module system is best (my guess is there will soon be a version of NetBeans that can also run as OSGi bundles), it’s important to have a system that enables you to create a modular architecture for your application. A module system is an invitation to create a clean and maintainable architecture with defined dependencies and nice APIs with clearly defined and easy-to-use extension points. If you follow these principles, others can extend your application easily. Maybe the easiest way to provide extension points in NetBeans is via the layer.xml file (also known as the "layer file"). In a NetBeans module (also known as a "plugin"), the layer file is its central configuration file. NetBeans IDE uses the layer file to provide extension points for APIs. Objects can be created declaratively in the layer file and you can use the NetBeans Lookup API to listen for changes. You will use this approach whenever you create new Actions (which are invoked via menu items, toolbar buttons, and/or shortcut keys) or TopComponents (which provide "views" or "windows"), for example. This quick tutorial shows how you can provide your own extension points via the layer file. The source code of the sample is found here in the NetBeans Plugin Portal. Prerequisites NetBeans (I’m using 6.1, but this will also work with older/newer versions). Create a new module suite: Choose File > New Project (Ctrl-Shift-N). Under Categories, select NetBeans Modules. Under projects, select "NetBeans Platform Application" or ("Module Suite Project" in older versions) and click Next. In the Name and Location panel, type "layerextensionpoints" in Project Name. Change the Project Location to any directory on your computer, to store the application. Click Finish. Now create four modules inside the suite, called "extensionpointinterface", "messagereader", "messageprovider1" and "messageprovider2": Choose File > New Project (Ctrl-Shift-N) again. Under Categories, select NetBeans Modules. Under Projects, select Module and click Next. In the Name and Location panel, type the name in Project Name (i.e., one of the four names listed at the start of this step). The default in the wizard should be to create the module underneath the directory where you just created the suite, which is fine. Click Next. In the Basic Module Configuration panel, replace the Code Name Base with de.eppleton.. Make sure to let the IDE create a layer file, by filling out the XML Layer field with de/eppleton//layer.xml. Click Finish. Here is what you should now see: Create a Service Provider Interface We will use the module "extensionpointinterface" to define an interface that will be used by the two extension point providers as well as by the "messagereader" module, which uses the two extension points. Inside that module create interface "MessageProviderInterface" with the single method getMessage() that returns a String: public interface MessageProviderInterface { public String getMessage(); } To make this part of the public API right click the project node, select API Versioning and select the check box of de.eppleton.extensionpointinterface. Now this package is accessible to other modules. Create Service Provider Implementations Now we need some modules that implement the MessageProviderInterface. We will use the modules "messageprovider1" and "messageprovider2" to do that. To implement the interface they both need a dependency on module "extensionpointinterface". For each of them do the following: Right click the project node, click Properties and, in the Project Properties dialog, select the "Libraries" category. Click "Add Dependency". Select "extensionpointinterface", and click "OK" twice. Now that we have access to the interface in our two message providers, we can implement it. Again, for both modules, do the following: Select "New" > "Java Class". In the Wizard type "MessageProvider1" or "MessageProvider2" in the Class Name field, respectively, and select the main package in each case, for stroring the new class. Implement the interface. Each of them should provide a different String. In other words, we will provide "Hello " in MessageProvider1 and then we will provide "World!" in MessageProvider2: import de.eppleton.extensionpointinterface.MessageProviderInterface; public class MessageProvider1 implements MessageProviderInterface { public String getMessage() { return "Hello "; } } import de.eppleton.extensionpointinterface.MessageProviderInterface; public class MessageProvider2 implements MessageProviderInterface { public String getMessage() { return "World!"; } } } In order to make our MessageProviders available as services, add these entries in the layer of the two modules. Between the the layer file's tags, add the following, i.e., in the first module add the first set of tags and add the second set of tags in the second module: and This will create an instance of our MessageProviders using the standard constructor. The trick is that those instances will be accessible from outside the modules, via the NetBeans System FileSystem. Now that you have created your services, the next step shows how you can access them, without even needing to set a module dependency for them. Find and Use the Service Providers We will use the module "messagereader" to display the messages provided by our two MessageProviders. To do so we will create a TopComponent, within the "messagereader" module: In the Project Properties dialog for "messagereader", set a dependency on "extensionpointinterface", exactly as shown earlier. Right-click on the "messagereader" project node and choose "New" > "Window Component". Choose "Output", which will determine where the new window will be displayed. Make it show on startup by ticking the checkbox. Click Next. Enter "MessageReader" for the class name prefix and click "Finish". The TopComponent class will open in Design View. Drop a JScrollPane from the palette in the window and make it fill the whole area. Add a JTextArea to it, making it fit the whole area too. In the source view (i.e., click "Source" at the top of the Design view) add this to the end of the constructor: Lookup lkp = Lookups.forPath("MessageProviders"); for (MessageProviderInterface mi : lkp.lookupAll(MessageProviderInterface.class)) { jTextArea1.append(mi.getMessage()); } The code above will lookup the folder you created via the layer file (Lookups.forPath("MessageProviders")), search for classes implementing the interface (lookupAll(MessageProviderInterface.class)) and call the interface method on all instances. Let’s try it out! Run the Module Suite. You will see the window either displaying "Hello World!" or "World!Hello ". As we can see in this very simple example, the order in which the ServiceProviders are called can be important for the result. So in the next step I will show you a trick to guarantee the correct order. Sort the Service Providers The NetBeans Platform provides a way to sort layer entries. This mechanism is used, for example, to provide the order of actions in menus and toolbars. Since 6.0, this is done via the position attribute in the layer file. So this won’t work in older versions: In the layer file of the two modules, insert the "position" attributes that you see below, i.e., the first set of tags below belongs to "messageprovider1", while the second belongs to "messageprovider2": and Now the messages will always be displayed in the correct order: "Hello world!". Simply swap these values to reverse the order of the messages. When you do something like this, make sure that you choose your values large enough to add services in between the initial ones, so that there’s room for your application to grow! Now try and see what happens when you set the same value for both attributes! Summary The intention of this article is to illustrate how simple it is to implement loose coupling in a NetBeans Platform application. Note that the module that uses the services (i.e., "messagereader") has no dependencies on the modules that provide the services ("messageprovider1" and "messageprovider2"). And not only does the NetBeans Platform provide a very simple mechanism to provide and lookup services, but it also provides an easy way to declaratively order them. Appendix: Alternative Registration Mechanism, Using "META-INF/services" In the previous sections, I showed how to register the Service Providers via the layer file. As stated correctly in the comment to this article, by Casper Bang, there's an alternative way to register the service providers. Using the META-INF/services folder is the standard approach that is supported by Java since version 1.3. This additional sections below show how it works. Register the Services There are only some small changes needed to change the registration mechanism: In module messageprovider1 create a folder via the context menu of "Source Packages" > "New" > "Other" > "Folder". Enter "META_INF/services" as Folder Name; the folder will show up like a normal package. Create a file via the context menu of this new package "META-INF.services" > "New" > "Other" > "Empty file", name the file "de.eppleton.extensionpointinterface.MessageProviderInterface". Edit the file and enter "de.eppleton.messageprovider1.MessageProvider1" Copy and paste the "META_INF" folder to the "Source packages" folder of module messageprovider2 and change the content of file "de.eppleton.extensionpointinterface.MessageProviderInterface" to "de.eppleton.messageprovider2.MessageProvider2" There are different ways to lookup the services. You can either use the default lookup to do so, or you can use the ServiceLoader mechanism introduced in Java 1.6. Let's begin with the method using the default lookup. Using Lookup to retrieve ServiceProviders The global lookup will automatically provide these services for you, so only a little change is needed. In the module "messagereader", edit "MessagereaderTopComponent", and replace this line: Lookup lkp = Lookups.forPath("MessageProviders"); with this line: Lookup lkp = Lookup.getDefault(); Afterwards, you can build and run the application as before. You may notice that the order of the services has changed. As before you can fix this by adding an additional position attribute when you define the ServiceProvider. Edit both "de.eppleton.extensionpointinterface.MessageProviderInterface" files in modules messageprovider1 and messageprovider2. Add the lines "#position=10" and "#position=20" respectively. Run the application and play with the values to change the order as before. Using ServiceLoader to Locate the ServiceProviders If you're using JDK 1.6 or later, you can edit "MessagereaderTopComponent" and replace the code we've added before with the following: ServiceLoader serviceLoader = ServiceLoader.load(MessageProviderInterface.class); for (MessageProviderInterface mi : serviceLoader) { jTextArea1.append(mi.getMessage()); } Note that the position attribute is now ignored, since it's not a part of the standard JDK but an extension added by the NetBeans Platform.
August 25, 2008
·
27,515 Views
Comments
Oct 30, 2013 · Tony Thomas
For me it's the integration of HTML5 features from Project Easel with Java Web Projects. That really is the way development should be like. You've got a complete set of tools for everything, debugging of Java and JavaScript in one debugging session, live CSS Editing, testing on mobile browsers. That really is a huge step forward.
May 07, 2013 · Tony Thomas
Here's some additional code to keep the enabled state. Make toolbarButton final and add:
final Button toolbarButton = new Button();SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
final boolean enabled = instanceObj.isEnabled();
Platform.runLater(new Runnable() {
@Override
public void run() {
toolbarButton.setDisable(!enabled);
}
});
}
});
instanceObj.addPropertyChangeListener(new PropertyChangeListener() {
@Override
public void propertyChange(final PropertyChangeEvent evt) {
if (evt.getPropertyName().equals("enabled")) {
Platform.runLater(new Runnable() {
@Override
public void run() {
toolbarButton.setDisable(!(Boolean) evt.getNewValue());
}
});
}
}
});
May 07, 2013 · Tony Thomas
Hi Geertjan,
I'm reading your series on adding JavaFX to NetBeans in many places inside NB Platform. Great idea! I also tried this one, but it seems whenever I press a button the application stalls.
Edit: Ah, found it: it's the invokeAndWait. Replace with invokeLater and it works fine!
Thanks,
Toni
Jan 24, 2012 · Tony Thomas
Hi Leonard,
have you tried the NetBeans Project I uploaded, or did you implement it yourself? In the latter case make sure that getUserAgentStylesheet returns the correct path to the css file.
Jan 24, 2012 · Toni Epple
Hi Leonard,
have you tried the NetBeans Project I uploaded, or did you implement it yourself? In the latter case make sure that getUserAgentStylesheet returns the correct path to the css file.
Jan 08, 2012 · Tony Thomas
It was great to meet the Javeleon Team at J1. Keep up the good work!
--Toni
Jan 02, 2012 · Mr B Loid
Hi Sergey, it's funny how different our impressions are :-). In my opinion JavaFX is on the right track for the first time. JavaFX will be Open Source and available on all major platforms in 2012. The CSS-styling is excellent. With FXML we've got a declarative way of defining UIs. And finally the integration with Swing gives developers a nice path of adoption and a way to provide missing functionality (Window Systems, etc.).
The only thing missing is decent tooling and a couple of controls. But the number ofavailable controls has increased significantly already and a DateChooser will probably be available soon ("This is a control that is planned for a future release of JavaFX").
Jan 02, 2012 · Mr B Loid
Hi Sergey, it's funny how different our impressions are :-). In my opinion JavaFX is on the right track for the first time. JavaFX will be Open Source and available on all major platforms in 2012. The CSS-styling is excellent. With FXML we've got a declarative way of defining UIs. And finally the integration with Swing gives developers a nice path of adoption and a way to provide missing functionality (Window Systems, etc.).
The only thing missing is decent tooling and a couple of controls. But the number ofavailable controls has increased significantly already and a DateChooser will probably be available soon ("This is a control that is planned for a future release of JavaFX").
Jan 02, 2012 · Mr B Loid
Hi Sergey, it's funny how different our impressions are :-). In my opinion JavaFX is on the right track for the first time. JavaFX will be Open Source and available on all major platforms in 2012. The CSS-styling is excellent. With FXML we've got a declarative way of defining UIs. And finally the integration with Swing gives developers a nice path of adoption and a way to provide missing functionality (Window Systems, etc.).
The only thing missing is decent tooling and a couple of controls. But the number ofavailable controls has increased significantly already and a DateChooser will probably be available soon ("This is a control that is planned for a future release of JavaFX").
Jan 02, 2012 · Mr B Loid
Hi Sergey, it's funny how different our impressions are :-). In my opinion JavaFX is on the right track for the first time. JavaFX will be Open Source and available on all major platforms in 2012. The CSS-styling is excellent. With FXML we've got a declarative way of defining UIs. And finally the integration with Swing gives developers a nice path of adoption and a way to provide missing functionality (Window Systems, etc.).
The only thing missing is decent tooling and a couple of controls. But the number ofavailable controls has increased significantly already and a DateChooser will probably be available soon ("This is a control that is planned for a future release of JavaFX").
Jan 02, 2012 · Toni Epple
Hi Sergey, it's funny how different our impressions are :-). In my opinion JavaFX is on the right track for the first time. JavaFX will be Open Source and available on all major platforms in 2012. The CSS-styling is excellent. With FXML we've got a declarative way of defining UIs. And finally the integration with Swing gives developers a nice path of adoption and a way to provide missing functionality (Window Systems, etc.).
The only thing missing is decent tooling and a couple of controls. But the number ofavailable controls has increased significantly already and a DateChooser will probably be available soon ("This is a control that is planned for a future release of JavaFX").
Jan 02, 2012 · Toni Epple
Hi Sergey, it's funny how different our impressions are :-). In my opinion JavaFX is on the right track for the first time. JavaFX will be Open Source and available on all major platforms in 2012. The CSS-styling is excellent. With FXML we've got a declarative way of defining UIs. And finally the integration with Swing gives developers a nice path of adoption and a way to provide missing functionality (Window Systems, etc.).
The only thing missing is decent tooling and a couple of controls. But the number ofavailable controls has increased significantly already and a DateChooser will probably be available soon ("This is a control that is planned for a future release of JavaFX").
Jan 02, 2012 · Toni Epple
Hi Sergey, it's funny how different our impressions are :-). In my opinion JavaFX is on the right track for the first time. JavaFX will be Open Source and available on all major platforms in 2012. The CSS-styling is excellent. With FXML we've got a declarative way of defining UIs. And finally the integration with Swing gives developers a nice path of adoption and a way to provide missing functionality (Window Systems, etc.).
The only thing missing is decent tooling and a couple of controls. But the number ofavailable controls has increased significantly already and a DateChooser will probably be available soon ("This is a control that is planned for a future release of JavaFX").
Jan 02, 2012 · Toni Epple
Hi Sergey, it's funny how different our impressions are :-). In my opinion JavaFX is on the right track for the first time. JavaFX will be Open Source and available on all major platforms in 2012. The CSS-styling is excellent. With FXML we've got a declarative way of defining UIs. And finally the integration with Swing gives developers a nice path of adoption and a way to provide missing functionality (Window Systems, etc.).
The only thing missing is decent tooling and a couple of controls. But the number ofavailable controls has increased significantly already and a DateChooser will probably be available soon ("This is a control that is planned for a future release of JavaFX").
Dec 15, 2011 · Gerd Storm
Hierarchical ClassLoaders are always sources of delight for developers. Especially when dealing with two independent classloader hierarchies, each aiming for world domination like here. I just got a mail from a user trying to use the above example from inside a TopComponent, and it doesn't work. Obviously the Module ClassLoader in NetBeans is updated in a way that conflicts with the example.
To fix it you need to switch to the EJBUtils classloader as explained in the TroubleShooting section:
Thread.currentThread().setContextClassLoader(com.sun.ejb.EJBUtils.class.getClassLoader());
This will solve the Lookup part of the problem and leave you with a new ClassNotFoundException, because EJBUtils classloader can't see the GreeterBeanRemote. To fix it, put your HelloWorldEJB.jar on the application classpath in the project.properties:
run.args.extra=-J-da -J-Dorg.omg.CORBA.ORBInitialHost=localhost -J-Dorg.omg.CORBA.ORBInitialPort=3700 \
-cp <path to your NetBeansProjects>/simple3tier/GreeterClientPlatform/HelloWorldEJB/release/modules/ext/HelloWorldEJB.jar:<path to yourglassfish-3.1.1>/glassfish/lib/gf-client.jar
Then it should work again...
Oct 07, 2011 · Gerd Storm
Hi Kim,
which version of Glassfish and NetBeans do you use? Did you also follow the advice in the troubleshooting section?
Toni
Oct 07, 2011 · Gerd Storm
Hi Kim,
which version of Glassfish and NetBeans do you use? Did you also follow the advice in the troubleshooting section?
Toni
Oct 07, 2011 · Gerd Storm
Hi Kim,
which version of Glassfish and NetBeans do you use? Did you also follow the advice in the troubleshooting section?
Toni
Sep 06, 2011 · Gerd Storm
Right, but the package-appclient copies everything for you and you should be able to put it on the classpath using the endorsed mechanism. Unpack the jar created by that and add everything you need from there (the jars) to your application installer. Then you can use the endorsed (-J-Djava.endorsed.dirs=${GFCLIENT_PATH}) mechanism in your app.conf to put it on the application classpath. This way you should be able to deploy it together with your client.
Sep 06, 2011 · Gerd Storm
Right, but the package-appclient copies everything for you and you should be able to put it on the classpath using the endorsed mechanism. Unpack the jar created by that and add everything you need from there (the jars) to your application installer. Then you can use the endorsed (-J-Djava.endorsed.dirs=${GFCLIENT_PATH}) mechanism in your app.conf to put it on the application classpath. This way you should be able to deploy it together with your client.
Sep 06, 2011 · Gerd Storm
Right, but the package-appclient copies everything for you and you should be able to put it on the classpath using the endorsed mechanism. Unpack the jar created by that and add everything you need from there (the jars) to your application installer. Then you can use the endorsed (-J-Djava.endorsed.dirs=${GFCLIENT_PATH}) mechanism in your app.conf to put it on the application classpath. This way you should be able to deploy it together with your client.
Sep 06, 2011 · Gerd Storm
Right, but the package-appclient copies everything for you and you should be able to put it on the classpath using the endorsed mechanism. Unpack the jar created by that and add everything you need from there (the jars) to your application installer. Then you can use the endorsed (-J-Djava.endorsed.dirs=${GFCLIENT_PATH}) mechanism in your app.conf to put it on the application classpath. This way you should be able to deploy it together with your client.
Sep 06, 2011 · Gerd Storm
Right, but the package-appclient copies everything for you and you should be able to put it on the classpath using the endorsed mechanism. Unpack the jar created by that and add everything you need from there (the jars) to your application installer. Then you can use the endorsed (-J-Djava.endorsed.dirs=${GFCLIENT_PATH}) mechanism in your app.conf to put it on the application classpath. This way you should be able to deploy it together with your client.
Sep 06, 2011 · Gerd Storm
Right, but the package-appclient copies everything for you and you should be able to put it on the classpath using the endorsed mechanism. Unpack the jar created by that and add everything you need from there (the jars) to your application installer. Then you can use the endorsed (-J-Djava.endorsed.dirs=${GFCLIENT_PATH}) mechanism in your app.conf to put it on the application classpath. This way you should be able to deploy it together with your client.
Sep 06, 2011 · Gerd Storm
Right, but the package-appclient copies everything for you and you should be able to put it on the classpath using the endorsed mechanism. Unpack the jar created by that and add everything you need from there (the jars) to your application installer. Then you can use the endorsed (-J-Djava.endorsed.dirs=${GFCLIENT_PATH}) mechanism in your app.conf to put it on the application classpath. This way you should be able to deploy it together with your client.
Sep 06, 2011 · Gerd Storm
Right, but the package-appclient copies everything for you and you should be able to put it on the classpath using the endorsed mechanism. Unpack the jar created by that and add everything you need from there (the jars) to your application installer. Then you can use the endorsed (-J-Djava.endorsed.dirs=${GFCLIENT_PATH}) mechanism in your app.conf to put it on the application classpath. This way you should be able to deploy it together with your client.
Sep 05, 2011 · Gerd Storm
Hi Geoff,
library wrappers won't work. They are only used for compilation ( Actually the above example should be cleaned up, because also the library modules we created here are not needed at runtime )
To deploy on a remote client, you need to carry the dependencies with you. Most importantly, you'll have to take a look at the manifests of the jars and make sure that all dependencies are there. E.g. gf-client.jar has these dependencies:
Class-Path: ../modules/woodstox-osgi.jar ../modules/jtype.jar ../modul
es/tools.jar ../modules/glassfish-corba-asm.jar ../modules/glassfish-
corba-codegen.jar ../modules/glassfish-corba-csiv2-idl.jar ../modules
/glassfish-corba-internal-api.jar ../modules/glassfish-corba-newtimer
.jar ../modules/glassfish-corba-omgapi.jar ../modules/glassfish-corba
-orb.jar ../modules/glassfish-corba-orbgeneric.jar ../modules/auto-de
pends.jar ../modules/config.jar ../modules/config-types.jar ../module
s/hk2.jar ../modules/hk2-core.jar ../modules/osgi-adapter.jar ../modu
les/grizzly-comet.jar ../modules/grizzly-config.jar ../modules/grizzl
y-framework.jar ../modules/grizzly-http.jar ../modules/grizzly-http-s
ervlet.jar ../modules/grizzly-lzma.jar ../modules/grizzly-portunif.ja
r ../modules/grizzly-rcm.jar ../modules/grizzly-utils.jar ../modules/
grizzly-websockets.jar ../modules/javax.mail.jar ../modules/pkg-clien
t.jar ../modules/jaxb-osgi.jar ../modules/activation.jar ../modules/e
l-api.jar ../modules/jaxrpc-api-osgi.jar ../modules/endorsed/jaxb-api
-osgi.jar ../modules/junit.jar ../modules/javax.persistence.jar ../mo
dules/org.eclipse.persistence.antlr.jar ../modules/org.eclipse.persis
tence.asm.jar ../modules/org.eclipse.persistence.core.jar ../modules/
org.eclipse.persistence.jpa.jar ../modules/org.eclipse.persistence.jp
a.modelgen.jar ../modules/org.eclipse.persistence.oracle.jar ../modul
es/endorsed/javax.annotation.jar ../modules/javax.ejb.jar ../modules/
javax.enterprise.deploy.jar ../modules/javax.jms.jar ../modules/javax
.management.j2ee.jar ../modules/javax.resource.jar ../modules/javax.s
ecurity.auth.message.jar ../modules/javax.security.jacc.jar ../module
s/javax.servlet.jar ../modules/javax.servlet.jsp.jar ../modules/javax
.transaction.jar ../modules/simple-glassfish-api.jar ../modules/admin
-core.jar ../modules/admin-util.jar ../modules/config-api.jar ../modu
les/monitoring-core.jar ../modules/acc-config.jar ../modules/gf-clien
t-module.jar ../modules/gms-bootstrap.jar ../modules/amx-core.jar ../
modules/amx-j2ee.jar ../modules/annotation-framework.jar ../modules/c
ommon-util.jar ../modules/container-common.jar ../modules/glassfish-a
pi.jar ../modules/glassfish-ee-api.jar ../modules/glassfish-naming.ja
r ../modules/internal-api.jar ../modules/scattered-archive-api.jar ..
/modules/stats77.jar ../modules/connectors-inbound-runtime.jar ../mod
ules/connectors-internal-api.jar ../modules/connectors-runtime.jar ..
/modules/work-management.jar ../modules/glassfish.jar ../modules/kern
el.jar ../modules/logging.jar ../modules/deployment-common.jar ../mod
ules/deployment-javaee-core.jar ../modules/dol.jar ../modules/ejb-con
tainer.jar ../modules/ejb-internal-api.jar ../modules/ldapbp-repackag
ed.jar ../modules/libpam4j-repackaged.jar ../modules/management-api.j
ar ../modules/flashlight-agent.jar ../modules/flashlight-framework.ja
r ../modules/gmbal.jar ../modules/ha-api.jar ../modules/class-model.j
ar ../modules/asm-all-repackaged.jar ../modules/bean-validator.jar ..
/modules/jms-core.jar ../modules/endorsed/webservices-api-osgi.jar ..
/modules/webservices-extra-jdk-packages.jar ../modules/webservices-os
gi.jar ../modules/orb-connector.jar ../modules/orb-iiop.jar ../module
s/eclipselink-wrapper.pom ../modules/jpa-connector.jar ../modules/per
sistence-common.jar ../modules/cmp-internal-api.jar ../modules/appcli
ent.security.jar ../modules/ejb.security.jar ../modules/jaspic.provid
er.framework.jar ../modules/security.jar ../modules/ssl-impl.jar ../m
odules/websecurity.jar ../modules/webservices.security.jar ../modules
/jta.jar ../modules/jts.jar ../modules/transaction-internal-api.jar .
./modules/el-impl.jar ../modules/jsp-impl.jar ../modules/war-util.jar
../modules/web-cli.jar ../modules/web-core.jar ../modules/web-embed-
api.jar ../modules/web-glue.jar ../modules/web-gui-plugin-common.jar
../modules/web-naming.jar ../modules/jsr109-impl.jar ../modules/mimep
ull.jar ../modules/tiger-types.jar ../modules/shoal-gms-api.jar ../..
/mq/lib/imq.jar ../../mq/lib/imqadmin.jar ../../mq/lib/imqutil.jar ..
/../mq/lib/fscontext.jar ../lib/install/applications/jmsra/imqjmsra.j
ar ../lib/install/applications/__ds_jdbc_ra/__ds_jdbc_ra.jar ../lib/i
nstall/applications/__cp_jdbc_ra/__cp_jdbc_ra.jar ../lib/install/appl
ications/__xa_jdbc_ra/__xa_jdbc_ra.jar ../lib/install/applications/__
dm_jdbc_ra/__dm_jdbc_ra.jar ../../javadb/lib/derby.jar ../../javadb/l
ib/derbyclient.jar ../../javadb/lib/derbynet.jar ../../javadb/lib/der
bytools.jar ../../javadb/lib/derbyrun.jar ../lib/install/applications
/jaxr-ra/jaxr-ra.jar
You might want to have a look at the "package-appclient" command which is used for Application Client Components as defined in the Java EE Spec:
http://download.oracle.com/docs/cd/E18930_01/html/821-2433/package-appclient-1m.html#scrolltoc
It creates a single jar file that you can unpack on the client. It contains a directory appclient/glassfish with everything you need, including the dependencies.
( Instead of appserv-rt.jar and javaee.jar you should then put gf-client.jar on the classpath. In glassfish 3 appserv-rt.jar is mainly a wrapper around gf-client.jar anyway, and javaee.jar is in gf-client.jar's dependencies. )
May 02, 2011 · Mr B Loid
Hi Geertjan,
great tutorial!
Right now the two main benefits of you implementation are that you're shielding the UI from the implementation details (JPA), and you can add additional capabilities without breaking backward compatibility by using Composition instead of inheritance.
Maybe you could enhance it by further decoupling:
If I understand it correctly, there's no way to declaratively swap implementations, because RootNode knows the CustomerQuery class, which in turn knows DAO, which knows the PU and everything else, right? So in the end the Ui is still coupled to the implementation.
You could place Customer and Discount in a separate Module from the Derby.jar, so they can be reused without JPA. CustomerQuery could implement an SPI (ICustomerQuery) and register itself as a service implementing the interface in default Lookup. Then RootNode can retrieve the registered Service from the Lookup to CRUD the DataObjects (Customer, Discount) and you could easily replace "JPADerbyCustomerQuery" with a different impl (e.g. based on serializing to files).
Cheers,
Toni
Apr 13, 2011 · Gerd Storm
Hi Cyrille-alexandre,
thanks for your interest. There are sometimes problems with the mails sent by Joomla to providers like gmail and yahoo. I've approved you manually. Can you checkif you can log in now?
Cheers,
Toni
Apr 13, 2011 · Gerd Storm
Hi Cyrille-alexandre,
thanks for your interest. There are sometimes problems with the mails sent by Joomla to providers like gmail and yahoo. I've approved you manually. Can you checkif you can log in now?
Cheers,
Toni
Apr 13, 2011 · Gerd Storm
Hi Cyrille-alexandre,
thanks for your interest. There are sometimes problems with the mails sent by Joomla to providers like gmail and yahoo. I've approved you manually. Can you checkif you can log in now?
Cheers,
Toni
Oct 13, 2010 · ah fei
I'm trying to write a NB Platform based client. Registered it as an aplication with read/write access.
ReadingTimelines works fine, but when I'm trying tosend a status update I get through sometimes (twice so far, but most of the time the Basic authenticator pops up asking for my credentials. Any idea why that happens, or what I can do about it?
My calls look like this:
UpdateStatusClient client = new UpdateStatusClient("xml");
client.login();
client.initOAuth();
client.updateStatus(Object.class, "Testing my NetBeans based Twitter client", null);
thanks,
Toni
Jul 15, 2010 · Tony Thomas
Hi Vincent,
You need to import your self-signed certificate to the truststore.
Putting the credentials in the URL was just the simplest way of doing it as a proof of concept. Normally you would register your own java.net.Authenticator that silently returns the correct username and password.
cheers
Toni
Apr 11, 2010 · Michael Malone
Hi Zoran, that's excellent news. Would be great to see this kind of synergy between independent projects.
Greetings from Bergen
--Toni
Apr 07, 2010 · Toni Epple
Hi Nicholas,
sorry I didn't see your comments earlier. Thanks for answering Jirka, I've fixed the snippets.
--Toni
Apr 07, 2010 · Toni Epple
Hi Nicholas,
sorry I didn't see your comments earlier. Thanks for answering Jirka, I've fixed the snippets.
--Toni
Apr 07, 2010 · Toni Epple
Hi Nicholas,
sorry I didn't see your comments earlier. Thanks for answering Jirka, I've fixed the snippets.
--Toni
Apr 07, 2010 · Toni Epple
Hi Nicholas,
sorry I didn't see your comments earlier. Thanks for answering Jirka, I've fixed the snippets.
--Toni
Apr 07, 2010 · Toni Epple
Hi Nicholas,
sorry I didn't see your comments earlier. Thanks for answering Jirka, I've fixed the snippets.
--Toni
Apr 07, 2010 · Toni Epple
Hi Nicholas,
sorry I didn't see your comments earlier. Thanks for answering Jirka, I've fixed the snippets.
--Toni
Apr 07, 2010 · Toni Epple
Hi Nicholas,
sorry I didn't see your comments earlier. Thanks for answering Jirka, I've fixed the snippets.
--Toni
Mar 09, 2010 · Mr B Loid
Which version of Java do you use? Heavyweight-Lightweight shouldn't be a problem anymore with JDK > u12:
http://java.sun.com/developer/technicalArticles/GUI/mixing_components/index.html
Feb 22, 2010 · Geertjan Wielenga
I was wondering about fcom and bcom as well, but actually bcom and fcom have a secret :-)! If you look at the definition of the bcom template you'll see it's defined as:
/*${selection}*/
The interesting part is ${selection}. If you use this in a template, the system will know this is a "Surround with" quickfix. It means whenever you select some text in the editor a lightbulb will appear and offer you to surround your selection with your text, in this case it will surround it with /* */ and comment it out.
Try it out! In the Editor select some text. A lightbulb will appear with quick fix "Surround with /* */".
fcom works the same way. It only makes real sense if you select something and then make it foldable by clicking the lightbulb.
Feb 22, 2010 · Geertjan Wielenga
I was wondering about fcom and bcom as well, but actually bcom and fcom have a secret :-)! If you look at the definition of the bcom template you'll see it's defined as:
/*${selection}*/
The interesting part is ${selection}. If you use this in a template, the system will know this is a "Surround with" quickfix. It means whenever you select some text in the editor a lightbulb will appear and offer you to surround your selection with your text, in this case it will surround it with /* */ and comment it out.
Try it out! In the Editor select some text. A lightbulb will appear with quick fix "Surround with /* */".
fcom works the same way. It only makes real sense if you select something and then make it foldable by clicking the lightbulb.
Dec 16, 2009 · Mr B Loid
As a long time NetBeans user and occasional user of Eclipse I can agree to point 4 in your list, MDA really is cool in Eclipse and a free and good plugin for that is missing in NetBeans.
Mylin is cool as well, but it's not unique. With Cubeon there's an extremely well integrated Task oriented interface for NetBeans as well. For the other 3 topics it probably depends a lot of what you're used to.
An Update Center probably wouldn't end up on my personal list of Killer features anyway, but I wonder how the Eclipse one would be superior to others, like e.g. the one in NetBeans, except for the fact that it's better hidden in Eclipse ;-). The one in NetBeans just works, the one in Eclipse as well, that's what I'd expect.
Regarding the smaller features what I don't like about Eclipse is Maven & subversion support. Both are really way behind in Eclipse. I'm working in a project right now where the standard IDE is Eclipse. I started to work on it with Eclipse but ended up doing so much on the commandline or with external tools for both maven and subversion tasks. I switched back to NetBeans very soon and never had to leave the IDE for this since.
Also I wouldn't agree that Enterprise support is better in Eclipse. And especially if Web Development is not your usual type of development NetBeans definitely has the better out-of-the-box experience, since it contains everything you need. Install the IDE and simply start coding and enjoy the deploy on save to the embedded glassfish. No need to install a plugin or a server.
Nov 13, 2009 · Gerd Storm
Thanks for this posting. It's a very good idea to point out that we can take the best parts of each of both products to create someting really great. The intention of a merger is to create synergies and add the parts that are missing in one company (e.g it's IDE) by parts from the other company (e.g. it's IDE). Then we can focus on competing with our real competitor ;-). Swing rocks!
Great article!
--Toni
Oct 19, 2009 · Mr B Loid
Interesting thoughts, but there is one interesting aspect you may have missed in your analysis. JetBrains has started to market IntelliJ as a platform for creating your own IDE on top of the IDEA core (http://www.jetbrains.org/display/IJOS/FAQ). This works best with an Open Source project. And they can sell support and training for this. So besides reaching more developers, which I think they will, they're adressing a new market.
I also don't have insights how well JetBrains is doing, but they are currently looking for new developers (http://www.jetbrains.com/company/jobs/index.html). When such a small company is hiring 6 people it's an indication that they are doing rather well.
And for the people who bought licenses in the past they've still got the Ultimate edition with all the interesting parts for Web Development who probably won't go away.
So in summary I don't think that IDEA is going away in the near future.
Oct 15, 2009 · Mr B Loid
Nice article, but there is a misconception in this sentence:
"[...] that Oracle may choose to officially support it's own platform, JDeveloper, instead of NetBeans"
JDeveloper is -unlike NetBeans- just an IDE and not a platform. So -unlike NetBeans- you cannot create applications on top of JDevelopers core. With NetBeans you actually get two things, an IDE and a stable and mature Desktop Application Framework that is used by many companies. There are many more than the ones Geertjan has published that we aren't allowed to talk about.
So while the whole NetBeans IDE versus JDeveloper story is very interesting, I'm even more interested in news about the platform.
I'm not really worried about the future of the platform though. There are many companies using it and there are many individuals and even some companies living on selling support for it. There's a vital community that is capable and willing to maintain and enhance the platform, but it would be good to hear from Oracle what they think. It would be great to know if they see the value of the platform and maybe invest in productizing it (since they are good at that), but I'm not sure if Oracle knows the difference between IDE and Platform. Actually I'm quite sure they don't, since even many people inside SUN don't know about the Platform...
Sep 30, 2009 · Peter Stofferis
Eclipse RCP is always an option, and there are many applications using Eclipse. In the scientific context with it's specific visualization needs I would personally nevertheless always prefer to work with a Swing based platform.
In my experience SWT and Eclipse RCP has it's focus on business applications with standard forms and tables, while Swing is more flexible and easier to use when you need non-standard components and visualizations, and that's why teams with such needs tend to choose Swing (like e.g. described here by Northrop Grumman: http://blogs.sun.com/geertjan/entry/netbeans_eclipse_comparison_slides_java).
But I don't want to start a flamewar about SWT and Swing either :-). I'm sure that there are some nice Eclipse RCP based applications in this field as well, and maybe Bioclipse is a good example.
Sep 05, 2009 · Peter Stofferis
Good idea to post an overview:
Trove is one of my favorites. Their collections for primitives are great for tuning memory usage of an application. You can get amazing improvements by drop-in replacements
--Toni
Jul 29, 2009 · Regnard Kreisler Raquedan
I absolutely agree with everything you say about the problem zones of JavaFX.
My personal opinion is that the lack of integration with Swing is the biggest issue. I'm quite sure that the JavaFX team has been asked thousands of times since JavaFX was released "why can't I embedd it in Swing?". It may be difficult, but it needs to be done. And it needs to be done now, not in an unforeseeable future.
The message sent out to the Swing developers by the lack of two-way integration and by the fact that most Swing developers were moved to JavaFX is that Swing is going to be deprecated with no replacement. Maybe the intention is to make everyone move to JavaFX immediately. But with the lack of controls and even worse the lack of a module system that's obviously not a choice even for medium sized apps.
Embedding on the other hand would allow Swing developers to keep OSGi or the NetBeans Module System for managing the complexity and dynamics of applications and use JavaFX for the UI (which I think is it's domain). We could start by using it for visualizations and then slowly move the whole UI to JavaFX as more controls become available. This is where JavaFX would really have an edge over all it's competitors.
Just one example: One of the applications missing in your list is NDSatCom's application Network Management Systems (Winners of the Duke's Choice Award 2009). I know those guys would love to add some cool JavaFX visuals, but will they port an application with Millions of lines of code and more than a thousand modules to JavaFX and loose modularity for doing that? And there are tons of applications and thousands of developers who would, like them, love to use it but simply can't.
When it comes to Swing developers JavaFX so far has been a PR disaster. Still I think it's not too late. I hope that your article will start a discussion and helps move things in the right direction. Really, my heart is bleeding when I see this cool technology heading in the wrong direction.
Toni
Jul 01, 2009 · Naing Win
Great Article, it has all the details that are missing in the release notes...
Thanks!
--Toni
Mar 26, 2009 · Mr B Loid
Mar 26, 2009 · Mr B Loid
Mar 19, 2009 · Mark Levison
Feb 17, 2009 · Dushan Hanuska
Hi Harris, reading your tip I had an idea how you can utilize the iconBase approach for some advanced branding :-) Cheers
Toni
Oct 14, 2008 · Nigel Wong
You're missing the main advantage of the NetBeans approach:
"Portability & Standards conformance: As long as you're using ServiceLoader you can reuse your jars without the platform and without any changes."
As Geertjan said: NetBeans supports the standard defined in the JAR specification, therfore you can take your API and IMPL jars and reuse them everywhere.
Cheers,
Toni
Sep 05, 2008 · Lebon Bon Lebon
Sep 05, 2008 · Toni Epple
Aug 25, 2008 · Lebon Bon Lebon
Sure, there are two ways to make a ServiceProvider available. The /META-INF/services approach is part of the JAR File Specification and a standard approach that can also be used without NetBeans.
Nevertheless there are small differences: With the standard approach the ServiceProvider needs a standard constructor, while the Services Folder can also use a static instanceCreate method ( e.g. a getDefault() ).
The second difference is that you can sort the ServiceProvider instances as shown here. This is not possible with the standard approach. (Well, to be honest in NetBeans it is possible, because there is an extension to the standard approach to let you add a position attribute to the configuration file )
Toni
Aug 25, 2008 · Toni Epple
Sure, there are two ways to make a ServiceProvider available. The /META-INF/services approach is part of the JAR File Specification and a standard approach that can also be used without NetBeans.
Nevertheless there are small differences: With the standard approach the ServiceProvider needs a standard constructor, while the Services Folder can also use a static instanceCreate method ( e.g. a getDefault() ).
The second difference is that you can sort the ServiceProvider instances as shown here. This is not possible with the standard approach. (Well, to be honest in NetBeans it is possible, because there is an extension to the standard approach to let you add a position attribute to the configuration file )
Toni
May 13, 2008 · admin