That's all for now...I'm looking forward to using another great product from the Netbeans team!
I am an application developer, database administrator, technical writer, and Java evangelist. Frequent this blog to learn from my experiences in Java, JavaEE, PL/SQL, and Python/Jython development. Follow my tweets @ http://twitter.com/javajuneau
Tuesday, April 29, 2008
Netbeans 6.1 - Out of the Box
I really haven't gotten too far into it yet, but I've just installed Netbeans 6.1 final edition. So far, I can say that the start up time seems good, and I am glad that all of my libraries were migrated out-of-the-box. I simply used the import prompt to grab all of my settings from 6.1 and I was good to go. This is great news...it means that I can just start using Netbeans 6.1 with no additional configuration overhead.
Wednesday, April 23, 2008
Grails - Coding and Accessing a simple custom controller method
If you've ever worked with Grails, then you know how easy it is to create domain classes which map to database tables. Similarly, it is easy to access the database via the automatically generated conroller methods that are available (create, list, delete, save, edit, show). However, if you need to perform a particular operation against the database which is not accomplished by using any of these automatically generated methods, it is still easy...but perhaps not very intuative. Once you learn how to accomplish this task then the entire power behind using hibernate and accessing your database is at your hands.
It really is as easy as 1, 2, 3 to create additional controller methods...especially if you know how to use the Groovy language itself. I will show you how to create a simple finder method which takes a parameter and searches a particular database table for the value of that parameter...then it returns the results.
As you already know, the list method for each Grails controller is already created for you...let's look at my list method for the "Test" domain class (database table):
def list = {
if(!params.max) params.max = 10
[ testList: Test.list( params) ]
}
This is all well and good, but it returns the entire dataset for the Test database table. What if I only wish to return all of the records which have foreign key id of 35? Let's say that our foreign key id variable is fkId to make it simple. So what we want is to return all members of the list returned using the "list" method above which have fkId == 35.
We need to first obtain the complete list of results, and then filter it out accordingly. This is where the power of Groovy comes into play. We could use Java and write a filter so that we iterate through each of the items in the complete list of results searching for instances where fkId == 35 and then adding those matching objects to another list. That would be lots of code though. Let's use a Groovy closure to accomplish the same thing. Take a look at the "find" method which does just that:
def find = {
def testList = Test.list( params)
[testSearch : testList.findAll{it.fkId == Integer.valueOf(params.fkId)}]
}
Ok, simplicity at it's finest! We first obtain the complete list from the database table into the testList object. Then, we use the Groovy "findAll" method to search that list for all instances where fkId == the value of our parameter which is passed in (params.fkId)...let's assume that the parameter equals 35. We store our results in the testSearch list.
Now, how do we access this method? Well, we have to create a Groovy Server Page named find.gsp to show our results. We also need to pass the fkId parameter to this method somehow. Here is a simple find.gsp which will iterate through all of the objects which are returned within the testSearch list. Of course...this is just a quick page with ugly results...but you can clean it up to suit your needs.
find.gsp:
It really is as easy as 1, 2, 3 to create additional controller methods...especially if you know how to use the Groovy language itself. I will show you how to create a simple finder method which takes a parameter and searches a particular database table for the value of that parameter...then it returns the results.
As you already know, the list method for each Grails controller is already created for you...let's look at my list method for the "Test" domain class (database table):
def list = {
if(!params.max) params.max = 10
[ testList: Test.list( params) ]
}
This is all well and good, but it returns the entire dataset for the Test database table. What if I only wish to return all of the records which have foreign key id of 35? Let's say that our foreign key id variable is fkId to make it simple. So what we want is to return all members of the list returned using the "list" method above which have fkId == 35.
We need to first obtain the complete list of results, and then filter it out accordingly. This is where the power of Groovy comes into play. We could use Java and write a filter so that we iterate through each of the items in the complete list of results searching for instances where fkId == 35 and then adding those matching objects to another list. That would be lots of code though. Let's use a Groovy closure to accomplish the same thing. Take a look at the "find" method which does just that:
def find = {
def testList = Test.list( params)
[testSearch : testList.findAll{it.fkId == Integer.valueOf(params.fkId)}]
}
Ok, simplicity at it's finest! We first obtain the complete list from the database table into the testList object. Then, we use the Groovy "findAll" method to search that list for all instances where fkId == the value of our parameter which is passed in (params.fkId)...let's assume that the parameter equals 35. We store our results in the testSearch list.
Now, how do we access this method? Well, we have to create a Groovy Server Page named find.gsp to show our results. We also need to pass the fkId parameter to this method somehow. Here is a simple find.gsp which will iterate through all of the objects which are returned within the testSearch list. Of course...this is just a quick page with ugly results...but you can clean it up to suit your needs.
find.gsp:
<g:each in="${testSearch}" status="i" var="test">
FieldOne: ${test.fieldOne}
FieldTwo: ${test.fieldTwo}
</g:each>
Now, what is the URL which we use in order to access our new controller and page? Assume that our application name is "site" and we are passing a parameter of fkId = 35...
http://localhost:8080/site/test/find?fkId=35
Easy enough, but it took me a bit of time to figure out when I first tried it. Hopefully this post will save you some time and get you adding some much needed functionality to your standard Grails app.
Friday, April 18, 2008
Groovy - Grails Work
Onto new stuff...I have been working a lot with Grails lately. This is the technology that I have chosen to use for the implementation of the gathereventplanning.com website. While Grails is easy to use out of the box, I have found myself searching the net for information regarding customization. No doubt about it, unless you are creating your own simple CRUD application, you will want to customize the program in one way or another.
There have been many articles and blogs written about creating Grails applications and customizing them, but perhaps one of the best I have found so far is the Mastering Grails series...it has been quite helpful thus far.
I'm not going to get too technical in this brief post, but I will say that I have found a bug already. The issue resides in the Grails 1.0.2 release. I had created and customized a tiny CRUD application for testing purposes using the embedded database that comes with Grails. All was good until I attempted to "hook" my program to a PostgreSQL database instead. At that point the application was in read-only mode as it was unable to perform any batch inserts or updates to the database. Each time I tried to insert or update data, I received a stack trace stating that there was a SQL Grammar error.
I scratched my head for days on this one, looked at lots of hibernate documenation (since this is used behind the scenes in Grails), and even tried to change my domain model a bit to see if that would work. Eventually, I ended up downloading Grails 1.0.1 and trying to do the same thing. It works perfectly...no issues as yet. I have been able to successfully re-create my small application and use a PostgreSQL database without issues.
My guess is that this will be resolved with Grails 1.0.3 release, but we will see. So far, I love Grails as it is quite powerful and easy to use. Other than the bug I found, the only complaint I have is that Grails is so involved...many plug-ins are available and the Grails documentation is huge as it is. If you really want to become an expert Grails developer, you will be doing a lot of studying...but learning new technology like this is fun stuff.
There have been many articles and blogs written about creating Grails applications and customizing them, but perhaps one of the best I have found so far is the Mastering Grails series...it has been quite helpful thus far.
I'm not going to get too technical in this brief post, but I will say that I have found a bug already. The issue resides in the Grails 1.0.2 release. I had created and customized a tiny CRUD application for testing purposes using the embedded database that comes with Grails. All was good until I attempted to "hook" my program to a PostgreSQL database instead. At that point the application was in read-only mode as it was unable to perform any batch inserts or updates to the database. Each time I tried to insert or update data, I received a stack trace stating that there was a SQL Grammar error.
I scratched my head for days on this one, looked at lots of hibernate documenation (since this is used behind the scenes in Grails), and even tried to change my domain model a bit to see if that would work. Eventually, I ended up downloading Grails 1.0.1 and trying to do the same thing. It works perfectly...no issues as yet. I have been able to successfully re-create my small application and use a PostgreSQL database without issues.
My guess is that this will be resolved with Grails 1.0.3 release, but we will see. So far, I love Grails as it is quite powerful and easy to use. Other than the bug I found, the only complaint I have is that Grails is so involved...many plug-ins are available and the Grails documentation is huge as it is. If you really want to become an expert Grails developer, you will be doing a lot of studying...but learning new technology like this is fun stuff.
Monday, April 14, 2008
Netbeans 6.1 Beta - Subtle Issues
I've been using Netbeans 6.1 beta for most of my development since it has become available. Until recently, I hadn't noticed any issues while using it. Late last week I think I've encountered a subtle, but time consuming issue.
I am in the process of migrating my Seam applications from 1.x to 2.0.1 at this time. In doing so, I am also adjusting libraries within Netbeans as necessary. As you may know, when moving from older versions of Seam you must update all JSF pages to comply with JSF 1.2 standards...so these libraries must be updated as well.
The issue arose when I attempted to deploy one of my applications to my test environment which is running Glassfish V2. Many class not found issues appeared in the server log each time I tried to deploy. At the bottom of the stack trace I received a misleading message stating that there were "Errors in the EjbDescriptor". This led me searching my ejb-jar.xml, pages.xml, and web.xml files looking for issues. As none were found, I tried to give it the old clean, rebuild, and deploy once again...same issue.
At this point I began comparing with another successful Seam 2.0 migration and there were really no apparent differences. I spotted the problem when I went to the file system and looked in the application's dist directory. None of my Seam 2.0 libraries were being packaged with the deployment.
As it turns out, if you repackage and change libraries for an existing application within Netbeans 6.1 beta, then you must do the following:
1) Right click on the project, and choose properties.
2) Navigate to Libraries and make necessary changes.
3) YOU MUST check and uncheck the package checkbox within the libraries configuration...even if it is checked by default. This must update the build script for Netbeans because this was checked by default, but my libraries were not included.
After I unchecked the library package box and then re-checked it everything worked fine. The necessary JAR files that are contained within my included Netbeans libraries were deployed with my app and it works fine now.
Not a big issue, but an issue that is definitely not obvious and took me some time to figure out. I still recommend Netbeans 6.1...but I am not moving to RC1 at this time. I will probably wait for the production release because I do not want to migrate my libraries manually...
Happy NetBeaning....
I am in the process of migrating my Seam applications from 1.x to 2.0.1 at this time. In doing so, I am also adjusting libraries within Netbeans as necessary. As you may know, when moving from older versions of Seam you must update all JSF pages to comply with JSF 1.2 standards...so these libraries must be updated as well.
The issue arose when I attempted to deploy one of my applications to my test environment which is running Glassfish V2. Many class not found issues appeared in the server log each time I tried to deploy. At the bottom of the stack trace I received a misleading message stating that there were "Errors in the EjbDescriptor". This led me searching my ejb-jar.xml, pages.xml, and web.xml files looking for issues. As none were found, I tried to give it the old clean, rebuild, and deploy once again...same issue.
At this point I began comparing with another successful Seam 2.0 migration and there were really no apparent differences. I spotted the problem when I went to the file system and looked in the application's dist directory. None of my Seam 2.0 libraries were being packaged with the deployment.
As it turns out, if you repackage and change libraries for an existing application within Netbeans 6.1 beta, then you must do the following:
1) Right click on the project, and choose properties.
2) Navigate to Libraries and make necessary changes.
3) YOU MUST check and uncheck the package checkbox within the libraries configuration...even if it is checked by default. This must update the build script for Netbeans because this was checked by default, but my libraries were not included.
After I unchecked the library package box and then re-checked it everything worked fine. The necessary JAR files that are contained within my included Netbeans libraries were deployed with my app and it works fine now.
Not a big issue, but an issue that is definitely not obvious and took me some time to figure out. I still recommend Netbeans 6.1...but I am not moving to RC1 at this time. I will probably wait for the production release because I do not want to migrate my libraries manually...
Happy NetBeaning....
Monday, April 07, 2008
Shameless Self-Advertising
Time for a bit of shameless self-advertising. I'd like to let everyone know about a new hosting service I've started to assist individuals in event planning. If you or anyone you know needs to plan an event sometime soon, please take a look at my site and see if it will help out. Gather Event Planning offers individuals their own dedicated web site for organizing an event. The website includes a news blog, member registration, member forum, email contact lists, and much more to help aid in the process of planning an organized event.
There is no fee to try the service...only an email address is required. If you use the service for less than 30 days then it is free. This will allow anyone to plan a short-term event (such as a surprise party) without incurring any charges. There are plans available for those who wish to host a long-term event site for class reunions and such.
Enough gabbing about the service, feel free to give it a try and then let me know what you think.
Visit the site at http://www.gathereventplanning.com for more details.
There is no fee to try the service...only an email address is required. If you use the service for less than 30 days then it is free. This will allow anyone to plan a short-term event (such as a surprise party) without incurring any charges. There are plans available for those who wish to host a long-term event site for class reunions and such.
Enough gabbing about the service, feel free to give it a try and then let me know what you think.
Visit the site at http://www.gathereventplanning.com for more details.
SeamFramework.org - In case you did not know...
I wanted to let everyone know about another great JBoss SEAM resource, it is the seamframework.org website. This site includes a lot of documentation, as well as a community for SEAM developers.
Another good reason to use the SEAM framework!
Another good reason to use the SEAM framework!
Jython Monthly Call for Articles - April 2008
The April 2008 edition of the Jython Monthly newsletter is scheduled for distribution on April 15, 2008.
Please post any articles or contributions for the April 2008 distribution of the Jython Monthly newsletter at the following link:
http://wiki.python.org/jython/JythonMonthly/Articles/April2008
Visit http://wiki.python.org/jython/JythonMonthly/Articles/Submitting for details regarding newsletter artical submittals.
All contributions are appreciated! Please feel free to contact me if you have any questions.
Please post any articles or contributions for the April 2008 distribution of the Jython Monthly newsletter at the following link:
http://wiki.python.org/jython/JythonMonthly/Articles/April2008
Visit http://wiki.python.org/jython/JythonMonthly/Articles/Submitting for details regarding newsletter artical submittals.
All contributions are appreciated! Please feel free to contact me if you have any questions.
Tuesday, April 01, 2008
Groovy Netbeans Plugin
After searching for a while to find information regarding the Groovy and Grails Netbeans plugin, I determined that it is only available if you download and use a nightly build. You must download a nightly build and then go to the plugin manager to find it.
Ok, that is good news, so now I will get to try out the plugin and see how it works. One slight reminder though, if you download and use a Netbeans nightly build then none of your created libraries will be carried forward. I've got too many libraries created so I plan on using the nightly build to evaluate the Groovy plugin only...I will continue my day-to-day development on the NB 6.1 release.
I wonder if a Jython plugin is in the future? One would think that since a couple of Jython gurus have been hired by Sun, we may have some hope for good Jython support in a future Netbeans release...let's hope so!
Ok, that is good news, so now I will get to try out the plugin and see how it works. One slight reminder though, if you download and use a Netbeans nightly build then none of your created libraries will be carried forward. I've got too many libraries created so I plan on using the nightly build to evaluate the Groovy plugin only...I will continue my day-to-day development on the NB 6.1 release.
I wonder if a Jython plugin is in the future? One would think that since a couple of Jython gurus have been hired by Sun, we may have some hope for good Jython support in a future Netbeans release...let's hope so!
Wednesday, March 19, 2008
Netbeans 6.1 Beta
I've downloaded the latest Netbeans 6.1 beta release and installed it on my Mac today. I haven't had too much time to work with it as yet, but thus far I have found the following to be nice:
- No need to manually set up libraries or import projects, ALL of my settings from 6.0.1 have been imported successfully!
- Javascript support is nice
- Startup time has been greatly reduced!
These are some of the improvements I've seen within the last few minutes of looking around. It also seems like my applications build faster and deploy to Glassfish V2 with improved speed...
I have found one negative point so far...Facelets support is completely gone from what I can see. My facelets support plugin https://nbfaceletssupport.dev.java.net/ which worked in 6.0.1 does not load anymore. All XHTML documents now look like plain old JSP...but I cannot say whether code completion for facelets will work or not as I have not really had a chance to test thus far.
If you are looking to see improvements and don't mind losing the facelets plugin support, I recommend giving it a try.
- No need to manually set up libraries or import projects, ALL of my settings from 6.0.1 have been imported successfully!
- Javascript support is nice
- Startup time has been greatly reduced!
These are some of the improvements I've seen within the last few minutes of looking around. It also seems like my applications build faster and deploy to Glassfish V2 with improved speed...
I have found one negative point so far...Facelets support is completely gone from what I can see. My facelets support plugin https://nbfaceletssupport.dev.java.net/ which worked in 6.0.1 does not load anymore. All XHTML documents now look like plain old JSP...but I cannot say whether code completion for facelets will work or not as I have not really had a chance to test thus far.
If you are looking to see improvements and don't mind losing the facelets plugin support, I recommend giving it a try.
Tuesday, March 11, 2008
Jython Monthly Call for Articles - March 2008
The March 2008 edition of Jython Monthly is scheduled to be distributed next Tuesday, March 18th. Everyone would definitely like to see more articles and/or tutorials, so if you have any content that you'd like to share then please submit it to the following area:
http://wiki.python.org/jython/JythonMonthly/Articles/March2008
Thanks in advance for all contributions!
P.S - Way to go Frank!! Good luck at Sun!
http://wiki.python.org/jython/JythonMonthly/Articles/March2008
Thanks in advance for all contributions!
P.S - Way to go Frank!! Good luck at Sun!
Tuesday, February 12, 2008
Jython Monthly Call for Articles - February 2008
Please submit new articles and/or tutorials for the Feburary 2008 distribution of Jython Monthly. Feel free to write or teach about any topic that is Jython related...the more articles the better!
Thanks in advance for your participation!
Monday, February 11, 2008
JavaFX Script - An Excellent Read
I finished reading the JavaFX Script book by James Weaver a couple of days ago. I ordered this book from Amazon last November, and it just arrived last month. I have to say that I was getting a bit impatient about the delay, but it really was worth the wait.
If you are new to JavaFX like me, then you will find this to be an excellent starting point. The book is really geared towards developers who are interested in authoring small Swing-like applications. I'd have to say that it helped to have a good background in Swing prior to reading this book...but I think that anyone could pick it up and just start from scratch. James does a great job from start to finish as he builds upon concepts as the book goes on. It really is a start-to-finish book, but at 200 pages, that is not very rough to read straight through. It really is a quick read, and quickly jumps into the basics and works up from there. I was also impressed with the example applications used in the book as they gave me a great sense of what the language is capable of doing.
This book is definitely worth the read if you are interested in learning JavaFX basics and beyond.
If you are new to JavaFX like me, then you will find this to be an excellent starting point. The book is really geared towards developers who are interested in authoring small Swing-like applications. I'd have to say that it helped to have a good background in Swing prior to reading this book...but I think that anyone could pick it up and just start from scratch. James does a great job from start to finish as he builds upon concepts as the book goes on. It really is a start-to-finish book, but at 200 pages, that is not very rough to read straight through. It really is a quick read, and quickly jumps into the basics and works up from there. I was also impressed with the example applications used in the book as they gave me a great sense of what the language is capable of doing.
This book is definitely worth the read if you are interested in learning JavaFX basics and beyond.
Thursday, January 24, 2008
EJB 3.1 - Significant Changes Sound Promising
Being a big fan of the EJB 3.0 specification, I read this new EJB 3.1 New Features article published by Serverside right away. Clearly, the current EJB spec is much simpler to use and maintain than previous generations. Building upon that logic, the upcoming EJB 3.1 specification looks even better.
Real quick, I just wanted to point two of the features I found most interesting about this article. First, it sounds like interfaces will be made optional. This could be viewed as a bonus or a downfall, depending upon the way you look at it. Certainly removing the need for interfaces will simplify the writing of EJB code immensely. However, the benefits of using the loose-coupled approach may make EJB more difficult in some circumstances. If you enjoy unit testing of EJB code, this may make a big difference. However, since the specification plans to make this an optional feature then it will leave the implementation to the coder. Therefore, this seems to be a feature that can greatly benefit those who do not wish to write EJB interfaces.
Second, the article briefly mentions support for stateful web services and EJB timer service enhancements to support scheduling and/or deployment-time timer creation. I will be interested to hear more about these.
Give the article a read if you are interested in EJB...it is worth the time.
Real quick, I just wanted to point two of the features I found most interesting about this article. First, it sounds like interfaces will be made optional. This could be viewed as a bonus or a downfall, depending upon the way you look at it. Certainly removing the need for interfaces will simplify the writing of EJB code immensely. However, the benefits of using the loose-coupled approach may make EJB more difficult in some circumstances. If you enjoy unit testing of EJB code, this may make a big difference. However, since the specification plans to make this an optional feature then it will leave the implementation to the coder. Therefore, this seems to be a feature that can greatly benefit those who do not wish to write EJB interfaces.
Second, the article briefly mentions support for stateful web services and EJB timer service enhancements to support scheduling and/or deployment-time timer creation. I will be interested to hear more about these.
Give the article a read if you are interested in EJB...it is worth the time.
Thursday, January 10, 2008
Oracle JDeveloper 11g Technology Preview 3 Released
I recently downloaded the new JDeveloper 11g Tech Preview 3 for my Mac, and I am impressed. While I primarily use Netbeans for Java application development, the JDeveloper IDE is great for developing PL/SQL and Java Stored Procedures.
All of the new features in this technology preview are amazing. I understand that if you develop Java applications within the JDeveloper IDE then there have been many enhancements and improvements as well. For instance, the SOA and Web Services modules have had some significant adjustments.
My primary use of the JDeveloper IDE is for PL/SQL and Java Stored Procedure development. If you are looking to create and/or maintain any PL/SQL, then this tool can help you greatly. The new editor is nice, package body and header separation is a plus, and the automatic SQL command window is nice to have. One no longer needs to open a SQL Worksheet to invoke an SQL statement, it opens automatically when a database connection is selected. Of all the great SQL IDEs available today, I do not think any are better than JDeveloper for managing Oracle Java Stored Procedures. Straightforward and easy to manage, developing Java Stored Procedures for the Oracle database has never been easier.
I recommend downloading the technology preview and giving it a try. Even if you do not develop any SQL or PL/SQL code, you may find that it has some nice features to benefit your Java development.
All of the new features in this technology preview are amazing. I understand that if you develop Java applications within the JDeveloper IDE then there have been many enhancements and improvements as well. For instance, the SOA and Web Services modules have had some significant adjustments.
My primary use of the JDeveloper IDE is for PL/SQL and Java Stored Procedure development. If you are looking to create and/or maintain any PL/SQL, then this tool can help you greatly. The new editor is nice, package body and header separation is a plus, and the automatic SQL command window is nice to have. One no longer needs to open a SQL Worksheet to invoke an SQL statement, it opens automatically when a database connection is selected. Of all the great SQL IDEs available today, I do not think any are better than JDeveloper for managing Oracle Java Stored Procedures. Straightforward and easy to manage, developing Java Stored Procedures for the Oracle database has never been easier.
I recommend downloading the technology preview and giving it a try. Even if you do not develop any SQL or PL/SQL code, you may find that it has some nice features to benefit your Java development.
Tuesday, January 08, 2008
Glassfish - A Noteworthy Application Server
I've been running across quite a few blogs lately speaking about Glassfish. It appears that this great application server is being used by more people and gaining some real popularity. I've been using Glassfish since version one. Actually, prior to Project Glassfish, I used the Sun Java Application Server version 8.
I have nothing bad to say about Glassfish. It is an excellent choice for a JavaEE application server. Powerful and easy to use, this application server should not be overlooked if you are in the business of Java web development.
I have not yet tried out version 3, but I plan to do so very soon. I've been working primarily with Glassfish version 2 for the past few months. I've found it very easy to deploy JBOSS Seam applications to Glassfish even though there is no direct IDE deployment option for this setup as yet.
I will post any issues or concerns with using Glassfish V3 and JBOSS Seam...
I have nothing bad to say about Glassfish. It is an excellent choice for a JavaEE application server. Powerful and easy to use, this application server should not be overlooked if you are in the business of Java web development.
I have not yet tried out version 3, but I plan to do so very soon. I've been working primarily with Glassfish version 2 for the past few months. I've found it very easy to deploy JBOSS Seam applications to Glassfish even though there is no direct IDE deployment option for this setup as yet.
I will post any issues or concerns with using Glassfish V3 and JBOSS Seam...
Monday, November 19, 2007
Mac OSX Leopard - Spaces Information
I love OSX Leopard, especially the spaces feature. It is really nice to have several "Spaces" with different apps open on each. However, I did find one nuance that is a bit annoying. If you open an application which allows for multiple windows (such as Firefox), you must use all of the windows within the same space. That means you cannot open Firefox in Space 1 and then go into Space 2 and open another FireFox window.
Now, there is an easy work around to this, and that is simply opening up all of your Firefox windows within the same Space and then hitting F8 to show all Spaces. Once you have all spaces showing then you can drag the windows into separate spaces as you wish. The issue I have found with this is that if you use the dock to navigate and hit the Firefox icon then spaces may go berserk. I have had spaces go back and forth between windows until I intervened with a mouse click.
This becomes frustrating if you are trying to use an technology such as Java Web Start in one Space and another Firefox window in a separate space. If the Web Start application tries to fire another window (such as a report), then Spaces will go berserk again.
Really, this is not a big issue but I thought I would point it out for anyone who was having issues with Spaces. The easiest work around in this case is to only use Firefox or other such apps within once Space only.
Now, there is an easy work around to this, and that is simply opening up all of your Firefox windows within the same Space and then hitting F8 to show all Spaces. Once you have all spaces showing then you can drag the windows into separate spaces as you wish. The issue I have found with this is that if you use the dock to navigate and hit the Firefox icon then spaces may go berserk. I have had spaces go back and forth between windows until I intervened with a mouse click.
This becomes frustrating if you are trying to use an technology such as Java Web Start in one Space and another Firefox window in a separate space. If the Web Start application tries to fire another window (such as a report), then Spaces will go berserk again.
Really, this is not a big issue but I thought I would point it out for anyone who was having issues with Spaces. The easiest work around in this case is to only use Firefox or other such apps within once Space only.
Monday, November 05, 2007
OSX and JavaFX Script
Recently, there has been a ton of complaining that JDK6 has not been ported over to OSX 10.5 Leopard. I am a 10.4 Tiger user, and I am currently running Apple's Java 1.5 implementation. I like the Apple JDK 5 implementation...it looks much nicer than running Swing apps on Windows. However, I do hope that JDK 6 is available soon for OSX because I'd like to start using JavaFX within my Java programs on my Mac.
Without thinking twice, I downloaded Netbeans 6.0 Beta 2 and the JavaFX plugins on my Mac. I then started writing some FX code and calling it from native Java, and realized that I cannot code against the javax.script packages in JDK 5. I am now in need of JDK 6 to move forward with JavaFX on the Mac.
This blog post is just another posting regarding the desire for JDK 6 to be ported to OSX. I hope it comes soon...until then I am stuck with Windows for writing any JavaFX apps.
Without thinking twice, I downloaded Netbeans 6.0 Beta 2 and the JavaFX plugins on my Mac. I then started writing some FX code and calling it from native Java, and realized that I cannot code against the javax.script packages in JDK 5. I am now in need of JDK 6 to move forward with JavaFX on the Mac.
This blog post is just another posting regarding the desire for JDK 6 to be ported to OSX. I hope it comes soon...until then I am stuck with Windows for writing any JavaFX apps.
Wednesday, September 26, 2007
Jython Monthly - Call for Articles
After a long hiatus, the Jython Monthly newsletter will begin distribution again this October. If you have any content that you would like to post, please do so using this link. The October edition of Jython Monthly is scheduled for distribution on 10/9.
Thanks in advance for any article or tutorial submissions!
Thanks in advance for any article or tutorial submissions!
Wednesday, September 12, 2007
Migrating SEAM Applications from Glassfish V1 to Glassfish V2
I've come up with some simple steps for migrating a JBoss SEAM application from Glassfish V1 to Glassfish V2. Actually, you can configure all SEAM applications which you plan on deploying to Glassfish in this manner, and they will be deployable on either V1 or V2.
Keep in mind that I am also integrating Ajax4Jsf into my SEAM applications.
1) Update faces-config.xml (if needed) to ensure that you are using SeamFaceletViewHandler
<view-handler>org.jboss.seam.ui.facelet.SeamFaceletViewHandler</view-handler>
2) Update web.xml
- Add context-param for org.ajax4jsf.VIEW_HANDLERS
<context-param>
<param-name>org.ajax4jsf.VIEW_HANDLERS</param-name>
<param-value>org.jboss.seam.ui.facelet.SeamFaceletViewHandler</param-value>
</context-param>
- Add SUN Faces Listener
<listener>
<listener-class>com.sun.faces.config.ConfigureListener</listener-class>
</listener>
- If using Ajax4JSF, update the filter to include dispatchers
<filter-mapping>
<filter-name>ajax4jsf</filter-name>
<url-pattern>*.seam</url-pattern>
<dispatcher>REQUEST</dispatcher>
<dispatcher>FORWARD</dispatcher>
<dispatcher>INCLUDE</dispatcher>
</filter-mapping>
3) Ensure that all database drivers are installed on the new server.
4) If using Ajax4Jsf, you will want to ensure that you are packaging Apache Commons 3.2
Keep in mind that I am also integrating Ajax4Jsf into my SEAM applications.
1) Update faces-config.xml (if needed) to ensure that you are using SeamFaceletViewHandler
<view-handler>org.jboss.seam.ui.facelet.SeamFaceletViewHandler</view-handler>
2) Update web.xml
- Add context-param for org.ajax4jsf.VIEW_HANDLERS
<context-param>
<param-name>org.ajax4jsf.VIEW_HANDLERS</param-name>
<param-value>org.jboss.seam.ui.facelet.SeamFaceletViewHandler</param-value>
</context-param>
- Add SUN Faces Listener
<listener>
<listener-class>com.sun.faces.config.ConfigureListener</listener-class>
</listener>
- If using Ajax4JSF, update the filter to include dispatchers
<filter-mapping>
<filter-name>ajax4jsf</filter-name>
<url-pattern>*.seam</url-pattern>
<dispatcher>REQUEST</dispatcher>
<dispatcher>FORWARD</dispatcher>
<dispatcher>INCLUDE</dispatcher>
</filter-mapping>
3) Ensure that all database drivers are installed on the new server.
4) If using Ajax4Jsf, you will want to ensure that you are packaging Apache Commons 3.2
Friday, September 07, 2007
Creating RSS Reader Component Using SEAM and ROME
I've been working lately on an enterprise application which will be used for developing and maintaining an organization's website. The application is being written using JSF, JBoss SEAM 1.2.1 GA, Facelets, ROME, Ajax4Jsf, and deploying to Glassfish V1.
There was a requirement to have an RSS reader as well as the ability to create RSS feeds. I found that the Rome Project had all of the tools which I was going to require to make this function. It is a great RSS library, and if you code in Java and use RSS then I definitely recommend it.
I've created an RSS reader which uses an Oracle database back end to store a table of RSS feeds to parse. There is also a table of pages in the database, and each RSS feed record is tied to one or more of the pages. The RSS web page component can go on any page...as long as the page is registered in the database. An administrator then has the ability to add RSS feeds to be read on that page. The component uses AJAX to display a news title for 10 seconds, and then read the database and parse the next RSS entry in the feed. Once the component has read all of the entries for a particular feed, it looks for more feeds registered to that page. If it finds more then it will parse all entries within that feed and so on. In the end, the RSS reader is a component which simply displays news from one or more RSS feed sources using AJAX.
The Database
create table rss_feed as(
FEED_ID NUMBER,
CONTENT_PAGE_ID NUMBER,
FEED_URL VARCHAR2(1000),
FEED_NAME VARCHAR2(500));
alter table rss_feed
add constraint rss_feed_pk
primary key(feed_id);
create sequence rssapp_rss_feed_seq
start with 1
increment by 1;
(This assumes that you have a table which stores each page name along with a unique page id)
The Code
Since we are using EJB3 technology with the SEAM framework, we will require an Entity class for persistence. We also need an EJB session bean which will contain all of the RSS logic, along with a local interface.
Entity Class - Straight forward. I use Netbeans to create the initial class from the database, and then I add the SEAM annotations.
/*
* RssAppRssFeed.java
*/
package org.jj.entity;
import java.io.Serializable;
import java.math.BigDecimal;
import java.math.BigInteger;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.NamedQueries;
import javax.persistence.NamedQuery;
import javax.persistence.SequenceGenerator;
import javax.persistence.Table;
import org.jboss.seam.ScopeType;
import org.jboss.seam.annotations.Name;
import org.jboss.seam.annotations.Scope;
@Entity
@Scope(ScopeType.PAGE)
@Name("RssAppRssFeed")
@Table(name = "RSSAPP_RSS_FEED")
@NamedQueries( {
@NamedQuery(name = "RssAppRssFeed.findByFeedId", query = "SELECT f FROM RssAppRssFeed f WHERE f.feedId = :feedId"),
@NamedQuery(name = "RssAppRssFeed.findByContentPageId", query = "SELECT f FROM RssAppRssFeed f WHERE f.contentPageId = :contentPageId"),
@NamedQuery(name = "RssAppRssFeed.findByFeedUrl", query = "SELECT f FROM RssAppRssFeed f WHERE f.feedUrl = :feedUrl"),
@NamedQuery(name = "RssAppRssFeed.findByFeedName", query = "SELECT f FROM RssAppRssFeed f WHERE f.feedName = :feedName")
})
public class RssAppRssFeed implements Serializable {
@Id
@GeneratedValue(strategy=GenerationType.SEQUENCE,
generator="RssApp_rss_feed_seq_generator")
@SequenceGenerator(name="RssApp_rss_feed_seq_generator",sequenceName="RssApp_rss_feed_seq", allocationSize=1)
@Column(name = "FEED_ID", nullable = false)
private BigDecimal feedId;
@Column(name = "CONTENT_PAGE_ID")
private BigInteger contentPageId;
@Column(name = "FEED_URL")
private String feedUrl;
@Column(name = "FEED_NAME")
private String feedName;
/** Creates a new instance of RssAppRssFeed */
public RssAppRssFeed() {
}
/**
* Creates a new instance of RssAppRssFeed with the specified values.
* @param feedId the feedId of the RssAppRssFeed
*/
public RssAppRssFeed(BigDecimal feedId) {
this.feedId = feedId;
}
/**
* Gets the feedId of this RssAppRssFeed.
* @return the feedId
*/
public BigDecimal getFeedId() {
return this.feedId;
}
/**
* Sets the feedId of this RssAppRssFeed to the specified value.
* @param feedId the new feedId
*/
public void setFeedId(BigDecimal feedId) {
this.feedId = feedId;
}
/**
* Gets the contentPageId of this RssAppRssFeed.
* @return the contentPageId
*/
public BigInteger getContentPageId() {
return this.contentPageId;
}
/**
* Sets the contentPageId of this RssAppRssFeed to the specified value.
* @param contentPageId the new contentPageId
*/
public void setContentPageId(BigInteger contentPageId) {
this.contentPageId = contentPageId;
}
/**
* Gets the feedUrl of this RssAppRssFeed.
* @return the feedUrl
*/
public String getFeedUrl() {
return this.feedUrl;
}
/**
* Sets the feedUrl of this RssAppRssFeed to the specified value.
* @param feedUrl the new feedUrl
*/
public void setFeedUrl(String feedUrl) {
this.feedUrl = feedUrl;
}
/**
* Gets the feedName of this RssAppRssFeed.
* @return the feedName
*/
public String getFeedName() {
return this.feedName;
}
/**
* Sets the feedName of this RssAppRssFeed to the specified value.
* @param feedName the new feedName
*/
public void setFeedName(String feedName) {
this.feedName = feedName;
}
/**
* Returns a hash code value for the object. This implementation computes
* a hash code value based on the id fields in this object.
* @return a hash code value for this object.
*/
@Override
public int hashCode() {
int hash = 0;
hash += (this.feedId != null ? this.feedId.hashCode() : 0);
return hash;
}
/**
* Determines whether another object is equal to this RssAppRssFeed. The result is
*
* has the same id field values as this object.
* @param object the reference object with which to compare
* @return
*
*/
@Override
public boolean equals(Object object) {
// TODO: Warning - this method won't work in the case the id fields are not set
if (!(object instanceof RssAppRssFeed)) {
return false;
}
RssAppRssFeed other = (RssAppRssFeed)object;
if (this.feedId != other.feedId && (this.feedId == null || !this.feedId.equals(other.feedId))) return false;
return true;
}
/**
* Returns a string representation of the object. This implementation constructs
* that representation based on the id fields.
* @return a string representation of the object.
*/
@Override
public String toString() {
return "org.jj.entity.RssAppRssFeed[feedId=" + feedId + "]";
}
}
EJB Session Bean - Once again, I use Netbeans to generate the initial session bean from the entity class and I modify for SEAM. I then added all of the essential methods and logic for the RSS in working with ROME. You will notice that I did not use SEAM's @In @Out annotations on some of the variables...that is because I had issues when doing so. The code that I post here does work as expected. You will also see some doubleSubmitIndex variables...this is due to an issue I've seen with Ajax4Jsf. When I use the a4j:poll, the page seems to invoke the server method twice. It causes the RSS reader to skip entries within the feed. Therefore, I coded a work around which is kind of messy, but it works.
/*
* FeedReader.java
*/
package org.jj.beans;
import com.sun.net.ssl.SSLContext;
import com.sun.syndication.feed.synd.SyndEntryImpl;
import java.net.URL;
import java.io.InputStreamReader;
import com.sun.syndication.feed.synd.SyndFeed;
import com.sun.syndication.io.SyndFeedInput;
import com.sun.syndication.io.XmlReader;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import javax.ejb.Remove;
import javax.ejb.Stateful;
import javax.ejb.Stateless;
import javax.interceptor.Interceptors;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.Query;
import org.jj.entity.RssAppContentPage;
import org.jj.entity.RssAppRssFeed;
import org.jj.interfaces.FeedLocal;
import org.jj.utility.RssAppCommonTasks;
import org.jboss.seam.ScopeType;
import org.jboss.seam.annotations.Destroy;
import org.jboss.seam.annotations.Name;
import org.jboss.seam.annotations.Out;
import org.jboss.seam.annotations.Scope;
import org.jboss.seam.annotations.datamodel.DataModel;
/**
*
*/
@Stateful
@Scope(ScopeType.SESSION)
@Name("rssReader")
@Interceptors({org.jboss.seam.ejb.SeamInterceptor.class})
public class FeedReader implements FeedLocal {
@PersistenceContext(unitName="rssApp-ejbPU-FESSPROD")
private EntityManager em;
@DataModel
public List feedList=null;
private List rssFeedList = null;
private String pageName = null;
@Out(required=false)
private Feed feedBean;
private String feedText = null;
private Date feedDate = null;
private String feedTitle = null;
private int feedCounter;
private int feedEntryCounter;
private int feedIndex;
private int feedEntryIndex;
private int doubleSubmitIndex;
private int doubleSubmitFeedIndex;
private Query qry;
public void readFeed() {
pageName = RssAppCommonTasks.obtainPageName();
if (!pageName.equals("underMaintenance")){
qry = em.createQuery("select object(p) from RssAppContentPage as p " +
"where p.contentPage = :pageName")
.setParameter("pageName", pageName);
RssAppContentPage page = (RssAppContentPage) qry.getSingleResult();
qry = em.createQuery("select object(f) from RssAppRssFeed as f " +
"where f.contentPageId = :pageId")
.setParameter("pageId", page.getContentPageId());
rssFeedList = qry.getResultList();
// Parse rss feeds for page, if any
if (rssFeedList.size() > 0){
for(int index = 0; index <= rssFeedList.size()-1; index++){ boolean ok = false; int entryNumber = 0; int entryIndex = 0; RssAppRssFeed rssFeed = new RssAppRssFeed(); rssFeed = rssFeedList.get(index); System.out.println("BEGINNING RSS READ....."); if (rssFeed.getFeedUrl() != null) { try { feedList = null; URL feedUrl = new URL(rssFeed.getFeedUrl()); SyndFeedInput input = new SyndFeedInput(); SyndFeed feed = input.build(new XmlReader(feedUrl)); entryNumber = feed.getEntries().size(); initializeList(); for (entryIndex = 0; entryIndex <= entryNumber; entryIndex++){ System.out.println("Reading..."); feedBean = new Feed(); feedBean.setAuthor(feed.getAuthor()); feedBean.setDescription(feed.getDescription()); feedBean.setEntry(((SyndEntryImpl)feed.getEntries().get(entryIndex)).getTitle()); feedBean.setEntryLink(((SyndEntryImpl)feed.getEntries().get(entryIndex)).getLink()); feedBean.setEntryUpdatedDate(((SyndEntryImpl)feed.getEntries().get(entryIndex)).getPublishedDate()); feedBean.setTitle(feed.getTitle()); feedBean.setUri(feed.getUri()); feedList.add(feedBean); } ok = true; } catch (Exception ex) { ex.printStackTrace(); System.out.println("ERROR: "+ex.getMessage()); } } if (!ok) { System.out.println(); System.out.println("FeedReader reads and prints any RSS/Atom feed type."); System.out.println("The first parameter must be the URL of the feed to read."); System.out.println(); } } } } } /** * This method is invoked via ajax from the front end page in order to read * a new feed into the display. The ajax front end causes a double submit * to this method, so we need to adjust counters such that they will only update * on every other submit. We do this by using the doubleSubmitIndex numbers. */ public void updateFeed(){ if (doubleSubmitIndex > 1){
doubleSubmitIndex = 0;
}
if (doubleSubmitFeedIndex > 1){
doubleSubmitFeedIndex = 0;
}
pageName = RssAppCommonTasks.obtainPageName();
if (!pageName.equals("underMaintenance")){
qry = em.createQuery("select object(p) from RssAppContentPage as p " +
"where p.contentPage = :pageName")
.setParameter("pageName", pageName);
RssAppContentPage page = (RssAppContentPage) qry.getSingleResult();
qry = em.createQuery("select object(f) from RssAppRssFeed as f " +
"where f.contentPageId = :pageId")
.setParameter("pageId", page.getContentPageId());
rssFeedList = qry.getResultList();
/*
* Obtain a list of rss feeds for a particular web page. If feeds
* exist for that page, then enter the feed parse logic.
*/
if (rssFeedList.size() > 0){
feedCounter = rssFeedList.size();
if(this.getFeedIndex() > feedCounter - 1){
this.setFeedIndex(0);
}
boolean ok = false;
int entryIndex = 0;
/*
* Obtain all feed entries for this particular feed index
*/
RssAppRssFeed rssFeed = new RssAppRssFeed();
RssFeed = rssFeedList.get(getFeedIndex());
System.out.println("Feed Index: " + getFeedIndex() + " Entry Index: " + getFeedEntryIndex());
if (rssFeed.getFeedUrl() != null) {
try {
feedList = null;
URL feedUrl = new URL(rssFeed.getFeedUrl());
String feedEntryDateText = null;
String feedEntryText = null;
String feedEntryUrl = null;
SyndFeedInput input = new SyndFeedInput();
SyndFeed feed = input.build(new XmlReader(feedUrl));
/*
* Obtain count of all feed entries
*/
feedEntryCounter = feed.getEntries().size();
initializeList();
if(getFeedEntryIndex() > 0){
if (getFeedEntryIndex() > feedEntryCounter - 1){
setFeedEntryIndex(0);
}
}
System.out.println("Reading...");
feedBean = new Feed();
feedBean.setAuthor(feed.getAuthor());
feedBean.setDescription(feed.getDescription());
feedBean.setEntry(((SyndEntryImpl)feed.getEntries().get(getFeedEntryIndex())).getTitle());
feedBean.setEntryLink(((SyndEntryImpl)feed.getEntries().get(getFeedEntryIndex())).getLink());
feedBean.setEntryUpdatedDate(((SyndEntryImpl)feed.getEntries().get(getFeedEntryIndex())).getPublishedDate());
feedBean.setTitle(feed.getTitle());
setFeedTitle(feed.getTitle());
feedBean.setUri(feed.getUri());
feedList.add(feedBean);
this.feedDate = feedBean.getEntryUpdatedDate();
feedText = "" +
feedBean.getEntry() + "";
ok = true;
if(doubleSubmitIndex > 0) {
this.feedEntryIndex++;
doubleSubmitIndex++;
// If all entries within current feedIndex have been read, move on
// to the next feed and start with entry zero.
if (feedEntryIndex > feedEntryCounter - 1){
this.feedIndex++;
this.feedEntryIndex = 0;
}
} else {
doubleSubmitIndex++;
}
} catch (Exception ex) {
ex.printStackTrace();
System.out.println("ERROR: "+ex.getMessage());
}
}
if (!ok) {
System.out.println();
System.out.println("FeedReader reads and prints any RSS/Atom feed type.");
System.out.println("The first parameter must be the URL of the feed to read.");
System.out.println();
}
}
}
}
private void initializeList(){
if (feedList == null){
feedList = new ArrayList();
}
}
public String getFeedText() {
return feedText;
}
public void setFeedText(String feedText) {
this.feedText = feedText;
}
public String getFeedTitle() {
return feedTitle;
}
public void setFeedTitle(String feedTitle) {
this.feedTitle = feedTitle;
}
public int getFeedIndex() {
return feedIndex;
}
public void setFeedIndex(int feedIndex) {
this.feedIndex = feedIndex;
}
public int getFeedEntryIndex() {
return feedEntryIndex;
}
public void setFeedEntryIndex(int feedEntryIndex) {
this.feedEntryIndex = feedEntryIndex;
}
public Date getFeedDate() {
return feedDate;
}
public void setFeedDate(Date feedDate) {
this.feedDate = feedDate;
}
@Remove @Destroy
public void destroy(){}
}
Local Interface - Nothing exciting in the local interface
/**
* FeedLocal.java
*/
package org.jj.interfaces;
import java.util.Date;
public interface FeedLocal {
void readFeed();
java.lang.String getFeedText();
void setFeedText(String feedText);
void updateFeed();
void destroy();
int getFeedIndex();
void setFeedIndex(int feedIndex);
Date getFeedDate();
void setFeedDate(Date feedDate);
java.lang.String getFeedTitle();
void setFeedTitle(String feedTitle);
}
Utility Class - Here is an excerpt from my utility class. This code obtains the current page name from the FacesContext.
public final class RssAppCommonTasks {
public static String obtainPageName(){
String currentPageName = null;
Query qry = null;
String tempPageName = FacesContext.getCurrentInstance().getViewRoot().getViewId();
if (tempPageName.lastIndexOf("/") > 0) {
tempPageName = tempPageName.substring(tempPageName.lastIndexOf("/") + 1).replace(".seam","").replace(".xhtml","");
currentPageName = tempPageName;
System.out.println("tempPageName: " + currentPageName);
} else {
System.out.println("view id: " + FacesContext.getCurrentInstance().getViewRoot().getViewId());
System.out.println("updated view id: " +
FacesContext.getCurrentInstance().getViewRoot().getViewId().replace("/","").replace(".seam","").replace(".xhtml",""));
currentPageName = FacesContext.getCurrentInstance().getViewRoot().getViewId().replace("/","").replace(".seam","").replace(".xhtml","");
}
return currentPageName;
}
***
}
pages.xml - Each page which contains the RSS component code will require an element within the pages.xml file to invoke server-side code.
<page id="/myPage.xhtml" action="#{rssReader.updateFeed}">
Component code in the XHTML page - I haven't yet created a separate component/tag for this code, but it should work by simply copying and pasting this code in each page which uses the reader. The back end code then determines which page is calling the code and parses the feeds in the database which are tied to that page.
<div id="autoreader">
<a4j:poll interval="10000"
reRender="autoReaderText, autoReaderDate, feedTitle"
action="#{rssReader.updateFeed}">
</a4j:poll>
<p align="center" class="sub_head_sub"><br />
<h:outputText id="feedTitle"
value="#{rssReader.feedTitle}"/>
</p>
<table id="feedList" name="feedList">
<td bgcolor="#CCFFCC" style="width: 100px">
<h:outputText id="autoReaderDate"
value="#{rssReader.feedDate}"/>
</td>
<td bgcolor="#CCFFCC" style="width: 400px">
<h:outputText id="autoReaderText"
escape="false"
value="#{rssReader.feedText}"/>
</td>
</table>
</div>
That is all there is to it. There is a bit of code to write, but the end result is very appealing. Once complete, one can add or remove feeds from the database and have them automatically appear on the desired pages.
There was a requirement to have an RSS reader as well as the ability to create RSS feeds. I found that the Rome Project had all of the tools which I was going to require to make this function. It is a great RSS library, and if you code in Java and use RSS then I definitely recommend it.
I've created an RSS reader which uses an Oracle database back end to store a table of RSS feeds to parse. There is also a table of pages in the database, and each RSS feed record is tied to one or more of the pages. The RSS web page component can go on any page...as long as the page is registered in the database. An administrator then has the ability to add RSS feeds to be read on that page. The component uses AJAX to display a news title for 10 seconds, and then read the database and parse the next RSS entry in the feed. Once the component has read all of the entries for a particular feed, it looks for more feeds registered to that page. If it finds more then it will parse all entries within that feed and so on. In the end, the RSS reader is a component which simply displays news from one or more RSS feed sources using AJAX.
The Database
create table rss_feed as(
FEED_ID NUMBER,
CONTENT_PAGE_ID NUMBER,
FEED_URL VARCHAR2(1000),
FEED_NAME VARCHAR2(500));
alter table rss_feed
add constraint rss_feed_pk
primary key(feed_id);
create sequence rssapp_rss_feed_seq
start with 1
increment by 1;
(This assumes that you have a table which stores each page name along with a unique page id)
The Code
Since we are using EJB3 technology with the SEAM framework, we will require an Entity class for persistence. We also need an EJB session bean which will contain all of the RSS logic, along with a local interface.
Entity Class - Straight forward. I use Netbeans to create the initial class from the database, and then I add the SEAM annotations.
/*
* RssAppRssFeed.java
*/
package org.jj.entity;
import java.io.Serializable;
import java.math.BigDecimal;
import java.math.BigInteger;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.NamedQueries;
import javax.persistence.NamedQuery;
import javax.persistence.SequenceGenerator;
import javax.persistence.Table;
import org.jboss.seam.ScopeType;
import org.jboss.seam.annotations.Name;
import org.jboss.seam.annotations.Scope;
@Entity
@Scope(ScopeType.PAGE)
@Name("RssAppRssFeed")
@Table(name = "RSSAPP_RSS_FEED")
@NamedQueries( {
@NamedQuery(name = "RssAppRssFeed.findByFeedId", query = "SELECT f FROM RssAppRssFeed f WHERE f.feedId = :feedId"),
@NamedQuery(name = "RssAppRssFeed.findByContentPageId", query = "SELECT f FROM RssAppRssFeed f WHERE f.contentPageId = :contentPageId"),
@NamedQuery(name = "RssAppRssFeed.findByFeedUrl", query = "SELECT f FROM RssAppRssFeed f WHERE f.feedUrl = :feedUrl"),
@NamedQuery(name = "RssAppRssFeed.findByFeedName", query = "SELECT f FROM RssAppRssFeed f WHERE f.feedName = :feedName")
})
public class RssAppRssFeed implements Serializable {
@Id
@GeneratedValue(strategy=GenerationType.SEQUENCE,
generator="RssApp_rss_feed_seq_generator")
@SequenceGenerator(name="RssApp_rss_feed_seq_generator",sequenceName="RssApp_rss_feed_seq", allocationSize=1)
@Column(name = "FEED_ID", nullable = false)
private BigDecimal feedId;
@Column(name = "CONTENT_PAGE_ID")
private BigInteger contentPageId;
@Column(name = "FEED_URL")
private String feedUrl;
@Column(name = "FEED_NAME")
private String feedName;
/** Creates a new instance of RssAppRssFeed */
public RssAppRssFeed() {
}
/**
* Creates a new instance of RssAppRssFeed with the specified values.
* @param feedId the feedId of the RssAppRssFeed
*/
public RssAppRssFeed(BigDecimal feedId) {
this.feedId = feedId;
}
/**
* Gets the feedId of this RssAppRssFeed.
* @return the feedId
*/
public BigDecimal getFeedId() {
return this.feedId;
}
/**
* Sets the feedId of this RssAppRssFeed to the specified value.
* @param feedId the new feedId
*/
public void setFeedId(BigDecimal feedId) {
this.feedId = feedId;
}
/**
* Gets the contentPageId of this RssAppRssFeed.
* @return the contentPageId
*/
public BigInteger getContentPageId() {
return this.contentPageId;
}
/**
* Sets the contentPageId of this RssAppRssFeed to the specified value.
* @param contentPageId the new contentPageId
*/
public void setContentPageId(BigInteger contentPageId) {
this.contentPageId = contentPageId;
}
/**
* Gets the feedUrl of this RssAppRssFeed.
* @return the feedUrl
*/
public String getFeedUrl() {
return this.feedUrl;
}
/**
* Sets the feedUrl of this RssAppRssFeed to the specified value.
* @param feedUrl the new feedUrl
*/
public void setFeedUrl(String feedUrl) {
this.feedUrl = feedUrl;
}
/**
* Gets the feedName of this RssAppRssFeed.
* @return the feedName
*/
public String getFeedName() {
return this.feedName;
}
/**
* Sets the feedName of this RssAppRssFeed to the specified value.
* @param feedName the new feedName
*/
public void setFeedName(String feedName) {
this.feedName = feedName;
}
/**
* Returns a hash code value for the object. This implementation computes
* a hash code value based on the id fields in this object.
* @return a hash code value for this object.
*/
@Override
public int hashCode() {
int hash = 0;
hash += (this.feedId != null ? this.feedId.hashCode() : 0);
return hash;
}
/**
* Determines whether another object is equal to this RssAppRssFeed. The result is
*
true if and only if the argument is not null and is a RssAppRssFeed object that* has the same id field values as this object.
* @param object the reference object with which to compare
* @return
true if this object is the same as the argument;*
false otherwise.*/
@Override
public boolean equals(Object object) {
// TODO: Warning - this method won't work in the case the id fields are not set
if (!(object instanceof RssAppRssFeed)) {
return false;
}
RssAppRssFeed other = (RssAppRssFeed)object;
if (this.feedId != other.feedId && (this.feedId == null || !this.feedId.equals(other.feedId))) return false;
return true;
}
/**
* Returns a string representation of the object. This implementation constructs
* that representation based on the id fields.
* @return a string representation of the object.
*/
@Override
public String toString() {
return "org.jj.entity.RssAppRssFeed[feedId=" + feedId + "]";
}
}
EJB Session Bean - Once again, I use Netbeans to generate the initial session bean from the entity class and I modify for SEAM. I then added all of the essential methods and logic for the RSS in working with ROME. You will notice that I did not use SEAM's @In @Out annotations on some of the variables...that is because I had issues when doing so. The code that I post here does work as expected. You will also see some doubleSubmitIndex variables...this is due to an issue I've seen with Ajax4Jsf. When I use the a4j:poll, the page seems to invoke the server method twice. It causes the RSS reader to skip entries within the feed. Therefore, I coded a work around which is kind of messy, but it works.
/*
* FeedReader.java
*/
package org.jj.beans;
import com.sun.net.ssl.SSLContext;
import com.sun.syndication.feed.synd.SyndEntryImpl;
import java.net.URL;
import java.io.InputStreamReader;
import com.sun.syndication.feed.synd.SyndFeed;
import com.sun.syndication.io.SyndFeedInput;
import com.sun.syndication.io.XmlReader;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import javax.ejb.Remove;
import javax.ejb.Stateful;
import javax.ejb.Stateless;
import javax.interceptor.Interceptors;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.Query;
import org.jj.entity.RssAppContentPage;
import org.jj.entity.RssAppRssFeed;
import org.jj.interfaces.FeedLocal;
import org.jj.utility.RssAppCommonTasks;
import org.jboss.seam.ScopeType;
import org.jboss.seam.annotations.Destroy;
import org.jboss.seam.annotations.Name;
import org.jboss.seam.annotations.Out;
import org.jboss.seam.annotations.Scope;
import org.jboss.seam.annotations.datamodel.DataModel;
/**
*
*/
@Stateful
@Scope(ScopeType.SESSION)
@Name("rssReader")
@Interceptors({org.jboss.seam.ejb.SeamInterceptor.class})
public class FeedReader implements FeedLocal {
@PersistenceContext(unitName="rssApp-ejbPU-FESSPROD")
private EntityManager em;
@DataModel
public List
private List
private String pageName = null;
@Out(required=false)
private Feed feedBean;
private String feedText = null;
private Date feedDate = null;
private String feedTitle = null;
private int feedCounter;
private int feedEntryCounter;
private int feedIndex;
private int feedEntryIndex;
private int doubleSubmitIndex;
private int doubleSubmitFeedIndex;
private Query qry;
public void readFeed() {
pageName = RssAppCommonTasks.obtainPageName();
if (!pageName.equals("underMaintenance")){
qry = em.createQuery("select object(p) from RssAppContentPage as p " +
"where p.contentPage = :pageName")
.setParameter("pageName", pageName);
RssAppContentPage page = (RssAppContentPage) qry.getSingleResult();
qry = em.createQuery("select object(f) from RssAppRssFeed as f " +
"where f.contentPageId = :pageId")
.setParameter("pageId", page.getContentPageId());
rssFeedList = qry.getResultList();
// Parse rss feeds for page, if any
if (rssFeedList.size() > 0){
for(int index = 0; index <= rssFeedList.size()-1; index++){ boolean ok = false; int entryNumber = 0; int entryIndex = 0; RssAppRssFeed rssFeed = new RssAppRssFeed(); rssFeed = rssFeedList.get(index); System.out.println("BEGINNING RSS READ....."); if (rssFeed.getFeedUrl() != null) { try { feedList = null; URL feedUrl = new URL(rssFeed.getFeedUrl()); SyndFeedInput input = new SyndFeedInput(); SyndFeed feed = input.build(new XmlReader(feedUrl)); entryNumber = feed.getEntries().size(); initializeList(); for (entryIndex = 0; entryIndex <= entryNumber; entryIndex++){ System.out.println("Reading..."); feedBean = new Feed(); feedBean.setAuthor(feed.getAuthor()); feedBean.setDescription(feed.getDescription()); feedBean.setEntry(((SyndEntryImpl)feed.getEntries().get(entryIndex)).getTitle()); feedBean.setEntryLink(((SyndEntryImpl)feed.getEntries().get(entryIndex)).getLink()); feedBean.setEntryUpdatedDate(((SyndEntryImpl)feed.getEntries().get(entryIndex)).getPublishedDate()); feedBean.setTitle(feed.getTitle()); feedBean.setUri(feed.getUri()); feedList.add(feedBean); } ok = true; } catch (Exception ex) { ex.printStackTrace(); System.out.println("ERROR: "+ex.getMessage()); } } if (!ok) { System.out.println(); System.out.println("FeedReader reads and prints any RSS/Atom feed type."); System.out.println("The first parameter must be the URL of the feed to read."); System.out.println(); } } } } } /** * This method is invoked via ajax from the front end page in order to read * a new feed into the display. The ajax front end causes a double submit * to this method, so we need to adjust counters such that they will only update * on every other submit. We do this by using the doubleSubmitIndex numbers. */ public void updateFeed(){ if (doubleSubmitIndex > 1){
doubleSubmitIndex = 0;
}
if (doubleSubmitFeedIndex > 1){
doubleSubmitFeedIndex = 0;
}
pageName = RssAppCommonTasks.obtainPageName();
if (!pageName.equals("underMaintenance")){
qry = em.createQuery("select object(p) from RssAppContentPage as p " +
"where p.contentPage = :pageName")
.setParameter("pageName", pageName);
RssAppContentPage page = (RssAppContentPage) qry.getSingleResult();
qry = em.createQuery("select object(f) from RssAppRssFeed as f " +
"where f.contentPageId = :pageId")
.setParameter("pageId", page.getContentPageId());
rssFeedList = qry.getResultList();
/*
* Obtain a list of rss feeds for a particular web page. If feeds
* exist for that page, then enter the feed parse logic.
*/
if (rssFeedList.size() > 0){
feedCounter = rssFeedList.size();
if(this.getFeedIndex() > feedCounter - 1){
this.setFeedIndex(0);
}
boolean ok = false;
int entryIndex = 0;
/*
* Obtain all feed entries for this particular feed index
*/
RssAppRssFeed rssFeed = new RssAppRssFeed();
RssFeed = rssFeedList.get(getFeedIndex());
System.out.println("Feed Index: " + getFeedIndex() + " Entry Index: " + getFeedEntryIndex());
if (rssFeed.getFeedUrl() != null) {
try {
feedList = null;
URL feedUrl = new URL(rssFeed.getFeedUrl());
String feedEntryDateText = null;
String feedEntryText = null;
String feedEntryUrl = null;
SyndFeedInput input = new SyndFeedInput();
SyndFeed feed = input.build(new XmlReader(feedUrl));
/*
* Obtain count of all feed entries
*/
feedEntryCounter = feed.getEntries().size();
initializeList();
if(getFeedEntryIndex() > 0){
if (getFeedEntryIndex() > feedEntryCounter - 1){
setFeedEntryIndex(0);
}
}
System.out.println("Reading...");
feedBean = new Feed();
feedBean.setAuthor(feed.getAuthor());
feedBean.setDescription(feed.getDescription());
feedBean.setEntry(((SyndEntryImpl)feed.getEntries().get(getFeedEntryIndex())).getTitle());
feedBean.setEntryLink(((SyndEntryImpl)feed.getEntries().get(getFeedEntryIndex())).getLink());
feedBean.setEntryUpdatedDate(((SyndEntryImpl)feed.getEntries().get(getFeedEntryIndex())).getPublishedDate());
feedBean.setTitle(feed.getTitle());
setFeedTitle(feed.getTitle());
feedBean.setUri(feed.getUri());
feedList.add(feedBean);
this.feedDate = feedBean.getEntryUpdatedDate();
feedText = "" +
feedBean.getEntry() + "";
ok = true;
if(doubleSubmitIndex > 0) {
this.feedEntryIndex++;
doubleSubmitIndex++;
// If all entries within current feedIndex have been read, move on
// to the next feed and start with entry zero.
if (feedEntryIndex > feedEntryCounter - 1){
this.feedIndex++;
this.feedEntryIndex = 0;
}
} else {
doubleSubmitIndex++;
}
} catch (Exception ex) {
ex.printStackTrace();
System.out.println("ERROR: "+ex.getMessage());
}
}
if (!ok) {
System.out.println();
System.out.println("FeedReader reads and prints any RSS/Atom feed type.");
System.out.println("The first parameter must be the URL of the feed to read.");
System.out.println();
}
}
}
}
private void initializeList(){
if (feedList == null){
feedList = new ArrayList();
}
}
public String getFeedText() {
return feedText;
}
public void setFeedText(String feedText) {
this.feedText = feedText;
}
public String getFeedTitle() {
return feedTitle;
}
public void setFeedTitle(String feedTitle) {
this.feedTitle = feedTitle;
}
public int getFeedIndex() {
return feedIndex;
}
public void setFeedIndex(int feedIndex) {
this.feedIndex = feedIndex;
}
public int getFeedEntryIndex() {
return feedEntryIndex;
}
public void setFeedEntryIndex(int feedEntryIndex) {
this.feedEntryIndex = feedEntryIndex;
}
public Date getFeedDate() {
return feedDate;
}
public void setFeedDate(Date feedDate) {
this.feedDate = feedDate;
}
@Remove @Destroy
public void destroy(){}
}
Local Interface - Nothing exciting in the local interface
/**
* FeedLocal.java
*/
package org.jj.interfaces;
import java.util.Date;
public interface FeedLocal {
void readFeed();
java.lang.String getFeedText();
void setFeedText(String feedText);
void updateFeed();
void destroy();
int getFeedIndex();
void setFeedIndex(int feedIndex);
Date getFeedDate();
void setFeedDate(Date feedDate);
java.lang.String getFeedTitle();
void setFeedTitle(String feedTitle);
}
Utility Class - Here is an excerpt from my utility class. This code obtains the current page name from the FacesContext.
public final class RssAppCommonTasks {
public static String obtainPageName(){
String currentPageName = null;
Query qry = null;
String tempPageName = FacesContext.getCurrentInstance().getViewRoot().getViewId();
if (tempPageName.lastIndexOf("/") > 0) {
tempPageName = tempPageName.substring(tempPageName.lastIndexOf("/") + 1).replace(".seam","").replace(".xhtml","");
currentPageName = tempPageName;
System.out.println("tempPageName: " + currentPageName);
} else {
System.out.println("view id: " + FacesContext.getCurrentInstance().getViewRoot().getViewId());
System.out.println("updated view id: " +
FacesContext.getCurrentInstance().getViewRoot().getViewId().replace("/","").replace(".seam","").replace(".xhtml",""));
currentPageName = FacesContext.getCurrentInstance().getViewRoot().getViewId().replace("/","").replace(".seam","").replace(".xhtml","");
}
return currentPageName;
}
***
}
pages.xml - Each page which contains the RSS component code will require an element within the pages.xml file to invoke server-side code.
<page id="/myPage.xhtml" action="#{rssReader.updateFeed}">
Component code in the XHTML page - I haven't yet created a separate component/tag for this code, but it should work by simply copying and pasting this code in each page which uses the reader. The back end code then determines which page is calling the code and parses the feeds in the database which are tied to that page.
<div id="autoreader">
<a4j:poll interval="10000"
reRender="autoReaderText, autoReaderDate, feedTitle"
action="#{rssReader.updateFeed}">
</a4j:poll>
<p align="center" class="sub_head_sub"><br />
<h:outputText id="feedTitle"
value="#{rssReader.feedTitle}"/>
</p>
<table id="feedList" name="feedList">
<td bgcolor="#CCFFCC" style="width: 100px">
<h:outputText id="autoReaderDate"
value="#{rssReader.feedDate}"/>
</td>
<td bgcolor="#CCFFCC" style="width: 400px">
<h:outputText id="autoReaderText"
escape="false"
value="#{rssReader.feedText}"/>
</td>
</table>
</div>
That is all there is to it. There is a bit of code to write, but the end result is very appealing. Once complete, one can add or remove feeds from the database and have them automatically appear on the desired pages.
Thursday, August 30, 2007
Oracle Database 11g
I'm really excited about the release of Oracle database 11g...even if it is only for Linux at this time. I am almost thinking about setting up a Linux box just to try it out...but perhaps I'll wait for the release of the Windows version.
There are a significant number of new features added to this release. One of the top items that I am interested in is "hot patching". I'm also glad that PL/SQL performance has been improved, and that SQL Tuning can now be fully automated.
Check out this link for a great amount of detail. The latest edition of Oracle magazine also showcases the new release...grab a copy if you do not have one yet.
This looks to be a release that we will definitely want to invest some time into!
There are a significant number of new features added to this release. One of the top items that I am interested in is "hot patching". I'm also glad that PL/SQL performance has been improved, and that SQL Tuning can now be fully automated.
Check out this link for a great amount of detail. The latest edition of Oracle magazine also showcases the new release...grab a copy if you do not have one yet.
This looks to be a release that we will definitely want to invest some time into!
Thursday, July 12, 2007
JBoss Seam Configurations - JARs and Details
I've sucessfully implemented NetBeans 6.0 M10 and Netbeans 5.5.1 projects using the JBOSS Seam framework. I can successfully deploy these projects to both Glassfish V1, JBoss 4.2.0, and JBoss 4.1. This blog post is a log so that I can remember the specific JAR files and details required for each of these projects. I intend to add onto this blog as time goes on and I encounter more detailed information.
Seam 1.2.1 GA and Glassfish V1:
This project utilizes the Ajax4Jsf and RichFaces APIs. I have been unable to make this setup work with Glassfish V2 as yet. If you have figured that one out, please let me know.
Follow these steps in either NB 5.5.1 or NB 6.0 M10
1) Create new Enterprise Application, and also create the following libraries within the IDE:
Seam1.2.1-GlassfishV1
hibernate-all.jar
hibernate-annotations.jar
jboss-common.jar
jboss-seam-debug.jar
jboss-seam-pdf.jar
jboss-seam-ui.jar
jboss-seam.jar
thirdparty-all.jar
jbpm-3.1.2.jar (If you plan to use JBpm...I have not tested as yet)
Ajax4Jsf
ajax4jsf-1.1.1.jar
commons-collections.jar
oscache-2.3.2.jar
richfaces-3.0.1.jar
2) Add those two libraries to your ejb sub-project along with these others:
commons-beanutils-1.7.0.jar
commons-codec-1.3.jar
commons-digester-1.6.jar
jboss-archive-browsing.jar
jsf-facelets.jar (unless you intend to add facelets support via the ide)
3) Add the following JARs to your war sub-project:
dom4j.jar (may not need this one...)
jboss-seam-ui.jar
4) Add configuration files to your ejb sub-project:
a) Add ejb-jar.xml to src/conf
b) Create empty seam.properties within src/conf
c) Create log4j.xml within src/conf
- Easiest configuration is to copy one of the log4j.xml files contained in the
example projects within the Seam 1.2.1 GA download.
d) Create persistence.xml within src/conf
- Use NetBeans to create persistence unit by right-clicking on the ejb sub-project
and then selecting New->Persistence Unit. Follow directions to create a unit
based upon one of the existing database connections you have defined in the IDE.
I use Toplink by default, but Hibernate works just as well.
5) Add configuration files to your war sub-project
a) Configure web.xml and faces-config.xml as suggested in Carol McDonald's Blog or Brian Leonard's Blog. It is also a good idea to take a look at the web.xml file from within one of the sample projects which comes with your Seam download. You will require a Seam filter, and Ajax4Jsf context-parameter if you plan to use that technology. I almost always use the same configuration contained within the sample project web.xml files, but also add the ejb references as discussed in the blog posts above.
b) Make sure the following additional xml files reside within your WEB-INF directory:
components.xml - Copy and use the one from the glassfish example in your Seam download. You will need to update it according to your ejb project name.
c) You may need to add META-INF to root of web pages and place application.xml within it.
I'll add the other configurations as time goes on, but this one will get you started with Seam application development on Glassfish V1.
Friday, July 06, 2007
Seam 2.0 and Netbeans 6.0 M10
Seam 2.0 works with Netbeans 6.0 M10 and the Netbeans Seam plugin. I've spent some time preparing an application based upon some of the examples given in the Seam 2.0 documentation.
I've managed to deploy and successfully run an application on JBoss 4.2.0 using Netbeans 6.0 M10 and the seam plugin. I only used the plug-in to generate the initial application. I did not use any of the other plug-in automation.
I've managed to deploy and successfully run an application on JBoss 4.2.0 using Netbeans 6.0 M10 and the seam plugin. I only used the plug-in to generate the initial application. I did not use any of the other plug-in automation.
Monday, July 02, 2007
Saw It, Got It, Using It
Netbeans 6.0 M10 is now available to the community. There are quite a few enhancements in this milestone.
I'll blog more about the M10 release as needed as time goes on. I've been using it all day with the Netbeans Seam plugin and Facelets plugin...and haven't experienced any issues thus far.
I'll blog more about the M10 release as needed as time goes on. I've been using it all day with the Netbeans Seam plugin and Facelets plugin...and haven't experienced any issues thus far.
Friday, June 29, 2007
JBoss Seam + Netbeans Update 2
The good news is that the Seam plugin for Netbeans deploys without any issues to JBoss 4.0.5 server. I've also added a Postgresql database into the mix and successfully generated entity classes and deployed to 4.0.5 successfully!
The bad news is that I ran into an issue with M9. At least, it is an issue with M9 and the Facelets plugin (on my workstation). I cannot tell if this issue is a bug with M9, or just my slow workstation, but the IDE literally locks up if I try to edit XHTML files with the Facelets plugin installed. I just found this out this morning when trying to add a new Facelets page to my Seam Plugin app. It would not work...I restarted the M9 application several times.
Needless to say, I've reverted to Netbeans 5.5.1 and have been using the Facelets code without issue.
In summary: Netbeans 5.5.1, Seam Framework Plugin, Facelets Plugin, and Postgresql database create an easy CRUD application without issue...and in just a few minutes!
As stated in previous posts, I will try to make a mini-application using this model. I then wish to port it to Glassfish as well just to see how difficult that step will be. It may take me a while...but I will post my results.
The bad news is that I ran into an issue with M9. At least, it is an issue with M9 and the Facelets plugin (on my workstation). I cannot tell if this issue is a bug with M9, or just my slow workstation, but the IDE literally locks up if I try to edit XHTML files with the Facelets plugin installed. I just found this out this morning when trying to add a new Facelets page to my Seam Plugin app. It would not work...I restarted the M9 application several times.
Needless to say, I've reverted to Netbeans 5.5.1 and have been using the Facelets code without issue.
In summary: Netbeans 5.5.1, Seam Framework Plugin, Facelets Plugin, and Postgresql database create an easy CRUD application without issue...and in just a few minutes!
As stated in previous posts, I will try to make a mini-application using this model. I then wish to port it to Glassfish as well just to see how difficult that step will be. It may take me a while...but I will post my results.
Saturday, June 23, 2007
JBoss Seam + Netbeans 6.0 M9 Update
I've not had much time lately to play with Seam and get some good development going. However, I've been trying to make the Seam plugin work with Netbeans 6.0 M9...and it does quite nicely. Follow the link to the blog by Michael Yuanto see how you should set up your environment. This is tested and functional with Netbeans 6.0 M9.
I tried to make this work with JBoss 4.2, but I never quite made it. The issue is that I need to run JBoss on a different port other than the default 8080. I cannot make this happen with JBoss 4.2 within the Netbeans 6.0 M9 environment. When I register the server with Netbeans, it automatically defaults to 8080...I do not like this. I've also tried to change all references to 8080 within the JBoss 4.2 home to something else...no luck. The good thing is that with JBoss 4.0.5, you can simply adjust the server.xml within the server\default\deploy\jbossweb-tomcat55.sar directory. This then registers with Netbeans 6.0 on the specified port without issue.
I am hopeful to hear more about the Netbeans Seam plugin soon...the initial release is very good...
I tried to make this work with JBoss 4.2, but I never quite made it. The issue is that I need to run JBoss on a different port other than the default 8080. I cannot make this happen with JBoss 4.2 within the Netbeans 6.0 M9 environment. When I register the server with Netbeans, it automatically defaults to 8080...I do not like this. I've also tried to change all references to 8080 within the JBoss 4.2 home to something else...no luck. The good thing is that with JBoss 4.0.5, you can simply adjust the server.xml within the server\default\deploy\jbossweb-tomcat55.sar directory. This then registers with Netbeans 6.0 on the specified port without issue.
I am hopeful to hear more about the Netbeans Seam plugin soon...the initial release is very good...
Saturday, June 09, 2007
JBoss SEAM 1.2.1 GA and Glassfish V2
I've just followed the excellent write-up by Roger Kitain and built the glassfish example for Seam on Glassfish v2. If you follow Roger's blog instructions, it works without any issues using Seam 1.2.1 GA.
Now...onto the Netbeans 6.0 M9 integration. I hope to install the Seam plug-in (or minimally the Facelets plug-in) for Netbeans to M9 and deploy to Glassfish...I'll blog on my results.
Now...onto the Netbeans 6.0 M9 integration. I hope to install the Seam plug-in (or minimally the Facelets plug-in) for Netbeans to M9 and deploy to Glassfish...I'll blog on my results.
Friday, June 08, 2007
Netbeans 6.0 - Great Information Resource
I am a little bit behind...but I've just recently read the article in the Netbeans Magazine May 2007 edition regarding Netbeans 6.0. It is an excellent article. If you are looking for a good resource to learn the newest features of the IDE then I definitely recommend giving it a read!
Also, another excellent resource is always Roumen's Weblog. I listen to each of the Netbeans podcasts, and I visit his site often...always has great information regarding Netbeans. He also has some good Flash Demos available.
Check it out Netbeans users!
Also, another excellent resource is always Roumen's Weblog. I listen to each of the Netbeans podcasts, and I visit his site often...always has great information regarding Netbeans. He also has some good Flash Demos available.
Check it out Netbeans users!
Tuesday, May 29, 2007
Good Java Reference
Just wanted to post the link to a good Java reference I ran across today. This may be old, but it is still a good reference while trying to port applications to different platforms. Read How to avoid pitfalls in your Java application development for some quick, yet decent material.
JFXBuilder...I'm Impressed
You've heard of JavaFX, right? Of course you have...unless you have not paid any attention to the Java world in the past couple of months. I'm interested in the upcoming technology and all that it will cover. I've read through a few tutorials and played around a bit and I do like the syntax of the FX scripting language. I was impressed when I checked out java.net this morning and saw that ReportMill has already released a WYSIWYG editor for JavaFX. I took a brief trial run and it looks good so far! Give it a test run at http://www.reportmill.com/jfx/ and you will also be impressed!
Wednesday, May 16, 2007
Two Early Access IDE Releases
Just recently, two of the IDEs which I use on a daily basis have released early preview distributions of future products. No doubt, JavaOne had a lot to do with the timing of these releases. I've used both of the new releases, but I cannot say that I will be using either of them full time as yet.
JDeveloper 11g - Quick Review
The technical preview for JDeveloper 11g was released recently. I decided to download it and take a look at it's capabilities this week. I must admit that I was blown away by the new layout of the IDE altogether. It is well thought out with added search boxes located throughout to assist in finding code. The application menu now displays only one application at a time by default...the other applications are listed in a pull-down menu. The overall look and feel is more visually appealing. I use the database connections features quite often and it is slick. Each database connection now has added options such as access to different types and database links. Another nice feature of the database connection editors is the SQL editor which opens by default when you connect to a database.
However, the JDeveloper 11g technical preview does have some faults. Unfortunately, the faults will limit my exposure to the IDE until the bugs have been repaired. For instance, the database connections expansion tree is way too sensitive. It is hard to select a database package and/or body for editing. By default, when you select a database package or package body then it opens in a read-only mode. You must select a variable, function, or procedure definition in order to edit the package. This is too cumbersome for my liking. I hope that these changes can be made for the next release because I can definitely see the potential in this IDE.
Netbeans 6.0 M9 - Quick Review
The Milestone 9 release of Netbeans 6.0 has an abundance of new features to tout. I have only performed some basic editing and development tasks thus far. Therefore, I do not feel that I can give an informative review of this release. However, with my limited exposure this IDE milestone release is outstanding. I have not run into any bugs thus far. The editor reacts nicely and the new look and feel is great. Built-in profiler is a welcome feature as well.
The only disappointing feature of M9 that I have found so far is that it does not come fully equipped with Tomcat AS. You must download and install Tomcat separately if you wish to use that application server. M9 comes with Glassfish by default (which is nice), but I think many people are still using Tomcat and may not like the removal.
It has been a great month for the Java community! Check out the IDEs when you have a chance because both of them are worthy of a look or two.
http://www.oracle.com/technology/software/products/jdev/index.html
http://www.netbeans.org/community/releases/60/index.html
JDeveloper 11g - Quick Review
The technical preview for JDeveloper 11g was released recently. I decided to download it and take a look at it's capabilities this week. I must admit that I was blown away by the new layout of the IDE altogether. It is well thought out with added search boxes located throughout to assist in finding code. The application menu now displays only one application at a time by default...the other applications are listed in a pull-down menu. The overall look and feel is more visually appealing. I use the database connections features quite often and it is slick. Each database connection now has added options such as access to different types and database links. Another nice feature of the database connection editors is the SQL editor which opens by default when you connect to a database.
However, the JDeveloper 11g technical preview does have some faults. Unfortunately, the faults will limit my exposure to the IDE until the bugs have been repaired. For instance, the database connections expansion tree is way too sensitive. It is hard to select a database package and/or body for editing. By default, when you select a database package or package body then it opens in a read-only mode. You must select a variable, function, or procedure definition in order to edit the package. This is too cumbersome for my liking. I hope that these changes can be made for the next release because I can definitely see the potential in this IDE.
Netbeans 6.0 M9 - Quick Review
The Milestone 9 release of Netbeans 6.0 has an abundance of new features to tout. I have only performed some basic editing and development tasks thus far. Therefore, I do not feel that I can give an informative review of this release. However, with my limited exposure this IDE milestone release is outstanding. I have not run into any bugs thus far. The editor reacts nicely and the new look and feel is great. Built-in profiler is a welcome feature as well.
The only disappointing feature of M9 that I have found so far is that it does not come fully equipped with Tomcat AS. You must download and install Tomcat separately if you wish to use that application server. M9 comes with Glassfish by default (which is nice), but I think many people are still using Tomcat and may not like the removal.
It has been a great month for the Java community! Check out the IDEs when you have a chance because both of them are worthy of a look or two.
http://www.oracle.com/technology/software/products/jdev/index.html
http://www.netbeans.org/community/releases/60/index.html
Tuesday, April 17, 2007
Essential Web Development Tool
I have been doing quite a bit of graphical design within my web development as of late. In previous web development projects, tools such as MS Paint and Open Office were good enough to complete the task. However, at times you may run across a task which cannot be completed with those basic image editing utilities.
I was about to break down and purchase the one and only Adobe Photoshop so that I could perform high-end image editing. Of all that I've heard, Photoshop is the ultimate image editing and graphic design software. That may be true, but have you ever heard of The GIMP, an open-source image manipulation program? If not, you may want to give it a spin.
I am able to complete every task imaginable with The GIMP, including image editing, text formatting, and even animation. Some of the tasks take a bit of work to complete, but there are a slew of online tutorials to help you along the way.
If you are in the need of an image manipulator, GIF creator, or just a cool imaging utility, give The GIMP a try.
I was about to break down and purchase the one and only Adobe Photoshop so that I could perform high-end image editing. Of all that I've heard, Photoshop is the ultimate image editing and graphic design software. That may be true, but have you ever heard of The GIMP, an open-source image manipulation program? If not, you may want to give it a spin.
I am able to complete every task imaginable with The GIMP, including image editing, text formatting, and even animation. Some of the tasks take a bit of work to complete, but there are a slew of online tutorials to help you along the way.
If you are in the need of an image manipulator, GIF creator, or just a cool imaging utility, give The GIMP a try.
Tuesday, April 10, 2007
Help Wanted: New Jython Monthly Editor
I have sent my last distribution of the Jython Monthly newsletter this morning. The choice to resign as editor of the newsletter comes about as a result of many changes which will impact my availability. I already do not have time to spend with the newsletter, and the April Newsletter shows it. I have not found the time to author articles for the newsletter as of late, and it has become increasingly difficult to find material for the distribution.
I'd like for someone to take over as editor of the newsletter as it is a great way to help increase the online Jython library and overall awareness of the language. If anyone is interested in taking over, please feel free to leave me a comment and let me know.
I'd like for someone to take over as editor of the newsletter as it is a great way to help increase the online Jython library and overall awareness of the language. If anyone is interested in taking over, please feel free to leave me a comment and let me know.
Tuesday, March 27, 2007
JPC
Check out the attached link...the JPC project offers computer virtualization in Java. Although I have only briefly reviewed the project, it looks to be very interesting and useful. Have a look...
Thursday, March 08, 2007
Just a Quick Note on FireBug
I have to blog about FireBug...the web development FireFox add-on. This tool is excellent, and it has helped me to find my javascripting bugs in a minimal amount of time. No more guessing which javascript line caused the bug, or using alert messages to find errors...Firebug allows one to traverse the javsscript while it is executing. This debugger is very similar to most IDE debuggers, and you can use it on any web page!
Love FireBug...if you have not tried it then I suggest downloading it now!
Love FireBug...if you have not tried it then I suggest downloading it now!
Jython Monthly Articles Needed
I am the editor and distributor of the Jython Monthly newsletter. Part of the monthly routine for ensuring an effective distribution is to obtain articles and blogs which are worth reading. I hate to throw together a newsletter full of garbage and waste the expensive time of the readers.
One of the reasons I started the Jython Monthly newsletter was to begin generating a more complete article library for Jython. I had hoped to obtain at least one or two articles per month for distribution with the newsletter. This worked well for a while, but we seem to have fallen into a slump as of late. Since the new year has begun, I've received very few articles for distribution with the newsletter. Therefore, I hope to see another spark in the community for generating useful Jython resources. We need more Jython articles!
If anyone has an article that they would like to contribute for this month or any coming month, please visit Jython Monthly Articles to get started. Anyone can contribute, so feel free to post any and all Jython related content.
Thanks for the help, and I look forward to reading your Jython Monthly article in the near future!
One of the reasons I started the Jython Monthly newsletter was to begin generating a more complete article library for Jython. I had hoped to obtain at least one or two articles per month for distribution with the newsletter. This worked well for a while, but we seem to have fallen into a slump as of late. Since the new year has begun, I've received very few articles for distribution with the newsletter. Therefore, I hope to see another spark in the community for generating useful Jython resources. We need more Jython articles!
If anyone has an article that they would like to contribute for this month or any coming month, please visit Jython Monthly Articles to get started. Anyone can contribute, so feel free to post any and all Jython related content.
Thanks for the help, and I look forward to reading your Jython Monthly article in the near future!
Friday, March 02, 2007
Old Buggy Details
I was reviewing an issue involving a record modification form within a PL/SQL web application yesterday. This modification form is basic...it displays the data which already exists within a database record and allows an end-user to modify that data within different text fields on the form.
The issue was that some of these text fields were not updating as expected. After some initial review, I saw that the records having this issue had been submitted without any data in the fields that were not updating. Furthermore, I checked the database and all varchar2 fields which were not updating as expected had NULL values within them. Ahh...the old NULL value comparison issue!!!
As it turns out, upon submitting a modified record, the PL/SQL application checks each field within the database to see if it's contents match the previously submitted data. If not, then the field and new content are added to the update statement so that the resulting modifications are submitted successfully. However, the comparison being used was not allowing for NULL values to be compared. The result was a false positive result which was prohibiting the data to be updated.
For example, the data is compared such as:
if cursor_rec.old_value != incoming_new_value then
update_text := update_text || ' my_field = ''' || upper(incoming_new_value)
|| ''';
end if;
The issue is that the above IF statement is never true if the varchar2 value contained within the incoming_new_value variable is NULL. You must always compare a varchar2 against a non-null value for obtaining a valid result in such cases. Therefore, the use of the Oracle nvl function comes into play.
The updated code which repairs the issue simply replaces a NULL value with a character so that comparisons will function as expected.
if cursor_rec.old_value != nvl(incoming_new_value, '*') then
update_text := update_text || ' my_field = ''' || upper(incoming_new_value)
|| ''';
end if;
An oldie but goodie to remember!!!
The issue was that some of these text fields were not updating as expected. After some initial review, I saw that the records having this issue had been submitted without any data in the fields that were not updating. Furthermore, I checked the database and all varchar2 fields which were not updating as expected had NULL values within them. Ahh...the old NULL value comparison issue!!!
As it turns out, upon submitting a modified record, the PL/SQL application checks each field within the database to see if it's contents match the previously submitted data. If not, then the field and new content are added to the update statement so that the resulting modifications are submitted successfully. However, the comparison being used was not allowing for NULL values to be compared. The result was a false positive result which was prohibiting the data to be updated.
For example, the data is compared such as:
if cursor_rec.old_value != incoming_new_value then
update_text := update_text || ' my_field = ''' || upper(incoming_new_value)
|| ''';
end if;
The issue is that the above IF statement is never true if the varchar2 value contained within the incoming_new_value variable is NULL. You must always compare a varchar2 against a non-null value for obtaining a valid result in such cases. Therefore, the use of the Oracle nvl function comes into play.
The updated code which repairs the issue simply replaces a NULL value with a character so that comparisons will function as expected.
if cursor_rec.old_value != nvl(incoming_new_value, '*') then
update_text := update_text || ' my_field = ''' || upper(incoming_new_value)
|| ''';
end if;
An oldie but goodie to remember!!!
Monday, February 26, 2007
Oracle ADF Faces
I've just read a great blog promoting the Oracle ADF Faces framework. I am an advocate of ADF Faces and I've used it in many of the applications which I have written. The open-sourced Gather! reunion application uses a version of ADF Faces which Oracle has open-sourced to Apache.
If you are a JSF developer and you have not yet worked with the framework, give it a chance and see how great it can be. I have found that the framework can save lots of time and it helps to create a professional layout.
If you are a JSF developer and you have not yet worked with the framework, give it a chance and see how great it can be. I have found that the framework can save lots of time and it helps to create a professional layout.
Wednesday, February 21, 2007
Another Fine JSF Component Library
I was performing my daily visual scrubbing of the java.net website this morning and I found a blurb about a new JSF component library called Woodstock. I briefly visited the project homepage and tested a few of the components. It looks as though this library could be a promising addition to the list of component libraries available for the JSF framework. While some of the basic components such as buttons and labels do not seem too different from stuff we've seen before, the Woodstock library has "Alert" and "Image and Masthead" components which may be very useful.
Check out the Woodstock JSF component library project page for more details, or go directly to the component preview to check out the features.
Check out the Woodstock JSF component library project page for more details, or go directly to the component preview to check out the features.
Tuesday, February 20, 2007
Best Jython/Python Podcasts
I am curious as to if anyone has any good links for podcasts relating to Jython or Python. I currently listen to Python 411 on a frequent basis, but I'd like to find out if there are any more very good podcasts for these subjects.
If you know of any other good Jython or Python podcasts, please leave me a comment!
Thanks
If you know of any other good Jython or Python podcasts, please leave me a comment!
Thanks
Thursday, February 15, 2007
Easy to Use Javascript Charting
I am currently working on a PL/SQL application which requires some simple charting. I have a defined set of trend data for which I must created a line chart...thus, displaying the trend for the data. I Googled javascript charting and found this javascript library. I cannot perform a complete review of the library because I have only used the line charting thus far, but I can tell you that the library is easy to use, flexible, and works great.
Using this library, it is possible to create one or many different charts on a web page. You can define static sets of data (does anyone do this anymore?) or use your database. I have found the line charting simple...especially with PL/SQL. The advantage of using PL/SQL to perform dynamic javascripting tasks is that your data is easily accessible.
I'll wrap up this blog with a quick example of line charting using PL/SQL and the JSGraph javascript library. If you have the need for a dynamic charting solution in your application, give JSGraph a look.
The following is an example of line charting in PL/SQL. In my particular case, I've defined a package which contains many different procedures. I recommmend using the PL/SQL Web Toolkit to define PL/SQL web applications. This is an exerpt from the procedure within my PL/SQL web package which defines my line chart:
(Please ignore the "-" within the tags...this blogger does not print tags well)
procedure GRAPH_TREND (in_trend_id number) is
cursor trend_cur is
select *
from my_trend_data
where trend_id = in_trend_id;
... more definitions ...
begin
... PL/SQL Code ...
-- Define Chart (Static data for this example)
htp.htmlopen;
htp.headopen;
htp.p('<-script language="JavaScript1.2" src="jsgraph.js"><-/script>
<-script language="JavaScript1.2">
var graph = new JSGraph();
graph.graphLeftPaddingOverride = 30;
graph.yAxis(4, 200);
graph.xAxis(4, 300);
graph.addBackground('#FFF8DC');
graph.addTrellis(40, 1, '#FF0000', 'blah1','tahoma,sans-serif',9);
graph.addTrellis(80, 1, '#FF0000', 'blah2','tahoma,sans-serif',9);
graph.addTrellis(120, 1, '#FF0000', 'blah3','tahoma,sans-serif',9);
graph.addTrellis(160, 1, '#FF0000', 'blah4','tahoma,sans-serif',9);
graph.addTrellis(200, 1, '#FF0000', 'blah5','tahoma,sans-serif',9);
graph.addLinePlot(0);
graph.addLinePlot(30,1,'maroon',1,'Foo 1','tahoma,sans-serif','maroon',9);
graph.addLinePlot(50,1,'maroon',1,'Foo 2','tahoma,sans-serif','black',9);
graph.addLinePlot(178,1,'maroon',1,'Foo 3','tahoma,sans-serif','maroon',9);
graph.addLinePlot(200,1,'maroon',1,'Foo 4','tahoma,sans-serif','black',9);
graph.addLinePlot(36,1,'maroon',1,'Foo 5','tahoma,sans-serif','maroon',9);
graph.addLinePlot(0,1,'maroon',1,'Foo 6','tahoma,sans-serif','black',9);
graph.addLinePlot(146,1,'maroon',1,'Foo 7','tahoma,sans-serif','maroon',9);
graph.addLinePlot(12,1,'maroon',1,'Foo 8','tahoma,sans-serif','black',9);
graph.addLinePlot(191,1,'maroon',1,'Foo 9','tahoma,sans-serif','maroon',9); <-/script>
');
htp.headclose;
htp.bodyopen;
htp.p('
<-div id="lineplotGraph1" style="PADDING-RIGHT: 0px; PADDING-LEFT: 0px; LEFT: 50px; PADDING-BOTTOM: 0px; MARGIN: 0px; PADDING-TOP: 0px; POSITION: absolute; TOP: 50px">
<-script language="JavaScript">
graph.makeGraph();
<-/script>
<-/div>
');
htp.bodyclose;
htp.htmlclose;
...
end GRAPH_TREND;
Using this library, it is possible to create one or many different charts on a web page. You can define static sets of data (does anyone do this anymore?) or use your database. I have found the line charting simple...especially with PL/SQL. The advantage of using PL/SQL to perform dynamic javascripting tasks is that your data is easily accessible.
I'll wrap up this blog with a quick example of line charting using PL/SQL and the JSGraph javascript library. If you have the need for a dynamic charting solution in your application, give JSGraph a look.
The following is an example of line charting in PL/SQL. In my particular case, I've defined a package which contains many different procedures. I recommmend using the PL/SQL Web Toolkit to define PL/SQL web applications. This is an exerpt from the procedure within my PL/SQL web package which defines my line chart:
(Please ignore the "-" within the tags...this blogger does not print tags well)
procedure GRAPH_TREND (in_trend_id number) is
cursor trend_cur is
select *
from my_trend_data
where trend_id = in_trend_id;
... more definitions ...
begin
... PL/SQL Code ...
-- Define Chart (Static data for this example)
htp.htmlopen;
htp.headopen;
htp.p('<-script language="JavaScript1.2" src="jsgraph.js"><-/script>
<-script language="JavaScript1.2">
var graph = new JSGraph();
graph.graphLeftPaddingOverride = 30;
graph.yAxis(4, 200);
graph.xAxis(4, 300);
graph.addBackground('#FFF8DC');
graph.addTrellis(40, 1, '#FF0000', 'blah1','tahoma,sans-serif',9);
graph.addTrellis(80, 1, '#FF0000', 'blah2','tahoma,sans-serif',9);
graph.addTrellis(120, 1, '#FF0000', 'blah3','tahoma,sans-serif',9);
graph.addTrellis(160, 1, '#FF0000', 'blah4','tahoma,sans-serif',9);
graph.addTrellis(200, 1, '#FF0000', 'blah5','tahoma,sans-serif',9);
graph.addLinePlot(0);
graph.addLinePlot(30,1,'maroon',1,'Foo 1','tahoma,sans-serif','maroon',9);
graph.addLinePlot(50,1,'maroon',1,'Foo 2','tahoma,sans-serif','black',9);
graph.addLinePlot(178,1,'maroon',1,'Foo 3','tahoma,sans-serif','maroon',9);
graph.addLinePlot(200,1,'maroon',1,'Foo 4','tahoma,sans-serif','black',9);
graph.addLinePlot(36,1,'maroon',1,'Foo 5','tahoma,sans-serif','maroon',9);
graph.addLinePlot(0,1,'maroon',1,'Foo 6','tahoma,sans-serif','black',9);
graph.addLinePlot(146,1,'maroon',1,'Foo 7','tahoma,sans-serif','maroon',9);
graph.addLinePlot(12,1,'maroon',1,'Foo 8','tahoma,sans-serif','black',9);
graph.addLinePlot(191,1,'maroon',1,'Foo 9','tahoma,sans-serif','maroon',9); <-/script>
');
htp.headclose;
htp.bodyopen;
htp.p('
<-div id="lineplotGraph1" style="PADDING-RIGHT: 0px; PADDING-LEFT: 0px; LEFT: 50px; PADDING-BOTTOM: 0px; MARGIN: 0px; PADDING-TOP: 0px; POSITION: absolute; TOP: 50px">
<-script language="JavaScript">
graph.makeGraph();
<-/script>
<-/div>
');
htp.bodyclose;
htp.htmlclose;
...
end GRAPH_TREND;
Friday, February 09, 2007
Jython 2.2 - Beta 1 - Part II
I have just finished installing Jython 2.2 beta1 without any issues. The installer is clean and easy to use. I am currently using Java SE 6 and this new Jython release had no problems installing.
I've only begun to test a few scripts out, but no issues thus far.
Thanks again to the Jython developers...it is great to see a new release!
I've only begun to test a few scripts out, but no issues thus far.
Thanks again to the Jython developers...it is great to see a new release!
Jython 2.2 Beta 1 Released
Wednesday, February 07, 2007
Snippets
Check out the new site from DZone which will be a repository for source code snippets. You can search the repository for existing code to use in your projects, or you can contribute some code which may be of use to others.
This is a great idea!
This is a great idea!
A Long Time Away
I have not posted for a while and I want to get back into the swing of things. My free time has been spent on side projects and I have not had much time to focus on new technologies as of late.
One technology I really want to focus more on is the Seam framework by JBoss. Seam takes the JSF framework and EJB 3 technology to a new level. It seems to ease development in this area while creating a more functional application development experience. I've only begun to look into the framework, but look for future blogs on this topic.
I'd also like to blog more on Jython. I have not had much time to spend with Jython as of late, but I'm still keeping up with the language. I will be distributing the February issue of Jython Monthly on 2/12, so keep an eye out for that.
Looking forward to a new year of great blogs...
One technology I really want to focus more on is the Seam framework by JBoss. Seam takes the JSF framework and EJB 3 technology to a new level. It seems to ease development in this area while creating a more functional application development experience. I've only begun to look into the framework, but look for future blogs on this topic.
I'd also like to blog more on Jython. I have not had much time to spend with Jython as of late, but I'm still keeping up with the language. I will be distributing the February issue of Jython Monthly on 2/12, so keep an eye out for that.
Looking forward to a new year of great blogs...
Monday, December 04, 2006
Gearing Up for Production 1.0
The Gather! project is gearing up for it's first production release. The project is pretty solid at this point, but it is lacking in documentation. I will be spending the better part of the next couple weeks on documenting the project so that we can attract new users.
I urge all who are interested in last chance beta testing for Gather! reunion organizational software to go ahead and download RC1 as soon as possible.
Thanks to all who have given feedback...it is appreciated!
I urge all who are interested in last chance beta testing for Gather! reunion organizational software to go ahead and download RC1 as soon as possible.
Thanks to all who have given feedback...it is appreciated!
Thursday, November 09, 2006
Trinidad and Facelets
I am beginning to work with the Apache Trinidad API and Facelets. Thus far, I've been using Netbeans 5.5 for my development since there is now a Facelets plugin available for the IDE. The new plug in allows for Facelets projects to be produced in an easy fashion. If you have ever used Netbeans 5.5 and created a JavaServer Faces project, it is very similar.
At first glance, it appears that my favorite thing about Facelets is going to be the templating feature. This technology offers a new way to create templating within a JSF application so that all pages can have a similar layout. I also have read (but not yet tried) about templating within templating...this allows for one to create a header template, for example, and use it within a page layout template. What would that buy you? It allows for one to create various different headers using the header template and apply them to the main layout template. Take a look at this link for more details! So all in all...Facelets looks promising for templating and probably lots more once I get into it.
The Apache Trinidad project is an open-sourced API for web applications...it used to be owned by Oracle and known as ADF faces. The Trinidad project contains some of the most advanced JSF components available, and I think it is great that Oracle has donated the project to Apache. It integrates seamlessly with MyFaces to allow one the ability for easy creation of JSF applications with a great selection of advanced components and page layouts. Please check the wiki for more information. I will blog more about this great project once I've sunk my teeth into it a bit farther. So far, I can tell you that the configuration with Facelets is fairly simple...there are a few steps but it is not too bad. Netbeans 5.5 appears to function great for this application model since you now have the ability to use the new Facelets plugin. If you are interested in using the original Oracle ADF Faces components within a WYSIWYG environment, JDeveloper offers excellent tools. I have not yet attempted to use Trinidad within JDeveloper, but I will do so once I've gotten it to function as expected within Netbeans 5.5.
At first glance, it appears that my favorite thing about Facelets is going to be the templating feature. This technology offers a new way to create templating within a JSF application so that all pages can have a similar layout. I also have read (but not yet tried) about templating within templating...this allows for one to create a header template, for example, and use it within a page layout template. What would that buy you? It allows for one to create various different headers using the header template and apply them to the main layout template. Take a look at this link for more details! So all in all...Facelets looks promising for templating and probably lots more once I get into it.
The Apache Trinidad project is an open-sourced API for web applications...it used to be owned by Oracle and known as ADF faces. The Trinidad project contains some of the most advanced JSF components available, and I think it is great that Oracle has donated the project to Apache. It integrates seamlessly with MyFaces to allow one the ability for easy creation of JSF applications with a great selection of advanced components and page layouts. Please check the wiki for more information. I will blog more about this great project once I've sunk my teeth into it a bit farther. So far, I can tell you that the configuration with Facelets is fairly simple...there are a few steps but it is not too bad. Netbeans 5.5 appears to function great for this application model since you now have the ability to use the new Facelets plugin. If you are interested in using the original Oracle ADF Faces components within a WYSIWYG environment, JDeveloper offers excellent tools. I have not yet attempted to use Trinidad within JDeveloper, but I will do so once I've gotten it to function as expected within Netbeans 5.5.
Tuesday, October 17, 2006
Duplicating Oracle DB
I have recently begun using the RMAN utility for backing up all of my organization's Oracle 10g databases. Previously, I've used manual OS commands and database hot backup procedures to perform the same tasks. RMAN is definitely much easier, and it brings many benefits to the table as well. While I am "old school" and still use my legacy backups in lieu of the RMAN backups (standard DBA best practices...or just paranoid), I think that if you are administering an Oracle database and not using RMAN then you are missing out.
My organization has many different databases. One in particular is used for hosting our maintenance management data. We have three instances of this database...production, development, and integration. The users are allowed to "beat up" the development instance and we can try out different features in this instance as well. Integration is a mirror of production, but we use it to apply patches and test prior to roll out on our production database. Obviously we all know what production is, so there is no need to describe that database.
Since I've begun to use RMAN, one of the best new features is the DUPLICATE database feature. This allows me to clone my production database in a matter of minutes. Previously, I had to create a database and then import a recent dump from my production database in order to acheive the same result. Now I just create the duplicate database instance, and then use RMAN to actually duplicate the datafiles, control files, and redo logs for me. It creates an exact replica (different SID and data locations of course) which allows me to easily recreate my integration instance.
Take a look at the bottom of this document for the procedures to follow in order to successfully DUPLICATE your organization's databases. It is worth the read....
My organization has many different databases. One in particular is used for hosting our maintenance management data. We have three instances of this database...production, development, and integration. The users are allowed to "beat up" the development instance and we can try out different features in this instance as well. Integration is a mirror of production, but we use it to apply patches and test prior to roll out on our production database. Obviously we all know what production is, so there is no need to describe that database.
Since I've begun to use RMAN, one of the best new features is the DUPLICATE database feature. This allows me to clone my production database in a matter of minutes. Previously, I had to create a database and then import a recent dump from my production database in order to acheive the same result. Now I just create the duplicate database instance, and then use RMAN to actually duplicate the datafiles, control files, and redo logs for me. It creates an exact replica (different SID and data locations of course) which allows me to easily recreate my integration instance.
Take a look at the bottom of this document for the procedures to follow in order to successfully DUPLICATE your organization's databases. It is worth the read....
Monday, October 09, 2006
Using Jython in Java Without Jythonc
Over the past two months, there have been a few good articles written on the concept of using Jython within Java apps without utilizing the jythonc utility. This is, in fact, the best way to invoke Jython code within a Java app.
Read more about using this technique in these articles written for the Jython Monthly newsletter.
Accessing Jython from Java Without Using Jythonc
Simple and Efficient Jython Object Factories
Read more about using this technique in these articles written for the Jython Monthly newsletter.
Accessing Jython from Java Without Using Jythonc
Simple and Efficient Jython Object Factories
Tuesday, October 03, 2006
Netbeans Gets Better...
I've just watched a great flash demo given by Roumen Strobl which shows an upcoming addition for the Netbeans IDE. This upcoming feature is known as the Visual Web Pack and it essentially allows for drag-and-drop creation of JSF applications.
Take a look at his blog and see how sweet it looks!
If you combine this new feature along with the new Hibernate Tools Suite and Facelets Support, Netbeans 5.5 (and beyond) makes for a powerful addition to the world of great IDEs.
Take a look at his blog and see how sweet it looks!
If you combine this new feature along with the new Hibernate Tools Suite and Facelets Support, Netbeans 5.5 (and beyond) makes for a powerful addition to the world of great IDEs.
Friday, September 29, 2006
Time to Try Facelets
Netbeans has a new Facelets Support add-on. It is time to start learning about this great framework! It sounds like Facelets may be the key to integrating JSF and JSP, and it allows for excellent templating.
Check out facelets at : https://facelets.dev.java.net/
Check out facelets at : https://facelets.dev.java.net/
Tuesday, September 05, 2006
TNS Security
I recently went through a semi-audit where the main focal point was TNS listener security. Although the TNS listener is more secure in Oracle 10g than in previous releases, it is still a good idea to implement some security measures to protect your database. Here are a few of the steps which I have taken to secure my TNS listeners:
1. Password Protect - This one is a given. You should always protect the listener with a password
2. Listener.ora logging - I set logging on the listener so that each attempted connection is logged. This is a good way to see who is trying to access your database. The only issue which may arise with the logging feature is that the log file will continue to grow in size. You must create a job or manually create a new listener log at some point, or your log file will become too large. Creating an automated job to complete log switching is easy, but you must remember that you'll need to stop the listener before you can alter the log file. On a Windows server, you can use a batch script similar to the following (the ping command just pauses the script momentarily...this gives the listener service a chance to stop):
change_log.bat>>
lsnrctl stop
ping -n 11 localhost
echo Change log...
set yymmdd=%date:~12.2%%date:~4.2%%date:~7.2
ren <>\listener.log listener-%yymmdd%.log
lsnrctl start
lsnrctl reload
The above script simply renames your log file and when the listener is restarted, it will create a new log file. You may also wish to copy the archived log file to a new location to free up some space in the TNS log directory.
3. Use the ADMIN_RESTRICTIONS_listener-name=ON listener.ora parameter. This will disable any remote LSNRCTL access.
Hopefully via the usage of these security settings coupled with the server security, the Oracle database TNS listener should be secure.
If anyone has another means of protecting the TNS listener which should be used by default, please let me know. I am always looking for better ways to secure Oracle.
1. Password Protect - This one is a given. You should always protect the listener with a password
2. Listener.ora logging - I set logging on the listener so that each attempted connection is logged. This is a good way to see who is trying to access your database. The only issue which may arise with the logging feature is that the log file will continue to grow in size. You must create a job or manually create a new listener log at some point, or your log file will become too large. Creating an automated job to complete log switching is easy, but you must remember that you'll need to stop the listener before you can alter the log file. On a Windows server, you can use a batch script similar to the following (the ping command just pauses the script momentarily...this gives the listener service a chance to stop):
change_log.bat>>
lsnrctl stop
ping -n 11 localhost
echo Change log...
set yymmdd=%date:~12.2%%date:~4.2%%date:~7.2
ren <
lsnrctl start
lsnrctl reload
The above script simply renames your log file and when the listener is restarted, it will create a new log file. You may also wish to copy the archived log file to a new location to free up some space in the TNS log directory.
3. Use the ADMIN_RESTRICTIONS_listener-name=ON listener.ora parameter. This will disable any remote LSNRCTL access.
Hopefully via the usage of these security settings coupled with the server security, the Oracle database TNS listener should be secure.
If anyone has another means of protecting the TNS listener which should be used by default, please let me know. I am always looking for better ways to secure Oracle.
Tuesday, August 29, 2006
Gather Beta-1 Released
It is a little behind, but the Gather Beta-1 release is now available for download. This beta version includes a fully funcitonal Gather reunion application as well as an administrative console (GatherAdmin) which is used for maintaining the application. The beta-1 release is installable via an MS-DOS/Jython installer, and it is easily configurable.
The intent of the Gather open-source reunion application is to provide a class or organization a means of hosting web content related to a reunion event of any type. The reunion site allows for individuals to register as members, update their account, become a reunion committee member, assist in finding others via outreach submission, and much more. This application makes it possible to completely organize any reunion event with ease.
Give it a try...it is free. If you are interested in developing the Gather project, please contact one of the project administrators. For more information, please visit Gather!
The intent of the Gather open-source reunion application is to provide a class or organization a means of hosting web content related to a reunion event of any type. The reunion site allows for individuals to register as members, update their account, become a reunion committee member, assist in finding others via outreach submission, and much more. This application makes it possible to completely organize any reunion event with ease.
Give it a try...it is free. If you are interested in developing the Gather project, please contact one of the project administrators. For more information, please visit Gather!
Tuesday, August 15, 2006
Gather...Free for All!
We've decided to open-source the complete Gather! reunion package. The complete package includes two robust JSF-based applications which allow one to plan and organize any type of reunion event with ease. One of the applications is the actual Gather! reunion site which all members can view and use...the second application is an Administrative console which allows selected members to completely control the reunion site. Gather! promises to be the most complete reunion planning software available today...and it is 100% free!
The BETA-1 release is scheduled for late this week. We plan to release a fully functional Gather! site for BETA-1...minus a few of the newer features. Please visit the site for more details!
The BETA-1 release is scheduled for late this week. We plan to release a fully functional Gather! site for BETA-1...minus a few of the newer features. Please visit the site for more details!
Friday, August 04, 2006
Gather - Temporary Site In Place
The temporary web site for the open source Gather! project is online. I've also added another administrator to the project. He is my former high school classmate, and he helped me develop Gather! for our 10 year reunion a few years back. I am glad to have Nathan Nickels on board with the development team.
He will be assisting me with web design for the Gather! site.
Beta-1 is soon to be released...visit the site to find out more!
He will be assisting me with web design for the Gather! site.
Beta-1 is soon to be released...visit the site to find out more!
Monday, July 31, 2006
Gather
I've decided upon making the ReunionWare software open source. The name of the project has changed to Gather, and it will be available for download within the next couple of weeks.
The software aspires to be an open source reunion planning software which will ease the effort of planning a reunion event. The software is comprised of a 100% customizable web application which includes a news page, member registration and account updates, and a member forum post. The software is open source and it will no doubt solve the reunion planning requirements of many.
As a matter of fact, I originally developed Gather for my high school class reunion and it worked great! Stay tuned to http://sourceforge.net/projects/gather for further updates.
The software aspires to be an open source reunion planning software which will ease the effort of planning a reunion event. The software is comprised of a 100% customizable web application which includes a news page, member registration and account updates, and a member forum post. The software is open source and it will no doubt solve the reunion planning requirements of many.
As a matter of fact, I originally developed Gather for my high school class reunion and it worked great! Stay tuned to http://sourceforge.net/projects/gather for further updates.
Wednesday, July 05, 2006
Post an Article for Jython Monthly
We need more articles for Jython Monthly - July 2006! If you've got any good content, please feel free to post an article. Great articles are appreciated!
http://wiki.python.org/jython/JythonMonthly/Articles/July2006
http://wiki.python.org/jython/JythonMonthly/Articles/July2006
Monday, June 26, 2006
Still Using JDBC?
Still using JDBC? I am...I still like the power of using JDBC. I do like the new EJB 3.0 ease of use with both Netbeans and JDeveloper, but I still revert back to JDBC on my older applications. There are several new features in JDBC 3.0 which is part of Java EE 5.0. Check out this article for a look at the WebRowSet.
Sunday, June 18, 2006
JSF Managed Bean Binding
When coding any significant JSF application, it is always useful to have access to managed bean values from any other managed bean. This is almost a trivial procedure, but I often forget how to implement the code (after I haven't done it for a while) and end up looking in previous programs. Here is a good quick refrence for solving these issues:
JSF Managed Bean FAQ
JSF Managed Bean FAQ
Saturday, June 17, 2006
Log4J Bug
I painfully found a bug within Log4J while working on a project. It appears that intermittantly, the following error will be thrown while using version 1.2.13:
NullPointerException at org.apache.log4j.NDC.get(NDC.java:209)
There is no work around. The best bet (and my choice of action) is to download and use the repaired version 1.3-alpha 8...even though it is still in test mode.
NullPointerException at org.apache.log4j.NDC.get(NDC.java:209)
There is no work around. The best bet (and my choice of action) is to download and use the repaired version 1.3-alpha 8...even though it is still in test mode.
Saturday, June 10, 2006
Monday, June 05, 2006
Jython Update

I'm a huge fan of the Jython scripting language. In case you've never heard of this excellent language, it is basically Python on the JVM. Well...it is almost Python on the JVM. At this point, Jython is a few steps behind the current Python release in terms of functionality. There are also some issues which are currently under review regarding translation of some Python constructs into the Java platform. I am currently trying to juggle my time between many things (aren't we all), and one of the things I am doing is taking a look at the Jython Bug Listing and trying to find some bugs which I can repair. If you enjoy Python then you should definitely try Jython...and if you are interested in becomming part of the Jython project, submit a bug fix. Here is a listing of the current bugs in Jython.
Wednesday, May 31, 2006
FACE Some New Changes
Ran into a new CSS concept called FACE in the latest edition of the Informit Newsletter. It looks promising for creating animated effects on websites with no Javascript.
Have a look: http://www.informit.com/guides/content.asp?g=webdesign&seqNum=259
Have a look: http://www.informit.com/guides/content.asp?g=webdesign&seqNum=259
Saturday, May 20, 2006
PL/SQL and Faces
I really enjoy coding web applications with PL/SQL. It is straight forward and easy to do. However, sometimes the PL/SQL applications do not seem as easily managed as some of the JavaServer Faces applications which I have written.
Usually I follow the same technique when it comes to coding a PL/SQL web application. I use the PL/SQL Web Toolkit to do most of the front end work. I usually try to keep the code simple, and if possible, I try to keep each application contained within it's own package. Sometimes one package per application does not happen because of code sizing and code reuse from some other "common" code package.
One thing I do not like about PL/SQL apps is that the view and the business logic are almost never separated. There really is no MVC (Model View Controller) structure to coding a PL/SQL web application. Navigation between pages usually involves passing parameters between different PL/SQL procedures to perform different tasks and output the result. Sometimes this gets annoying (similar to that of coding with JSP) because keeping track of parameters can be a pain if you have lots to deal with. All in all, typical PL/SQL web appplications are easy to code, but they are riddled with intertwined PL/SQL code and HTP web toolkit "tags". This leads to code which is difficult to maintain. Especially if you do not look at the code for 6 months and then try to come back and determine what you did in the first place. It can be done...but it takes time to review your work and come up to speed with the tact you took when you wrote the application.
I do not think PL/SQL web applications need to be this way. They should be easier to code and they should follow an MVC structure to keep the view separated from the business logic in different packages. JavaServer Faces is an excellent Java EE coding framework. I'd argue that it could possibly be the most advanced web framework available today. I think PL/SQL needs a framework which is similar.
Why not use objects to pass data in PL/SQL apps instead of passing parameters between procedures? Why can't we code PL/SQL components like those in the JSF API? I propose that we create a framework similar to JSF for PL/SQL.
Usually I follow the same technique when it comes to coding a PL/SQL web application. I use the PL/SQL Web Toolkit to do most of the front end work. I usually try to keep the code simple, and if possible, I try to keep each application contained within it's own package. Sometimes one package per application does not happen because of code sizing and code reuse from some other "common" code package.
One thing I do not like about PL/SQL apps is that the view and the business logic are almost never separated. There really is no MVC (Model View Controller) structure to coding a PL/SQL web application. Navigation between pages usually involves passing parameters between different PL/SQL procedures to perform different tasks and output the result. Sometimes this gets annoying (similar to that of coding with JSP) because keeping track of parameters can be a pain if you have lots to deal with. All in all, typical PL/SQL web appplications are easy to code, but they are riddled with intertwined PL/SQL code and HTP web toolkit "tags". This leads to code which is difficult to maintain. Especially if you do not look at the code for 6 months and then try to come back and determine what you did in the first place. It can be done...but it takes time to review your work and come up to speed with the tact you took when you wrote the application.
I do not think PL/SQL web applications need to be this way. They should be easier to code and they should follow an MVC structure to keep the view separated from the business logic in different packages. JavaServer Faces is an excellent Java EE coding framework. I'd argue that it could possibly be the most advanced web framework available today. I think PL/SQL needs a framework which is similar.
Why not use objects to pass data in PL/SQL apps instead of passing parameters between procedures? Why can't we code PL/SQL components like those in the JSF API? I propose that we create a framework similar to JSF for PL/SQL.
Wednesday, May 17, 2006
Java EE SDK & NB 5.5
I've had a chance to work a bit with both the Java EE SDK and Netbeans 5.5 beta. I love the SDK...I've been able to produce EJB 3 code with ease. I love the ease of utilizing Netbeans with the SDK. You literally install and begin coding...very little set up time!
I continue to use JDeveloper at work, and it is also great. Although there is a bit of a learning curve involved. I'd definitely prefer Netbeans if I was a beginner. Its ease of use and its new features make it a very close contender with any other great IDE.
I've also had no issues with the Sun Application Server PE9 thus far. I've always been a fan of this free Sun App Server, and the new release is no let down.
Give it a try!
I continue to use JDeveloper at work, and it is also great. Although there is a bit of a learning curve involved. I'd definitely prefer Netbeans if I was a beginner. Its ease of use and its new features make it a very close contender with any other great IDE.
I've also had no issues with the Sun Application Server PE9 thus far. I've always been a fan of this free Sun App Server, and the new release is no let down.
Give it a try!
Tuesday, May 16, 2006
ORA-07445
Ever since I created my first database on our new production box, I've been receiving an ORA-07445 error intermittantly. For a while (about a month or so), it went away and that is the time frame when we moved into production. About a week later we were getting the ORA error again.
I have done about all that an Oracle DBA could do in this situation. I've raked through the alert log, and taken a look at each trace file. I've also run the Oracle RDA (Remote Diagnostic Assistant) and sent the output to Oracle support. We've narrowed the error down to an issue with XML DB within the database. Now, we do not even use XML DB, but perhaps there is a process running within the database that is utilizing the feature. Of course, there is a known Oracle bug which corresponds to my issue. I am supposed to grant all users the XDBADMIN role in order to prevent the issue from occurring. That is not going to happen.
My solution (I thought) was to create a limited role which had SELECT privileges on XDBCONFIG. That role was granted to each user in the database....nothing was resolved. As a matter of fact, this error has been occurring on and off for the past couple of months and it is still not resolved. It does not appear to be affecting the way in which the database is functioning, and my users are not complaining of any issues. But I am still curious as to why I continue to receive this error. Is it really the Oracle bug which support thinks it is, or is there another cause which we have not yet found?
I have done about all that an Oracle DBA could do in this situation. I've raked through the alert log, and taken a look at each trace file. I've also run the Oracle RDA (Remote Diagnostic Assistant) and sent the output to Oracle support. We've narrowed the error down to an issue with XML DB within the database. Now, we do not even use XML DB, but perhaps there is a process running within the database that is utilizing the feature. Of course, there is a known Oracle bug which corresponds to my issue. I am supposed to grant all users the XDBADMIN role in order to prevent the issue from occurring. That is not going to happen.
My solution (I thought) was to create a limited role which had SELECT privileges on XDBCONFIG. That role was granted to each user in the database....nothing was resolved. As a matter of fact, this error has been occurring on and off for the past couple of months and it is still not resolved. It does not appear to be affecting the way in which the database is functioning, and my users are not complaining of any issues. But I am still curious as to why I continue to receive this error. Is it really the Oracle bug which support thinks it is, or is there another cause which we have not yet found?
Friday, May 12, 2006
NB 5.5 Beta
It is now available for download. I will try it out this weekend. I have shyed away from Netbeans lately in favor of JDeveloper. Let's see how Netbeans rates...
Sunday, May 07, 2006
And We're Off!
My golfing season just began today...love that sport! I've been in a golf league for the past two years now, and I haven't gotten any better. Well, I take that back...last year I started to get better and then I purchased a new set of RAM golf clubs...been terrible ever since.
It was a great day for golfing and I did bad as usual. Got a couple of pars, but mostly bogey and double-bogey. I think it will be my goal this year to land at least 2 birdies in one game...that is a tough goal for me considering how bad I am!
Even though I am terrible...golf is great!
It was a great day for golfing and I did bad as usual. Got a couple of pars, but mostly bogey and double-bogey. I think it will be my goal this year to land at least 2 birdies in one game...that is a tough goal for me considering how bad I am!
Even though I am terrible...golf is great!
Decisions, Decisions
As application developers, we come upon far too many decisions within the development of even a simple application. Developers need to make decisions about which type of business logic to use and it what cases to use it. Developers also need to make decisions about how to lay out a user interface and which components will work best for a particular situation.
I've been finding myself in a major decision state when it comes to application development...a decision which must be made prior to making any decisions at all about how the business logic will flow, or how the UI will be constructed. Which language will best suit my needs? As developers, many of us know how to construct applications in more than one language...but which one will do the job best? One of my most difficult decisions is based upon this very question.
For example, last week I was asked to develop a simple layout which will display statistical results for a number of different job crafts. I basically needed to display some data within several different HTML tables. Now, I can easily create this page using a variety of languages: HTML, PL/SQL, JSP, JSF, Python...just to name a few. Which will work best?
I am an advocate of PL/SQL since it is stored within the database, and the speed is unmatched. However, the development time with PL/SQL in such a case may be a bit more lengthy than some other solutions. I also love JSF because of it's clear separation between the view and the business logic, but it may perform a bit slower than PL/SQL. However, my development time with JSF would probably be much shorter than PL/SQL because I can use JDevelopers WYSIWYG JSF solution.
What do you choose in such a situation?
I've been finding myself in a major decision state when it comes to application development...a decision which must be made prior to making any decisions at all about how the business logic will flow, or how the UI will be constructed. Which language will best suit my needs? As developers, many of us know how to construct applications in more than one language...but which one will do the job best? One of my most difficult decisions is based upon this very question.
For example, last week I was asked to develop a simple layout which will display statistical results for a number of different job crafts. I basically needed to display some data within several different HTML tables. Now, I can easily create this page using a variety of languages: HTML, PL/SQL, JSP, JSF, Python...just to name a few. Which will work best?
I am an advocate of PL/SQL since it is stored within the database, and the speed is unmatched. However, the development time with PL/SQL in such a case may be a bit more lengthy than some other solutions. I also love JSF because of it's clear separation between the view and the business logic, but it may perform a bit slower than PL/SQL. However, my development time with JSF would probably be much shorter than PL/SQL because I can use JDevelopers WYSIWYG JSF solution.
What do you choose in such a situation?
Thursday, May 04, 2006
PL/SQL Application Authentication
Recently I ran across a unique way of authenticating users in PL/SQL applications. Usually when I create a PL/SQL application which requires authentication, I end up using the default DAD (data access descriptor) authentication method. I've gotten sick of the pop-up username/password prompt and I wanted to create custom log in pages like I do for my JSF apps. This newly found authentication mechanism allows me to do so.
Take a look at the link asktom.com Q&A ... of course it is from asktom.oracle.com. It describes the methodology that Oracle uses for "retaining" user passwords and how you can create a log in screen which accepts the defacto username/password and then use a stored procedure to check the validity of the user.
It is worth a look if you'd like to do away with the DAD authenication.
Take a look at the link asktom.com Q&A ... of course it is from asktom.oracle.com. It describes the methodology that Oracle uses for "retaining" user passwords and how you can create a log in screen which accepts the defacto username/password and then use a stored procedure to check the validity of the user.
It is worth a look if you'd like to do away with the DAD authenication.
Subscribe to:
Comments (Atom)