This is my blog for software development. I am a professional software engineer. I work on various projects. I also contribute to open-source projects such as www.netbeans.org
Showing posts with label NetBeans. Show all posts
Showing posts with label NetBeans. Show all posts
2016-09-13
"Run Focused Test Method" and "Debug Focused Test Method" for NetBeans Groovy Support Now in main-golden and Nightly Builds
If you use NetBeans nightly builds you will now have this functionality. Try it out, and let me know if you experience any issues.
2016-09-11
"Run Focused Test Method" and "Debug Focused Test Method" for NetBeans Groovy Support in main and main-silver Hg Repositories
The ability to run or debug a single Groovy test from the IDE has now been merged into the main and main-silver Hg repositories for the NetBeans IDE. I assume this will work into main-golden and thus the nightly dev builds soon. I will post another update once that happens.
Labels:
Computer Programming,
FOSS,
Groovy,
NetBeans,
Swing
2016-09-06
Adding "Run Focused Test Method" and "Debug Focused Test Method" to NetBeans Groovy Support
If you are a NetBeans and Groovy fan, then you have probably noticed over the years you can not execute nor debug an individual test method if using Groovy for testing. I have contributed to other parts of the IDE at various times, but hadn't looked into the Groovy support until recently. I finally had enough executing all tests in a file.
The code isn't necessarily difficult. For what I am adding it is slightly complicated due to NetBeans Groovy support module dependencies, and some things needing to be broken out a little differently. For now I am using reflection to access what I need, and that will work fine enough in the near term. Long term I plan to work with other community contributors to clean things up.
Another thing which makes coding this interesting is a mismatch between NetBeans notion of an offset into a source file and the Groovy ASTs notion of it. NetBeans uses a cursor or single integer value offset, and Groovy uses the notion of a line and column. So, some translation and AST traversal is needed to pinpoint the selected method. Standard editor things, but of note for this fix.
Too, the previous code halfway attempted to do this, but it seems some copy and paste happened between the Java and Groovy support as that code was using Java specific features which will not exactly work as Java is a subset of Groovy. The Groovy AST classes along with a little translation fixed it right up.
The changes should make their way into the code base soon. I have things working locally. I am now cleaning things up. I figure I will tackle other items which bother me about NetBeans Groovy support now that I am getting into it.
I will update once merged in, so check back.
The code isn't necessarily difficult. For what I am adding it is slightly complicated due to NetBeans Groovy support module dependencies, and some things needing to be broken out a little differently. For now I am using reflection to access what I need, and that will work fine enough in the near term. Long term I plan to work with other community contributors to clean things up.
Another thing which makes coding this interesting is a mismatch between NetBeans notion of an offset into a source file and the Groovy ASTs notion of it. NetBeans uses a cursor or single integer value offset, and Groovy uses the notion of a line and column. So, some translation and AST traversal is needed to pinpoint the selected method. Standard editor things, but of note for this fix.
Too, the previous code halfway attempted to do this, but it seems some copy and paste happened between the Java and Groovy support as that code was using Java specific features which will not exactly work as Java is a subset of Groovy. The Groovy AST classes along with a little translation fixed it right up.
The changes should make their way into the code base soon. I have things working locally. I am now cleaning things up. I figure I will tackle other items which bother me about NetBeans Groovy support now that I am getting into it.
I will update once merged in, so check back.
Labels:
Computer Programming,
FOSS,
Groovy,
NetBeans,
Swing
2012-02-22
Java Module Systems The EDT and ClassLoader Issues
As mentioned in Java Module Systems SwingWorker, Runnable, Thread and ClassLoader Issues, where invokeLater and invokeAndWait are discussed, the EDT is a separate thread with its own context classloader, and this is most likely the system classloader. It is important to understand this.
If you create a user interface in a modular system, such as the NetBeans RCP, upon a user action logic will run on the EDT, and if in that logic you access classes by name, create new instances of them, or perform casts and those classes could possibly be in more than one module, you will run into classloader collision issues. I will restate here that this also affects EventQueue.invokeLater and invokeAndWait.
Along with collision issues, you need to also understand that certain class access may be blocked depending on the classloader being used once you set the thread context classloader. Imagine you have some classes your current UI components classloader can see; they are part of its dependencies. Those dependencies classloaders may not have access to each other. If you use a classloader which does not have access to some classes to set the thread context classloader, then access will be blocked to those classes, and your logic will not work.
Suppose there is a button and it has an action listener attached to it. It could be written as:
The above could make an assumption it is the only possible some.specificpackage.MyActionListener to be within any module in the system at one time were it to use MyActionListener.class.getClassLoader(), and if that were not to be the case, you would need to get creative in the manner in which you get a classloader into this object.
The code does slightly guard against that since it uses getClass().getClassLoader() versus the static MyActionListener.class.getClassLoader() which would unequivocally infer it is expected to be the only one in the system per the way the class and classloader are being accessed. This means the instances classloader will be used, and if the instance was created using a specific classloader, and it is correct, then the code will simply work. If the classloader is not correct, then the logic which created the instance will need to be fixed.
This is another subtle way in which classloader issues can creep into the domain of concurrency and Java modular systems. You can use this information to ensure you have protected your modules logic from being broken by other modules at runtime which you probably will not have tested against.
Remember, if you use 3rd party libraries in a module, or you are writing one, it is highly probable and definitely possible others will too, and you may use the same ones. Whether the library is the same version or not, unless it is accessed in the context of a shared module classloader, i.e. the library is itself in a module versus a simple JAR dependency and all other modules use it this way, it can cause collision and access issues.
If you create a user interface in a modular system, such as the NetBeans RCP, upon a user action logic will run on the EDT, and if in that logic you access classes by name, create new instances of them, or perform casts and those classes could possibly be in more than one module, you will run into classloader collision issues. I will restate here that this also affects EventQueue.invokeLater and invokeAndWait.
Along with collision issues, you need to also understand that certain class access may be blocked depending on the classloader being used once you set the thread context classloader. Imagine you have some classes your current UI components classloader can see; they are part of its dependencies. Those dependencies classloaders may not have access to each other. If you use a classloader which does not have access to some classes to set the thread context classloader, then access will be blocked to those classes, and your logic will not work.
Suppose there is a button and it has an action listener attached to it. It could be written as:
public class MyActionListener implements ActionListener {
public void actionPerformed(ActionEvent evt){
ClassLoader oldCl = Thread.currentThread().getContextClassLoader();
try {
//here we are actually taking the current instances classloader
//which could be slightly better than
//MyActionListener.class.getClassLoader()
Thread.currentThread()
.setContextClassLoader(getClass().getClassLoader());
//create instances, cast, load classes by name
}finally{
Thread.currentThread().setContextClassLoader(oldCl);
}
}
}
The above could make an assumption it is the only possible some.specificpackage.MyActionListener to be within any module in the system at one time were it to use MyActionListener.class.getClassLoader(), and if that were not to be the case, you would need to get creative in the manner in which you get a classloader into this object.
The code does slightly guard against that since it uses getClass().getClassLoader() versus the static MyActionListener.class.getClassLoader() which would unequivocally infer it is expected to be the only one in the system per the way the class and classloader are being accessed. This means the instances classloader will be used, and if the instance was created using a specific classloader, and it is correct, then the code will simply work. If the classloader is not correct, then the logic which created the instance will need to be fixed.
This is another subtle way in which classloader issues can creep into the domain of concurrency and Java modular systems. You can use this information to ensure you have protected your modules logic from being broken by other modules at runtime which you probably will not have tested against.
Remember, if you use 3rd party libraries in a module, or you are writing one, it is highly probable and definitely possible others will too, and you may use the same ones. Whether the library is the same version or not, unless it is accessed in the context of a shared module classloader, i.e. the library is itself in a module versus a simple JAR dependency and all other modules use it this way, it can cause collision and access issues.
2012-02-21
Agile MVC User Interface Design - Not Soley For The Web
Introduction
When I wrote this I mainly had Java Swing developers in mind, particularly members of my current development team working on a NetBeans RCP based application, and I was initially going to title it Java Swing User Interface Design, but it certainly applies to any user interface work I have done in C, C++, C#, and JavaScript.
There are a few things to keep in mind when starting to design and develop a user interface. First, and most importantly, has anyone from the user community contributed to the interface you are working on; ideas, use cases/user stories, business rules? Next, has the user community reviewed any ideas and UI mock ups before starting any heavy coding? Have you taken time to design the user interface before adding complex business rules or worrying about concurrency and threading? These things affect time and resources which impacts how quickly they can be done correctly.
User Community Initial Input - User Stories or Use Cases
The essential question to basically everything we do may be: Why am I doing this? The user community, which a developer could possibly be a member, knows their domain or business. In many cases, they don't know how to get that result out of a user interface or possible ways the experience can be better until they are shown, but they know what data goes in and what data should come out; roughly at a minimum.
This is where requirements gathering comes into play. These have to start some where. The initial user stories (interchange with use cases) will be broad statements of what the users want to do. Users need to be coached into breaking those broad statements down into some very discreet ones which collectively would allow them to achive the one which is more broad. In project management terms, this starts to form what is known as a work breakdown structure.
The above is the top tier of the work breakdown structure or the work to be performed which allows the application and project to fulfill its purpose. A developer should be able to take this information and create those portions of the application. If the user stories are refined enough, developers should be able to understand them, and in turn, create tasks which will guide the development of their source code.
The tasks the developers create will become the lower tiers of the WBS. If the developers have a hard time deriving tasks from the refined user stories, they need to push back on the users until the stories are refined enough to allow this to happen. To the point. This represents why you are doing the thing you are doing. In this case, and more specifically, why the user interface will work the way it does.
User Contributions to The User Interface - User Interface Mock Ups
The advantage to iterative development, or in construction speak - design build, is direction can change more easily as development progresses. As the system gradually grows, replacing the whole becomes a more and more expensive proposition. If additions are built incrementally or in baby steps, they can be corrected within an iteration or two. Getting feedback from users ahead of time through UI mock ups helps with this as it relates to user interface design.
A UI mock up should be as simple as possible while expressing and displaying enough of the UI layout along with functionality to the assumed user community, or at least a narrowed test group of the user community. Various tools can be used to perform this work.
In some cases, a simple graphics application with annotated screen shots can be extremely useful. This is good when minor improvements or tweaks are added to existing functionality. This can be useful less the screen shots as well; imagine a simple form is thought to be all that is needed. Image applications can be useful for creating general layout examples along with rudimentary form objects. There are tools designed specifically for creating these type UI mock ups too, but many of the image manipulation programs one uses often work well.
In other cases, more developer oriented tools are better suited. With developer oriented tools, such as the NetBeans IDE and its UI designer, a partially functional representation can be created complete with real UI form components and windows and dialogs. Executable JAR files can be given to users which when run allow the user to play with an actual UI and get a feel for the ideas being presented.
Along with the above, branch development provides yet another option. In a branch of the source code, parts of the UI changes can be worked into an existing and running application. Though the parts will not be complete, remember this is a mock up, they give the user a glimpse of exactly how those pieces will fit into the current system. The whole thing need not be working or a large amount of work done to achieve the desired result. If the UI is acceptable, then the rest of the UI work can take place inside the branch taking advantage of the work which went into the mock up; some refactoring will certainly be required, but at least much of the UI components will be in place even if simply copied and pasted.
In some other cases, it may be best to create some kind of a functional prototype as mentioned above along with taking screen shots and then annotating them. It is often going to be much easier to create certain graphical effects in an image manipulation program than to write logic or source code from scratch to work those effects into an application; even if it is a prototype. The user can then take the functionality you can give them quickly, examine it, take the screen shots into consideration, and then make a determination as to whether such a feature adds value.
All features should be evaluated as to which of the above will work best. Remember: mock ups should show the user the intent and give them a glimpse of possibilities as quickly as possible to allow the team to change course if needed. If too much code and time goes into the mock up, then it may not provide as many advantages. But, there are times where a more in depth prototype will be required. It simply depends on whether users really understand what they are being shown or not, so always remember that communication is the best tool.
Incrementally Add Complexity
Possibly the best designed user interface will have as little business logic in the UI components as possible. The UI components should merely be a vessel for retrieving information from the user and displaying it to them. Initially this will be to get and set information intentionally not adding progress updates and background threading possibly long processes.
Progress updates and background operations will be determined by the data being set and retrieved per user operations and the processes required to get it. If taken into consideration in the user interface from the start, the user interface components are more likely to require changes often and in multiple places as use cases and operations evolve per user feedback. Minimise this until absolutely necessary. If the interface, along with data models - which probably differ from the data, capture the business rules correctly, then adding progress updates and threading at the end should require less work than reworking them.
MVC
In general an MVC pattern should be used. Data models, general utilities, controller logic, and the UI classes should be built into separate classes and files allowing them to be tested independently. This will also reduce the size of the individual files of the project. It will probably help produce a better design, and definitely with better separation.
UI components should know how to take a data model and display it or convert it from a model into something the user sees through the lens of the component. Data models should be able to take a set of data and expose it through a particular programming interface which various logic can access. Often models will have selected values, data, and fire events upon certain changes or at least allow a domain to tell it when to fire such an event through something like a fireXEvent() method call.
UI components should expose setters and getters or mechanisms to set and retrieve data the users actions have modified. These can expose data or models. These components should also allow various listeners to be added, removed, and retrieved. User actions, even if pressing a single button in some complex UI component, should generally be exposed through listeners and cause nothing to necessarily change in the UI unless it is purely related to the UI state.
The controller should attach listeners and act upon such actions, and the logic which enables, disables, or changes various features of the user interface, such as setting a new model or updating an existing one which was a result of the action, should be built into the controller. The controller should contain the business logic. Other extraneous logic which seems fairly generic in the process should go into some possibly shareable utility class and not pollute the controller.
A simple example of an MVC would be a file search utility. Suppose the UI of this utility has a single text field called searchTerm. Next, there is a button to the right of searchTerm called searchButton with a magnifying glass on it. The UI contains a tree table below called searchResults. The searchResults displays a model called searchModel of the type SearchModel (which is just an interface). The component has a property inSearch which when true searchButton has a magnifying glass which moves slowing in a circle, and searchTerm is disabled. When false, searchButton has its default still graphic, and searchTerm is enabled.
Let's simply state that searchModel has a method called getFile which accepts an integer as the row in the model as well as one called getSize. It doesn't provide any filtering or anything. This is done by the controller by way of the searchTerm. The UI component knows how to take a model and show its files represented in a tree structure by way of getFile(ndx).getParent(), and that is all this component knows of this model.
The UI component allows add/remove/getSearchButtonActionListener(s), get/setSearchTerm which sets and gets searchTerms text, set/getSearchModel, and set/isInSearch. The controller uses these exposed attributes of the UI component to do all the work and tell the UI how to look. It hooks in a searchButton listener, when searchButton is clicked, it sets inSearch to true, performs its background work, retrieves data, creates a model, which may be empty, sets the model, and finally sets inSearch to false. All the UI component did was fire an event, handle the button animation, and get and display information from and to the user.
As it relates to incrementally adding complexity, there are a couple things which would have been done last in the above example. They are probably obvious, but they are 1) animating the searchButton, and 2) background work of the search. The actual functionality is the most important part. Once that works correctly, then backgrounding some logic and animating a button can be done. Those are not very high risk items on an agenda. It is safe to say that once one has done such a thing a couple times they will be able to do it in various situations over and over; static from a pure human memory perspective. The domain/business logic is the higher priority and most difficult and dynamic piece.
When I wrote this I mainly had Java Swing developers in mind, particularly members of my current development team working on a NetBeans RCP based application, and I was initially going to title it Java Swing User Interface Design, but it certainly applies to any user interface work I have done in C, C++, C#, and JavaScript.
There are a few things to keep in mind when starting to design and develop a user interface. First, and most importantly, has anyone from the user community contributed to the interface you are working on; ideas, use cases/user stories, business rules? Next, has the user community reviewed any ideas and UI mock ups before starting any heavy coding? Have you taken time to design the user interface before adding complex business rules or worrying about concurrency and threading? These things affect time and resources which impacts how quickly they can be done correctly.
User Community Initial Input - User Stories or Use Cases
The essential question to basically everything we do may be: Why am I doing this? The user community, which a developer could possibly be a member, knows their domain or business. In many cases, they don't know how to get that result out of a user interface or possible ways the experience can be better until they are shown, but they know what data goes in and what data should come out; roughly at a minimum.
This is where requirements gathering comes into play. These have to start some where. The initial user stories (interchange with use cases) will be broad statements of what the users want to do. Users need to be coached into breaking those broad statements down into some very discreet ones which collectively would allow them to achive the one which is more broad. In project management terms, this starts to form what is known as a work breakdown structure.
The above is the top tier of the work breakdown structure or the work to be performed which allows the application and project to fulfill its purpose. A developer should be able to take this information and create those portions of the application. If the user stories are refined enough, developers should be able to understand them, and in turn, create tasks which will guide the development of their source code.
The tasks the developers create will become the lower tiers of the WBS. If the developers have a hard time deriving tasks from the refined user stories, they need to push back on the users until the stories are refined enough to allow this to happen. To the point. This represents why you are doing the thing you are doing. In this case, and more specifically, why the user interface will work the way it does.
User Contributions to The User Interface - User Interface Mock Ups
The advantage to iterative development, or in construction speak - design build, is direction can change more easily as development progresses. As the system gradually grows, replacing the whole becomes a more and more expensive proposition. If additions are built incrementally or in baby steps, they can be corrected within an iteration or two. Getting feedback from users ahead of time through UI mock ups helps with this as it relates to user interface design.
A UI mock up should be as simple as possible while expressing and displaying enough of the UI layout along with functionality to the assumed user community, or at least a narrowed test group of the user community. Various tools can be used to perform this work.
In some cases, a simple graphics application with annotated screen shots can be extremely useful. This is good when minor improvements or tweaks are added to existing functionality. This can be useful less the screen shots as well; imagine a simple form is thought to be all that is needed. Image applications can be useful for creating general layout examples along with rudimentary form objects. There are tools designed specifically for creating these type UI mock ups too, but many of the image manipulation programs one uses often work well.
In other cases, more developer oriented tools are better suited. With developer oriented tools, such as the NetBeans IDE and its UI designer, a partially functional representation can be created complete with real UI form components and windows and dialogs. Executable JAR files can be given to users which when run allow the user to play with an actual UI and get a feel for the ideas being presented.
Along with the above, branch development provides yet another option. In a branch of the source code, parts of the UI changes can be worked into an existing and running application. Though the parts will not be complete, remember this is a mock up, they give the user a glimpse of exactly how those pieces will fit into the current system. The whole thing need not be working or a large amount of work done to achieve the desired result. If the UI is acceptable, then the rest of the UI work can take place inside the branch taking advantage of the work which went into the mock up; some refactoring will certainly be required, but at least much of the UI components will be in place even if simply copied and pasted.
In some other cases, it may be best to create some kind of a functional prototype as mentioned above along with taking screen shots and then annotating them. It is often going to be much easier to create certain graphical effects in an image manipulation program than to write logic or source code from scratch to work those effects into an application; even if it is a prototype. The user can then take the functionality you can give them quickly, examine it, take the screen shots into consideration, and then make a determination as to whether such a feature adds value.
All features should be evaluated as to which of the above will work best. Remember: mock ups should show the user the intent and give them a glimpse of possibilities as quickly as possible to allow the team to change course if needed. If too much code and time goes into the mock up, then it may not provide as many advantages. But, there are times where a more in depth prototype will be required. It simply depends on whether users really understand what they are being shown or not, so always remember that communication is the best tool.
Incrementally Add Complexity
Possibly the best designed user interface will have as little business logic in the UI components as possible. The UI components should merely be a vessel for retrieving information from the user and displaying it to them. Initially this will be to get and set information intentionally not adding progress updates and background threading possibly long processes.
Progress updates and background operations will be determined by the data being set and retrieved per user operations and the processes required to get it. If taken into consideration in the user interface from the start, the user interface components are more likely to require changes often and in multiple places as use cases and operations evolve per user feedback. Minimise this until absolutely necessary. If the interface, along with data models - which probably differ from the data, capture the business rules correctly, then adding progress updates and threading at the end should require less work than reworking them.
MVC
In general an MVC pattern should be used. Data models, general utilities, controller logic, and the UI classes should be built into separate classes and files allowing them to be tested independently. This will also reduce the size of the individual files of the project. It will probably help produce a better design, and definitely with better separation.
UI components should know how to take a data model and display it or convert it from a model into something the user sees through the lens of the component. Data models should be able to take a set of data and expose it through a particular programming interface which various logic can access. Often models will have selected values, data, and fire events upon certain changes or at least allow a domain to tell it when to fire such an event through something like a fireXEvent() method call.
UI components should expose setters and getters or mechanisms to set and retrieve data the users actions have modified. These can expose data or models. These components should also allow various listeners to be added, removed, and retrieved. User actions, even if pressing a single button in some complex UI component, should generally be exposed through listeners and cause nothing to necessarily change in the UI unless it is purely related to the UI state.
The controller should attach listeners and act upon such actions, and the logic which enables, disables, or changes various features of the user interface, such as setting a new model or updating an existing one which was a result of the action, should be built into the controller. The controller should contain the business logic. Other extraneous logic which seems fairly generic in the process should go into some possibly shareable utility class and not pollute the controller.
A simple example of an MVC would be a file search utility. Suppose the UI of this utility has a single text field called searchTerm. Next, there is a button to the right of searchTerm called searchButton with a magnifying glass on it. The UI contains a tree table below called searchResults. The searchResults displays a model called searchModel of the type SearchModel (which is just an interface). The component has a property inSearch which when true searchButton has a magnifying glass which moves slowing in a circle, and searchTerm is disabled. When false, searchButton has its default still graphic, and searchTerm is enabled.
Let's simply state that searchModel has a method called getFile which accepts an integer as the row in the model as well as one called getSize. It doesn't provide any filtering or anything. This is done by the controller by way of the searchTerm. The UI component knows how to take a model and show its files represented in a tree structure by way of getFile(ndx).getParent(), and that is all this component knows of this model.
The UI component allows add/remove/getSearchButtonActionListener(s), get/setSearchTerm which sets and gets searchTerms text, set/getSearchModel, and set/isInSearch. The controller uses these exposed attributes of the UI component to do all the work and tell the UI how to look. It hooks in a searchButton listener, when searchButton is clicked, it sets inSearch to true, performs its background work, retrieves data, creates a model, which may be empty, sets the model, and finally sets inSearch to false. All the UI component did was fire an event, handle the button animation, and get and display information from and to the user.
As it relates to incrementally adding complexity, there are a couple things which would have been done last in the above example. They are probably obvious, but they are 1) animating the searchButton, and 2) background work of the search. The actual functionality is the most important part. Once that works correctly, then backgrounding some logic and animating a button can be done. Those are not very high risk items on an agenda. It is safe to say that once one has done such a thing a couple times they will be able to do it in various situations over and over; static from a pure human memory perspective. The domain/business logic is the higher priority and most difficult and dynamic piece.
Labels:
AWT,
C,
C#,
C++,
Java,
JavaScript,
NetBeans,
NetBeans RCP,
Swing,
User Interface Design
2012-02-10
Java Module Systems, SwingWorker, Runnable, Thread and Class Loader Issues
People often have a hard time getting used to a Java module systems constraints on class loaders and dealing with compile time versus runtime dependencies. There are a lot of issues just around getting the dependencies organized.
Often overlooked is how threading impacts class loaders. NetBeans modules, when "they" create a thread for you, will generally set the context class loader to the current class loader. However, in your own code you need to handle this.
Note Runnable is mentioned above. This does not necessarily consider the cases of EventQueue.invokeLater and invokeAndWait as those things are generally cases where the object instances have been realized, and class loading is no longer in the picture, or at least they should be, as those things should be short and to the point as they happen on the EDT, but it focuses on Runnable when given to the Thread constructor.
However, this could become a source of issues, and if creating new object instances in the Runnable, and it is ever a possibility those classes could be included in more than one module in the targeted system, then you should probably go ahead and deal with a class loader change out as your code will be running on the EDT.
Either way, the reason this becomes important is class access and class collision.
Access deals with the visibility or permissions a given class loader gives the calling code. Calling code may not have access to a certain class, and thus the current class loader should not be the one to load classes, but should instead delegate that to another module which has access to not only the public API but the private API of the module itself. That would be the one loading the classes the caller can access or the public API of the called module.
Collision is a more subtle thing to deal with. Imagine one module has class mine.Foo and another module does as well. Even though these modules may not call or touch each other and thus not collide with each other under normal calling conditions, they may very well do that in a thread without setting the context class loader as those classes will have to be loaded some how, and here the system class loader will be used which will access all the class loaders, and that means either an arbitrary class must be chosen or the first one found, and in nearly all conditions this is not what you want.
In the NetBeans module system this will cause an error as the NetBeans developers do not want this to be a surprise and thus hide crashes. Others may load them; I'm not sure, so if anyone knows how various module systems handle this please comment. Either way, unless you give Java and the module system more guidance, you will run into strange and unusual problems.
Given a class, the following should really be used:
This does a couple things at various runtimes. When the code runs in a regular Java application with no module system, the system class loader will always be used. Next, when run in a modular application, the current caller, or current module will use its class loader in the threaded logic. Finally, in both cases, the loader is reset to whatever it was before; for throw away threads, that is probably not a big deal, but what if your code is using a thread pool?
This is a basic convention to follow for safety and refactorability. Safety as noted in access and collision. If your code is used in a modular system, and does not follow the above, it will crash as soon as you add the same classes to other modules. Refactorability per the fact that if more than one module later adds a different version of a class, or the same version different class loader, then the application will start to crash until fixed, and if the person tracking down the issue has to spend time finding and/or fixing it, they can't focus on refactoring code to work with the same classes in different ways.
Another thing to keep in mind is there are times when you may need to pass a specific class other than your own for some block of code to pin-point an exact class loader. Imagine some code you are calling will need classes which your class loader does not have access as the module being called does not expose them as part of its public API.
So, there are times when you have to think beyond the current class loader, but the good thing is no matter which class works in the modular system, the code will continue to work if used outside of one in a standard Java application.
The one major time this differs are libraries written to load and use classes dynamically. MyBatis is a good example. In such cases, the current thread context class loader should be passed along. The idea being the caller is telling you which class loaders to use. This only applies to threads however as the module wrapping the called code will have configured the context class loader as needed for the current thread.
The MyBatis folks were working to address this issue the last time I was on the lists. Someone using it in such a context now should comment if able.
I hope this will help projects (open source and not) write Java code which is compatible in both modular and non-modular applications.
Often overlooked is how threading impacts class loaders. NetBeans modules, when "they" create a thread for you, will generally set the context class loader to the current class loader. However, in your own code you need to handle this.
Note Runnable is mentioned above. This does not necessarily consider the cases of EventQueue.invokeLater and invokeAndWait as those things are generally cases where the object instances have been realized, and class loading is no longer in the picture, or at least they should be, as those things should be short and to the point as they happen on the EDT, but it focuses on Runnable when given to the Thread constructor.
However, this could become a source of issues, and if creating new object instances in the Runnable, and it is ever a possibility those classes could be included in more than one module in the targeted system, then you should probably go ahead and deal with a class loader change out as your code will be running on the EDT.
Either way, the reason this becomes important is class access and class collision.
Access deals with the visibility or permissions a given class loader gives the calling code. Calling code may not have access to a certain class, and thus the current class loader should not be the one to load classes, but should instead delegate that to another module which has access to not only the public API but the private API of the module itself. That would be the one loading the classes the caller can access or the public API of the called module.
Collision is a more subtle thing to deal with. Imagine one module has class mine.Foo and another module does as well. Even though these modules may not call or touch each other and thus not collide with each other under normal calling conditions, they may very well do that in a thread without setting the context class loader as those classes will have to be loaded some how, and here the system class loader will be used which will access all the class loaders, and that means either an arbitrary class must be chosen or the first one found, and in nearly all conditions this is not what you want.
In the NetBeans module system this will cause an error as the NetBeans developers do not want this to be a surprise and thus hide crashes. Others may load them; I'm not sure, so if anyone knows how various module systems handle this please comment. Either way, unless you give Java and the module system more guidance, you will run into strange and unusual problems.
Given a class, the following should really be used:
public class MyClass {
Runnable r = new Runnable(){
public void run(){
ClassLoader oldCl = Thread.currentThread().getContextClassLoader();
try {
Thread.currentThread().setContextClassLoader(MyClass.class.getClassLoader());
}finally{
Thread.currentThread().setContextClassLoader(oldCl);
}
}
};
Thread t = new Thread(){
public void run(){
ClassLoader oldCl = Thread.currentThread().getContextClassLoader();
try {
Thread.currentThread().setContextClassLoader(MyClass.class.getClassLoader());
}finally{
Thread.currentThread().setContextClassLoader(oldCl);
}
}
};
SwingWorker<Void, Void> = new SwingWorker<Void, Void>{
public Void doInBackGround(){
ClassLoader oldCl = Thread.currentThread().getContextClassLoader();
try {
Thread.currentThread().setContextClassLoader(MyClass.class.getClassLoader());
}finally{
Thread.currentThread().setContextClassLoader(oldCl);
}
return null;
}
};
}
This does a couple things at various runtimes. When the code runs in a regular Java application with no module system, the system class loader will always be used. Next, when run in a modular application, the current caller, or current module will use its class loader in the threaded logic. Finally, in both cases, the loader is reset to whatever it was before; for throw away threads, that is probably not a big deal, but what if your code is using a thread pool?
This is a basic convention to follow for safety and refactorability. Safety as noted in access and collision. If your code is used in a modular system, and does not follow the above, it will crash as soon as you add the same classes to other modules. Refactorability per the fact that if more than one module later adds a different version of a class, or the same version different class loader, then the application will start to crash until fixed, and if the person tracking down the issue has to spend time finding and/or fixing it, they can't focus on refactoring code to work with the same classes in different ways.
Another thing to keep in mind is there are times when you may need to pass a specific class other than your own for some block of code to pin-point an exact class loader. Imagine some code you are calling will need classes which your class loader does not have access as the module being called does not expose them as part of its public API.
So, there are times when you have to think beyond the current class loader, but the good thing is no matter which class works in the modular system, the code will continue to work if used outside of one in a standard Java application.
The one major time this differs are libraries written to load and use classes dynamically. MyBatis is a good example. In such cases, the current thread context class loader should be passed along. The idea being the caller is telling you which class loaders to use. This only applies to threads however as the module wrapping the called code will have configured the context class loader as needed for the current thread.
The MyBatis folks were working to address this issue the last time I was on the lists. Someone using it in such a context now should comment if able.
I hope this will help projects (open source and not) write Java code which is compatible in both modular and non-modular applications.
2011-04-13
Automated Web Testing with Selenium and The NetBeans Rich Client Platform
I developed tooling for work I do for Scripps which helps me create Selenium based automated user tests more easily. These are not open source at this time, though that may be possible some day. I might use the ones I have created as an example to make some better for OSS since I have learned lessons along the way.
This tooling has been built on the NetBeans Rich Client Platform, but too, will run right in the IDE. I show IDE examples in this post. It helps create Java projects for using Selenium for automated user testing. This ties in nicely with the IDE.
There are different technologies supported in the tooling. There is a JavaScript runner or window which allows one to run JavaScript inside Selenium using runScript and getEval. Too, there is project support for Java and Groovy. I don't show the Groovy support here, but it is exactly the same as the Java examples less you will be using a Groovy file instead of a Java file, so you can derive how it works from that.
This is not the same as the tooling available in the current NetBeans auto update centers. I noticed it when I started this, and I don't see that it addresses things in the same manner which I do. I don't focus on the tests in this case as much as I focus on being able to test chunks of code as you are trying to develop the logic which will exercise your application.
The reason I do this is because I do not just write tests. I create automation APIs which can be used to affect the system. This then allows tests to be created using those APIs. That limits the impact of application changes to the high level test scripts which use the APIs I create. Thus, if a change occurs in the application which can break the tests, then I change one file versus many.
The above may be a topic of another post one day. I will now get on with showing the tooling.
First, and not really shown here, I needed a way to proxy calls to a Selenium session. I created a library which implements certain aspects of Selenium to allow this to happen. This simply gets and sets the Selenium session ID so calls for a Selenium session may come from multiple places. In this case, the user serializes those things. You will see it references in code which follows.
Next, I needed a way to manage Selenium server connections, and too I needed a simple way to kick off a Selenium server in the development environment. The "Selenium Manager" top component handles this for me. Certain aspects are configurable.



You can also start and stop the in IDE Selenium server here. The output uses the NetBeans output window for this.

Once you have configured connections, you can start and use them one at a time

Once a live session is available, the manager allows you to stop it or to copy the session ID using context menus

Next, and most importantly, there is the ability to do productive things.
There is a Selenium JavaScript runner. This is a special window where one can type in JavaScript, execute it, and see the response. Too, one can ask for the current HTML from the page based on the DOM and not the plain HTML sources before any JavaScript logic has applied changes.

Notice the syntax highlighting options in the output below. I suppose I could add the ability to view that as JSON too. This is an example of using the "Grab HTML" button

Notice the part above dealing with ret=ret in the JavaScript image. This is due to the way this logic will be run directly in Selenium and the way it returns the last evaluation instead of having the caller use the return statement; this is a Selenium thing (see Selenium.getEval). That could have been worked around in the JavaScript runner if I had put the logic in a function and called it, but for the purposes of using this window that is a little overhead I don't need.
Above, you may have noticed the use of jQuery. How did it get there? Right, there is a difference in the JavaScript used in your application, and that used in Selenium. You can see my other blog post for more information, but I injected jQuery into the current Selenium session using Selenium.addScript from some Java code.
I will show you how that gets there in a bit.
It should be obvious we are using the started session here, but just to be clear, before I can run this JavaScript, I had to start a Selenium session and drive the state of the browser manually to get to what I wanted to operate against. In this case not really as the session opened on the Google home page.
Above, I mentioned injecting jQuery. Well, if you can inject jQuery, then you can inject your own JavaScript as well. You can take the logic you figure out in the JavaScript runner and move that into your own JavaScript files which you will inject.

Next, you can create a regular Java project in the NetBeans IDE. Then, you can create a standard Java class. You can then click on a line in the Java file and bring up a context menu and ask the tooling to inject the required Selenium proxy logic to allow you to write code using the current session.

This can be in a main method as above in which case it will be a local variable, or it can be at the class level. Repeated uses of the above action will just overwrite the previously injected code unless it is deleted; in that case it will be added back. This is needed if you stop the Selenium session and restart it. In this case you get a new session ID. Once you use the action, your class will look like this

Then you fill in some scratch pad type code to exercise some logic you will later add to an actual API. This may seem counter intuitive, but the point is to be able to drive the state of the application with the browser while you write some finite pieces of the whole which you know work. This greatly reduces the time to get the state in place and start the test etc. The develop test cycle becomes easier to manage.


So, how did our JavaScript and jQuery come to reside in the Selenium session? It was put there with another scratch pad Java class.

The related libraries were added to my Java project automatically for me by the tooling too. This includes the proxy library which I first wrote about.

I'm obviously trying to use a very simple example here. To get real work from these tools I have a full blown AUT API I have designed and developed for the project I'm testing. Too, I have developed the infrastructure needed to use the API including a set of tests and Ant build scripts.
The individual tests I can run directly from the IDE as they are JUnit tests, and their core logic can be developed, along with the APIs, running against a live Selenium session. The Selenium JavaScript injection is done automatically by my base JUnit test along with other preliminary things.
Hopefully at some point in the near future I will create an OSS version of this tooling. I don't have an ETA at this moment. But, I hope as I feel it could be useful for many.
This tooling has been built on the NetBeans Rich Client Platform, but too, will run right in the IDE. I show IDE examples in this post. It helps create Java projects for using Selenium for automated user testing. This ties in nicely with the IDE.
There are different technologies supported in the tooling. There is a JavaScript runner or window which allows one to run JavaScript inside Selenium using runScript and getEval. Too, there is project support for Java and Groovy. I don't show the Groovy support here, but it is exactly the same as the Java examples less you will be using a Groovy file instead of a Java file, so you can derive how it works from that.
This is not the same as the tooling available in the current NetBeans auto update centers. I noticed it when I started this, and I don't see that it addresses things in the same manner which I do. I don't focus on the tests in this case as much as I focus on being able to test chunks of code as you are trying to develop the logic which will exercise your application.
The reason I do this is because I do not just write tests. I create automation APIs which can be used to affect the system. This then allows tests to be created using those APIs. That limits the impact of application changes to the high level test scripts which use the APIs I create. Thus, if a change occurs in the application which can break the tests, then I change one file versus many.
The above may be a topic of another post one day. I will now get on with showing the tooling.
First, and not really shown here, I needed a way to proxy calls to a Selenium session. I created a library which implements certain aspects of Selenium to allow this to happen. This simply gets and sets the Selenium session ID so calls for a Selenium session may come from multiple places. In this case, the user serializes those things. You will see it references in code which follows.
Next, I needed a way to manage Selenium server connections, and too I needed a simple way to kick off a Selenium server in the development environment. The "Selenium Manager" top component handles this for me. Certain aspects are configurable.



You can also start and stop the in IDE Selenium server here. The output uses the NetBeans output window for this.

Once you have configured connections, you can start and use them one at a time

Once a live session is available, the manager allows you to stop it or to copy the session ID using context menus

Next, and most importantly, there is the ability to do productive things.
There is a Selenium JavaScript runner. This is a special window where one can type in JavaScript, execute it, and see the response. Too, one can ask for the current HTML from the page based on the DOM and not the plain HTML sources before any JavaScript logic has applied changes.

Notice the syntax highlighting options in the output below. I suppose I could add the ability to view that as JSON too. This is an example of using the "Grab HTML" button

Notice the part above dealing with ret=ret in the JavaScript image. This is due to the way this logic will be run directly in Selenium and the way it returns the last evaluation instead of having the caller use the return statement; this is a Selenium thing (see Selenium.getEval). That could have been worked around in the JavaScript runner if I had put the logic in a function and called it, but for the purposes of using this window that is a little overhead I don't need.
Above, you may have noticed the use of jQuery. How did it get there? Right, there is a difference in the JavaScript used in your application, and that used in Selenium. You can see my other blog post for more information, but I injected jQuery into the current Selenium session using Selenium.addScript from some Java code.
I will show you how that gets there in a bit.
It should be obvious we are using the started session here, but just to be clear, before I can run this JavaScript, I had to start a Selenium session and drive the state of the browser manually to get to what I wanted to operate against. In this case not really as the session opened on the Google home page.
Above, I mentioned injecting jQuery. Well, if you can inject jQuery, then you can inject your own JavaScript as well. You can take the logic you figure out in the JavaScript runner and move that into your own JavaScript files which you will inject.

Next, you can create a regular Java project in the NetBeans IDE. Then, you can create a standard Java class. You can then click on a line in the Java file and bring up a context menu and ask the tooling to inject the required Selenium proxy logic to allow you to write code using the current session.

This can be in a main method as above in which case it will be a local variable, or it can be at the class level. Repeated uses of the above action will just overwrite the previously injected code unless it is deleted; in that case it will be added back. This is needed if you stop the Selenium session and restart it. In this case you get a new session ID. Once you use the action, your class will look like this

Then you fill in some scratch pad type code to exercise some logic you will later add to an actual API. This may seem counter intuitive, but the point is to be able to drive the state of the application with the browser while you write some finite pieces of the whole which you know work. This greatly reduces the time to get the state in place and start the test etc. The develop test cycle becomes easier to manage.


So, how did our JavaScript and jQuery come to reside in the Selenium session? It was put there with another scratch pad Java class.

The related libraries were added to my Java project automatically for me by the tooling too. This includes the proxy library which I first wrote about.

I'm obviously trying to use a very simple example here. To get real work from these tools I have a full blown AUT API I have designed and developed for the project I'm testing. Too, I have developed the infrastructure needed to use the API including a set of tests and Ant build scripts.
The individual tests I can run directly from the IDE as they are JUnit tests, and their core logic can be developed, along with the APIs, running against a live Selenium session. The Selenium JavaScript injection is done automatically by my base JUnit test along with other preliminary things.
Hopefully at some point in the near future I will create an OSS version of this tooling. I don't have an ETA at this moment. But, I hope as I feel it could be useful for many.
2008-07-16
Make adding properties to classes in NetBeans a simpler task
NetBeans has a great feature called Code Templates. This is used to create shortcuts which may be typed in the editor then expanded into a template which the editor will ask the user to fill in the blanks. There are many useful ones which come configured upon installation within the NetBeans IDE, but one I have used for a long time, yet never written about except on the NetBeans mailing lists, is one to create properties more easily.
These properties are plain properties un-bounded and not incorporating property change events, but none the less very useful, and it isn't much work to transform into your choice of other useful property creating templates. Without further delay, my code template is:

I simply press the TAB button to jump between the fields TYPE,VAR, and VAL, enter the values, and when I have them all filled in press the ENTER button and my cursor is placed at the ${cursor} position or offset in the editor.
The final result is a read-write property with the source code all laid out nicely

To expand the function of the template is easy enough. I have one which adds the logic for property change events. I have it named eprop in my IDE.
I have another one named ewprop which stands for Wrap or Wrapper, and in this case another field is needed to handle wrapping primitive types to pass the call to firePropertyChange, and it also assumes a variable named pcs:
One thing still missing from the pre 6.0 or 5.5 days is the ability to easily manage JavaBean patterns. This involves things such as being able to rename a property and have the field and method names change at once. The ability to add JavaBean properties has been added back to the IDE at least, but these code templates I'm writing about are easier to use, or at least quicker, than the UI to add properties through the Java editor once you are used to using them, but maybe that can be remedied by adding a quick pop up menu for doing things with JavaBean patterns to the Java editor; if I have time this year that can be one of my community contributions :-D
These properties are plain properties un-bounded and not incorporating property change events, but none the less very useful, and it isn't much work to transform into your choice of other useful property creating templates. Without further delay, my code template is:
private ${TYPE} ${VAR} = ${VAL};Mine is named prop, so when I am in a Java file I type
public ${TYPE} get${NAME}(){
return ${VAR};
}
public void set${NAME}(${TYPE} ${VAR}){
this.${VAR} = ${VAR};
}
${cursor}
propthen press the TAB button/key. The template is expanded and asks me to fill in the details. Below are some screen samples of this in action.

I simply press the TAB button to jump between the fields TYPE,VAR, and VAL, enter the values, and when I have them all filled in press the ENTER button and my cursor is placed at the ${cursor} position or offset in the editor.The final result is a read-write property with the source code all laid out nicely

To expand the function of the template is easy enough. I have one which adds the logic for property change events. I have it named eprop in my IDE.
private ${TYPE} ${VAR} = ${VAL};It assumes you have an instance of java.beans.PropertyChangeSupport called pcs.
public ${TYPE} get${NAME}(){
return ${VAR};
}
public void set${NAME}(${TYPE} ${VAR}){
${TYPE} lold${VAR} = this.${VAR};
this.${VAR} = ${VAR};
pcs.firePropertyChange("${VAR}",lold${VAR},${VAR});
}
${cursor}
I have another one named ewprop which stands for Wrap or Wrapper, and in this case another field is needed to handle wrapping primitive types to pass the call to firePropertyChange, and it also assumes a variable named pcs:
private ${TYPE} ${VAR} = ${VAL};That covers much of what one wants to do with beans.
public ${TYPE} get${NAME}(){
return ${VAR};
}
public void set${NAME}(${TYPE} ${VAR}){
${TYPE} lold${VAR} = this.${VAR};
this.${VAR} = ${VAR};
pcs.firePropertyChange("${VAR}",new ${WTYPE}(lold${VAR}),new ${WTYPE}(${VAR}));
}
${cursor}
One thing still missing from the pre 6.0 or 5.5 days is the ability to easily manage JavaBean patterns. This involves things such as being able to rename a property and have the field and method names change at once. The ability to add JavaBean properties has been added back to the IDE at least, but these code templates I'm writing about are easier to use, or at least quicker, than the UI to add properties through the Java editor once you are used to using them, but maybe that can be remedied by adding a quick pop up menu for doing things with JavaBean patterns to the Java editor; if I have time this year that can be one of my community contributions :-D
2008-04-02
Who says a RootPane always has to be at the top?
Some friends and I have started a project to extend functionality inside the NetBeans RCP (Rich Client Platform). We call it PlatformX, and it is located on the web at http://platformx.netbeans.org. We hope to have the repository public soon for others to use and contribute.
One of the APIs I'm working on is called RootPaneTopComponent. For the uninitiated in NetBeans RCP, a TopComponent is a Swing component managed by the NetBeans platform. They may work as regular components or can also be used as dockable/undockable components which may be moved around in the application.
A RootPaneTopComponent is a TopComponent which implements the RootPaneContainer interface. It allows one to use a glass pane, a menu and menu items, or a layered pane in more component based classes such as JFrame, JInternalFrame, and JApplet do for the more encompassing classes, so this new class in PlatformX allows the same thing yet at a lower level.
I'll have more information as soon as possible about this class and its sister class CloneableRootPaneTopComponent when I get it finished and we are closer to having a more public release of our first Platformx APIs and repository access. Until now here are some simple screen shots.
Imagine you have a dockable component you need disabled or the ability to cover with some user blocking message until another application state has been reached, and you do not want to block the entire window or a dialog. This is where component level glass panes come in handy:
Now you see me:

now you don't:
and I'll leave it up to you to figure out ways you could use this in your applications today. I'm using it to block certain components which need the user to login to be able to use them.
I mentioned the menu bar. I have also coded this particular class to allow north, south, east, and west components to be placed around it. This could be used for multiple things. I have chosen in this example to imagine some type of an editor which might have search functionality and maybe a notes editor which could show different notes for paragraphs or diagrams or any thing else one might think of:
No notes showing:

and now they are:
Anyways, this is just a simple example to show some of the capabilities of what I'm working on at the moment. This entry is to make it easier to show the others working on the project how it works right now more than anything, but it can be a preview as well :-D. Hopefully it, along with some other things, will be released soon. It's NetBeans, so of course it is open-source.
One of the APIs I'm working on is called RootPaneTopComponent. For the uninitiated in NetBeans RCP, a TopComponent is a Swing component managed by the NetBeans platform. They may work as regular components or can also be used as dockable/undockable components which may be moved around in the application.
A RootPaneTopComponent is a TopComponent which implements the RootPaneContainer interface. It allows one to use a glass pane, a menu and menu items, or a layered pane in more component based classes such as JFrame, JInternalFrame, and JApplet do for the more encompassing classes, so this new class in PlatformX allows the same thing yet at a lower level.
I'll have more information as soon as possible about this class and its sister class CloneableRootPaneTopComponent when I get it finished and we are closer to having a more public release of our first Platformx APIs and repository access. Until now here are some simple screen shots.
Imagine you have a dockable component you need disabled or the ability to cover with some user blocking message until another application state has been reached, and you do not want to block the entire window or a dialog. This is where component level glass panes come in handy:
Now you see me:

now you don't:
and I'll leave it up to you to figure out ways you could use this in your applications today. I'm using it to block certain components which need the user to login to be able to use them.I mentioned the menu bar. I have also coded this particular class to allow north, south, east, and west components to be placed around it. This could be used for multiple things. I have chosen in this example to imagine some type of an editor which might have search functionality and maybe a notes editor which could show different notes for paragraphs or diagrams or any thing else one might think of:
No notes showing:

and now they are:
Anyways, this is just a simple example to show some of the capabilities of what I'm working on at the moment. This entry is to make it easier to show the others working on the project how it works right now more than anything, but it can be a preview as well :-D. Hopefully it, along with some other things, will be released soon. It's NetBeans, so of course it is open-source.
2007-12-18
Central Lookup: Creating a central repository and lookup for an application context in a NetBeans RCP application
I have been working on a NetBeans RCP project where I needed a central place to register different interfaces and allow different views to operate on these regular POJOs one would use in a regular Swing application and to be able to listen to changes to them from the standpoint of some kind of an Application Context where different instances will come and go. A good example is a desktop application requiring a login. You will have user information and want to be able to track a global login or validation token.
I create a simple class and API in a NetBeans module and called it CentralLookup. This is all the code for such a simple thing (please ignore the formatting of the code...maybe I can update it later, but it seems blogger isn't wanting to format it correctly when posted):
package org.netbeans.modules.centrallookup.api;
import java.util.Collection;
import org.openide.util.Lookup.Result;
import org.openide.util.lookup.AbstractLookup;
import org.openide.util.lookup.InstanceContent;
/**
* Class used to house anything one might want to store
* in a central lookup which can affect anything within
* the application. It can be thought of as a central context
* where any application data may be stored and watched.
*
* A singleton instance is created using @see getDefault().
* This class is as thread safe as Lookup. Lookup appears to be safe.
* @author Wade Chandler
* @version 1.0
*/
public class CentralLookup extends AbstractLookup {
private InstanceContent content = null;
private static CentralLookup def = new CentralLookup();
public CentralLookup(InstanceContent content) {
super(content);
this.content = content;
}
public CentralLookup() {
this(new InstanceContent());
}
public void add(Object instance) {
content.add(instance);
}
public void remove(Object instance) {
content.remove(instance);
}
public static CentralLookup getDefault(){
return def;
}
}
The nice thing about this code is that it is real simple. The strange thing for me is that there hasn't been something already implemented in the base RCP. It seems pretty common a thing. For instance, the normal global lookups deal with Actions, Services, and Nodes (which are part of the NetBeans data model), and that is fine until one needs to work with generic interfaces and classes from a global perspective.
Regardless, I can now write code to listen to changes in this global context or Lookup in this case. The code doesn't have to know about any implementation except for the code which does the injection, and the code in other places can just setup a result and a listener. The following illustrates this a bit, and of course it is just a sub-set of the code:
final class CentralLookupTest1TopComponent extends TopComponent {
private static CentralLookupTest1TopComponent instance;
private Lookup.Result userInfoResult = null;
private CentralLookupTest1TopComponent() {
Lookup.Template template = new Lookup.Template(UserInformation.class);
CentralLookup cl = CentralLookup.getDefault();
userInfoResult = cl.lookup(template);
userInfoResult.addLookupListener(new UserInformationListener());
}
private javax.swing.JTextField name;
private javax.swing.JTextField pwd;
private javax.swing.JTextField token;
private javax.swing.JTextField uid;
private class SetterRunnable implements Runnable {
UserInformation ui = null;
public SetterRunnable(UserInformation ui) {
this.ui = ui;
}
public void run() {
name.setText(ui.getName());
pwd.setText(ui.getPassword());
uid.setText(ui.getUserID());
token.setText(ui.getToken());
}
}
private class UserInformationListener implements LookupListener {
public void resultChanged(LookupEvent evt) {
Object o = evt.getSource();
if (o != null) {
Lookup.Result r = (Lookup.Result) o;
Collection infos = r.allInstances();
if (infos.isEmpty()) {
EventQueue.invokeLater(new SetterRunnable(new DefaultUserInformation()));
} else {
Iterator it = infos.iterator();
while (it.hasNext()) {
UserInformation info = it.next();
EventQueue.invokeLater(new SetterRunnable(info));
}
}
}
}
}
}
Notice we have a result. The result has attached to it a listener. The listener knows about DefaultUserInformation and the UserInformation interface, and that is it. It then knows it needs to listen for instances of UserInformation and act accordingly. It doesn't know how it got there, but knows what it must do with it. We then have some other code in another class which will inject the instances into the CentralLookup based on some user input removing any previous:
private void buttonActionPerformed(java.awt.event.ActionEvent evt) {
//ok we need to remove any user information from the central lookup
//and then we need to add this new one
CentralLookup cl = CentralLookup.getDefault();
Collection infos = cl.lookupAll(UserInformation.class);
if(!infos.isEmpty()){
Iterator it = infos.iterator();
while(it.hasNext()){
UserInformation info = it.next();
cl.remove(info);
}
}
DefaultUserInformation info = new DefaultUserInformation();
info.setName(name.getText());
info.setPassword(pwd.getText());
info.setUserID(uid.getText());
info.setToken(token.getText());
cl.add(info);
}
You can get a good idea from here the possibilities. This is a rather simple example, but it certainly shows it working. This can be used for any other services which need to use regular POJOs and not much else. Why add more overhead of class wrappers etc when they are not needed for everything? Sometimes one just needs a dynamic application context which can breakup the application into a more modular framework of simple classes and interfaces without major restrictions.
I have an AVI video formatted video of this in action. It is a very simple example, but it shows it working. The one piece of code doesn't know anything other than the fact that user information will appear magically in the CentralLookup in the form of the UserInformation interface.
I create a simple class and API in a NetBeans module and called it CentralLookup. This is all the code for such a simple thing (please ignore the formatting of the code...maybe I can update it later, but it seems blogger isn't wanting to format it correctly when posted):
package org.netbeans.modules.centrallookup.api;
import java.util.Collection;
import org.openide.util.Lookup.Result;
import org.openide.util.lookup.AbstractLookup;
import org.openide.util.lookup.InstanceContent;
/**
* Class used to house anything one might want to store
* in a central lookup which can affect anything within
* the application. It can be thought of as a central context
* where any application data may be stored and watched.
*
* A singleton instance is created using @see getDefault().
* This class is as thread safe as Lookup. Lookup appears to be safe.
* @author Wade Chandler
* @version 1.0
*/
public class CentralLookup extends AbstractLookup {
private InstanceContent content = null;
private static CentralLookup def = new CentralLookup();
public CentralLookup(InstanceContent content) {
super(content);
this.content = content;
}
public CentralLookup() {
this(new InstanceContent());
}
public void add(Object instance) {
content.add(instance);
}
public void remove(Object instance) {
content.remove(instance);
}
public static CentralLookup getDefault(){
return def;
}
}
The nice thing about this code is that it is real simple. The strange thing for me is that there hasn't been something already implemented in the base RCP. It seems pretty common a thing. For instance, the normal global lookups deal with Actions, Services, and Nodes (which are part of the NetBeans data model), and that is fine until one needs to work with generic interfaces and classes from a global perspective.
Regardless, I can now write code to listen to changes in this global context or Lookup in this case. The code doesn't have to know about any implementation except for the code which does the injection, and the code in other places can just setup a result and a listener. The following illustrates this a bit, and of course it is just a sub-set of the code:
final class CentralLookupTest1TopComponent extends TopComponent {
private static CentralLookupTest1TopComponent instance;
private Lookup.Result
Lookup.Template
userInfoResult = cl.lookup(template);
userInfoResult.addLookupListener(new UserInformationListener());
}
private javax.swing.JTextField name;
private javax.swing.JTextField pwd;
private javax.swing.JTextField token;
private javax.swing.JTextField uid;
private class SetterRunnable implements Runnable {
UserInformation ui = null;
public SetterRunnable(UserInformation ui) {
this.ui = ui;
}
public void run() {
name.setText(ui.getName());
pwd.setText(ui.getPassword());
uid.setText(ui.getUserID());
token.setText(ui.getToken());
}
}
private class UserInformationListener implements LookupListener {
public void resultChanged(LookupEvent evt) {
Object o = evt.getSource();
if (o != null) {
Lookup.Result
Collection infos = r.allInstances();
EventQueue.invokeLater(new SetterRunnable(new DefaultUserInformation()));
} else {
Iterator it = infos.iterator();
while (it.hasNext()) {
UserInformation info = it.next();
EventQueue.invokeLater(new SetterRunnable(info));
}
}
}
}
}
}
Notice we have a result. The result has attached to it a listener. The listener knows about DefaultUserInformation and the UserInformation interface, and that is it. It then knows it needs to listen for instances of UserInformation and act accordingly. It doesn't know how it got there, but knows what it must do with it. We then have some other code in another class which will inject the instances into the CentralLookup based on some user input removing any previous:
private void buttonActionPerformed(java.awt.event.ActionEvent evt) {
//ok we need to remove any user information from the central lookup
//and then we need to add this new one
CentralLookup cl = CentralLookup.getDefault();
Collection infos = cl.lookupAll(UserInformation.class);
if(!infos.isEmpty()){
Iterator it = infos.iterator();
while(it.hasNext()){
UserInformation info = it.next();
cl.remove(info);
}
}
DefaultUserInformation info = new DefaultUserInformation();
info.setName(name.getText());
info.setPassword(pwd.getText());
info.setUserID(uid.getText());
info.setToken(token.getText());
cl.add(info);
}
You can get a good idea from here the possibilities. This is a rather simple example, but it certainly shows it working. This can be used for any other services which need to use regular POJOs and not much else. Why add more overhead of class wrappers etc when they are not needed for everything? Sometimes one just needs a dynamic application context which can breakup the application into a more modular framework of simple classes and interfaces without major restrictions.
I have an AVI video formatted video of this in action. It is a very simple example, but it shows it working. The one piece of code doesn't know anything other than the fact that user information will appear magically in the CentralLookup in the form of the UserInformation interface.
2007-07-27
I have updated my "Java Text Copy Paste Module/Plugin"
The Java Text Copy Paste Module/Plugin now works in NetBeans 6.0. I tested it and am using it in 6.0. The module helps copy and paste text from and to Java source code. This module works well with SQL or HTML or XML which needs to be embedded in Java source code or needs to be extracted from Java source code. Look for the "Java Text Copy and Paste" context menu inside Java source files. There are no default hot keys for the functionality. I suggest playing around with the different actions to get a feel for how they work. + signs are pre-pended at the beginning of lines of source to make hand editing of generated code easier.
This module allows source code to be selected then formatted back into the text format it was before converted into Java source. It also allows one to select XML, HTML, or SQL in their favorite tool (as text) and then paste into the NetBeans Java editor where it is automatically formatted as Java source code. I find I use it all the time and comes in very handy.
Version 1.1 added a new way to copy the text from the editor which keeps newlines in the selected text yet removes any newlines fromJ the actual Java sources.
Version 1.2 adds tested support for NetBeans 6.0 and corrects a bug which deals with concurrent access of the edited document. The bug has not shown any issues yet, but possibly could as concurrent access could have unknown results.
Version 1.3 fixes an issue dealing with the context menu sorting and NetBeans 6.0.
Enjoy!
This module allows source code to be selected then formatted back into the text format it was before converted into Java source. It also allows one to select XML, HTML, or SQL in their favorite tool (as text) and then paste into the NetBeans Java editor where it is automatically formatted as Java source code. I find I use it all the time and comes in very handy.
Version 1.1 added a new way to copy the text from the editor which keeps newlines in the selected text yet removes any newlines fromJ the actual Java sources.
Version 1.2 adds tested support for NetBeans 6.0 and corrects a bug which deals with concurrent access of the edited document. The bug has not shown any issues yet, but possibly could as concurrent access could have unknown results.
Version 1.3 fixes an issue dealing with the context menu sorting and NetBeans 6.0.
Enjoy!
2007-07-24
Sharing classes with modules and non-module based JARs in a NetBeans RCP Application
Sometimes, such as when using JPA or Hibernate from more than one module, it is necessary to share classes between any number of modules and non-module based libraries/JARs in a NetBeans RCP/Platform based application. The reason this solution is needed is because some libraries, and even at times modules, need to be able to see classes from other libraries and modules at runtime to use certain patterns and these classes and modules have a cyclic dependency because of the type of classes being used. JPA or Hibernate are perfect examples where the entity manager will reside in one library and needs to be able to create instances of classes from another library or module, which also references other JPA or Hibernate classes themselves, using annotations or XML descriptors. This usually happens dynamically at runtime in these type situations.
In NetBeans the module system provides good separation. The problem is this can at times be too strict. To work around this issue you need to create a custom platform and then find the platform#/core directory under the platform directory and put the libraries and JARs in it. I will update this later to explain how to setup a custom platform.
Once you have the libraries in the core directory they can be used by any module or other library at runtime. These JARs can be copied to the core folder at build time and before distribution using ANT, so it is a good idea to make this custom platform reside relative to your project. Another good reason to have them reside relative to the project is that these common JAR files will have to be referenced by your module projects. To reference these JARs from your module projects you will have to edit project.properties and add a property:
cp.extra
which is a colon delimited list of JAR files needed for the classes the particular module needs to reference. Once cp.extra is setup, any errors you may see in the Java editor, related to these classes, should disappear and you can actually compile your project.
It is best to avoid doing this if possible as it removes the ability to use different versions of the same libraries by different modules while also removing the ability to auto-update these libraries, but when it is not possible to avoid such things then they are certainly needed. You wouldn't shoot yourself in the foot for spite, nor do I suspect you would not complete your project just because it best to not step outside the bounds of the regular module class loaders.
In NetBeans the module system provides good separation. The problem is this can at times be too strict. To work around this issue you need to create a custom platform and then find the platform#/core directory under the platform directory and put the libraries and JARs in it. I will update this later to explain how to setup a custom platform.
Once you have the libraries in the core directory they can be used by any module or other library at runtime. These JARs can be copied to the core folder at build time and before distribution using ANT, so it is a good idea to make this custom platform reside relative to your project. Another good reason to have them reside relative to the project is that these common JAR files will have to be referenced by your module projects. To reference these JARs from your module projects you will have to edit project.properties and add a property:
cp.extra
which is a colon delimited list of JAR files needed for the classes the particular module needs to reference. Once cp.extra is setup, any errors you may see in the Java editor, related to these classes, should disappear and you can actually compile your project.
It is best to avoid doing this if possible as it removes the ability to use different versions of the same libraries by different modules while also removing the ability to auto-update these libraries, but when it is not possible to avoid such things then they are certainly needed. You wouldn't shoot yourself in the foot for spite, nor do I suspect you would not complete your project just because it best to not step outside the bounds of the regular module class loaders.
2007-03-07
I'm a Netbeans Dream Team member
I'm a member of a new Netbeans group called the Dream Team. We are all supporters of the open-source Netbeans project. We work to promote and improve Netbeans. See www.netbeans.org which has a RCP package and a Java IDE. To me it is the best Java development environment available with many out of the box features. Best of all: it's free. I also contribute patches and modules/plug-ins to the project.
New Netbeans Module for copying and pasting text formats to and from Java source code
I created this module when I finally became tired of having to un-format large SQL queries I did not have a copy of any where other than Java source code. I ran into this large query from the past which used many many joins from this huge database. I was hours into trying to figure out what I had missed in the un-format process because Oracle's error message was more confusing than looking at the SQL. I finally decided it would be easier to write a Netbeans modules to just copy the formatted Java source code SQL String and paste it as un-formatted SQL into TOAD my SQL tool. After an evening of hacking at the module I have something which works great. It also does the reverse operation. I have been using it for a month now and it works great. I submitted it to the Netbeans contrib site hoping it might help someone else. I'll upload it the new Netbeans Plug-in Portal site when it goes live. Look for http://plugins.netbeans.org/ to go live soon.
2006-02-02
Netbeans Modules Development Update
I have been working on a Library->Module Converter for the J2SE Library Manager in Netbeans 5.0. I have it working well. I wanted to add a feature to allow the module to install beans to the 'Form Editor' palette when started. The module currently allows one to select a library and export this to a module which can then be used by both Netbeans Module Projects as a module dependency and as a J2SE library in a Standard Project type. More on this later and I will be trying to add the module to NBExtras.org as well as placing it on contrib.netbeans.org once I get my 'Contributor Agreement' signed and faxed or mailed in.
Subscribe to:
Posts (Atom)