Wednesday, September 21, 2016

Eclipse Tip: Using an Built-In Variable to Customize a Linked File Location in the Build Path

Today, we came across this issue and I thought I would share this information since we couldn’t find much out on the net about this subject. Warning: This is a very narrow use case.

Author Note: This post is my first java-centric blog since I have moved on from my Domino/XPages role. I hope to blog more about java related topics in the coming months, thanks to those who encouraged me to continue blogging. I have several ideas in the pipeline.

Background:  My Tech Lead and I are creating three java web services.  We often pair program but also want to be able to work alone. We use Rational Application Developer, which is a flavor of the Eclipse IDE. To manage our code, we use SVN for source control, and I making the assumption that everyone knows the basics of how that works. We are both currently working local, and the code is not on a shared server yet.

As part of our project, there are some file resources in which we need to read. These resources are in a folder that we need to add to our build path and to do so we use a linked source folder.  Also worth noting, we are not allowed to use Maven in our environment.

The Problem:  When each of us, link to the source folder on our hard drive it is stored with an absolute path. When we commit this to our shared repository and then Update to Head, we get the other person’s absolute path.  Each of our user folders is based on our five digit ID so the path is always different.  We needed a way to avoid absolute paths when we link source.

The solution: We used a variable to specify the Linked File Location which translates to our individual paths. This works well, but it is quite confusing initially, until you understand how it works.

How to Implement Solution:

Follow these five steps to use a variable for the Linked File Location:

 1) Configure the Build Path of the project and click on the ‘Source’ tab as show here.  



2a)  
If creating a new location, click on ‘Link Source


2b) Alternatively if you already have a link source then select it, and press edit to see this similar window


3) From either window above, select the ‘Variables’ button and you will see a window like this. These four variables/constants are created by default. You could also add your own here if you have a need to do so.  Make a note of the variable name or write it down because you cannot copy the name to the clipboard.


4) In the linked file location add the variable “WORKSPACE_LOC” instead of the concrete path. Hit 'Finish' to save.


The variable will show in the Build Properties now prior to hitting OK to save. However once it is saved, it will show the complete path without the variable you entered.  This is very confusing.


5) Despite the confusion, if you followed the steps right, the variable is saved. I would recommend verifying that the variable change took by opening the .project XML file and checking to see if the variable is in the path.  You need to use the Navigator window to find the .project file.  If the change took, it will look like below.

Friday, September 16, 2016

Thoughts on my XPages Experience

It is painfully obvious that XPages is on its way out as a technology solution.  Although I will always have a fondness for XPages, its time of relevancy was much shorter than I ever expected.
As someone who dived head first into XPages, I have no regrets learning the technology. What learning XPages taught me was invaluable for moving forward in the world of software development.  For me personally I am currently immersed in the java world.  Right now, I am only working on back end services, but I hope that this changes in the future.  Getting the job I have now would not have been possible without the experience gained using java within XPages. I plan on staying where I am for a long, long time.
So it occurred to me that sure, learning OneUI was a waste, there were many more lasting benefits that I gained from learning XPages.  Here are a few that come to mind.

  • Hands on Java.  I embraced the use of java managed beans, and used them over SSJS whenever it made sense.
  • Javascript. Even proprietary SSJS was beneficial in becoming very comfortable with the language of the web. The more you use something the better you are at it.
  • Bootstrap – still very popular and another skill used everywhere. 
  • JQuery – I used this heavily, and another skill that any developer is expected to know.
  • Relational database exposure – Because my company had a policy of using backend DB2 with XPages, I benefited greatly.
  • Dojo – I am not all that fond of dojo, but it is a skill that is good to know outside XPages. For instance, my company uses dojo as part of one of their key applications (not XPages).
  • Front end javascripts frameworks. This is the future here, and XPages opened the door for me in this area.
  • REST services – it was the XPages Extension Library that introduced me to this concept.  This goes hand in hand with the previous bullet point.
  • Using frameworks in General.  XPages taught me to see the benefit of using established framework to structure an application.


There are probably even more, but this is the list of skills that helped me the most. Because of these skills, I have entirely no regrets about diving headfirst into XPages. I loved working with it, and in some ways wished that time lasted longer.  XPages is still an incredible technology developed by some brilliant people, but market trends and business decisions have brought us to its current state.
If you are still developing XPages, do not feel that you are spinning your wheels, but also proactively plan for the future.

Monday, June 27, 2016

New Directions

It has been a long time since I have posted any blog updates, so I wanted to give an update on what is happening in my world.
As I write, it seems like a very long time since I attended IBM Connect 2016 this past January/February.  It was a great conference and I came home from it very optimistic and fired up about the future.  I was nearly 100% sure that I would soon be moving on from my current position as a contract XPages developer at Navy Federal and finding a new position somewhere else as a Notes Domino/XPages developer.  I had several encouraging meetings at the conference and I left sure that one of them would work out for me.
In March, I came very close to being hired for one particular position that would have had me working with some of the best XPages developers in the business.  After a very positive interview, that job fell through due to factors beyond mine and their control.   It's also worth noting that in the last year, I started to notice a decline in the number of XPages job postings.  It seems like a year ago, there were always 5-7 postings out there, sometimes more, sometimes less.  It seems now the only postings are in the DC or New York areas, two places in which I do not wish to move.
While I love the platform and have a long and positive history with Notes, I knew and have known for years that it was only a matter of time before I would need to move on to other technologies. Years ago in the mid 2000’s I immersed myself in Java with the intent of moving in that direction.  I thought that my ideal job would be where I can get in the door as a Notes developer and then transition to Java without taking the big pay cut that would occur if I went the Junior Developer route.  This was my plan, but I kept getting interesting and well-paying Notes developer jobs.  When XPages came out, I immersed myself in learning it, and found that my prior Java studies have paid off greatly in that area.  While I like backend java, I really loved front end work and I think I am a decent UI designer.
In early April, I found myself working as contract developer and working on doing mostly Notes development.  For some reason, Navy Federal has decided not to create any more XPages projects so most of the work would be maintenance projects on existing Notes client applications.  I was not getting serious interest for other jobs developing XPages despite the honor of being an IBM Champion.  Meanwhile my manager, for whom I have a lot of respect, continued to encourage me to apply for a full time Java developer position in which I would still report to him.  After much reflection, discussion, and prayer I did decide that I would move forward and accept a position if it was offered.  
At the end of April I accepted a full time position as an ISD Developer III and will be working on Java and whatever else they ask me to do.  I hope to get to eventually get to work with the front end again, but for now it will be mostly back end.  I still might work occasionally with Notes if they assign me those projects.  It is very unlikely that I will work with XPages again any time soon.
It is not without some sadness that I move on from the Yellow Bubble (Notes Community).  Even though I am moving on, I hope to maintain contact with the friends I have made.  I remain extremely honored to have been named an IBM Champion for 2016. In some ways it feels like going out on top.  I look back to my goal of ten years ago of transitioning to a Java developer internally from Notes, and realize that I have obtained that goal over 10-12 years after making it.
After I accepted the job but prior to my start date, Navy Federal was kind enough to let me take six weeks of leave to catch up on family visits and move the last of my possessions in storage from Utah to Florida.  Despite many miles of driving, we had great visits in Texas, Utah, Missouri, Minnesota, Indiana, Pennsylvania, and Virginia.  I also got to add 62 miles towards my goal of completing the Appalachian Trail in my lifetime.
So as of today, Monday June 27, I am now a Navy Federal full time employee.  I plan to stay for a while and we will settle here in the Florida panhandle. I have peace about my decision and am excited for the future.  I am also relieved to not have to worry about my future employment for a long time. 
As far as this blog, I hope to continue to blog whenever I find topics that I think will be of interest, and/or topics that I need to make sure I remember for later.

Saturday, February 6, 2016

Thoughts on IBM Connect 2016

Three days have passed since I returned home from IBM Connect in Orlando. This was my fourth ‘Sphere’ with my last being two years ago. This is my first time to attend as an IBM Champion! My overall impression was extremely positive. It certainly exceeded my expectations, and my expectations were pretty high.


My Goals for a Successful Conference


My personal goals were split into three equal parts:
  1. Spend time with existing friends/acquaintances as part of the finest software community in the world 
  2. Network, network, network which overlaps with #1 
  3. Increase my knowledge by attending technical sessions
Community
The community was out in force this year with just a few notable exceptions. The community we have really is something special, amazing really. I am tempted to list all the names of people I enjoyed seeing but don’t want to miss anyone. It was great to meet some people that I knew of but never met such as John Dalsgaard, Simon Peek, Greg Reeder, and Jeff Twardowski.

I also really enjoyed spending time with my Navy Federal coworkers Ernie Javier and Blair Armeau. Prior to this, I had only known Blair via sametime so it was great to meet in person. To me now, they are friends, not just coworkers.


When it was time to leave immediately after the closing session, I was tired and ready to see my family, but still it felt hard to leave such a group of amazing people.


I would be remiss if I didn’t mention the people whose presence was missed. It would have been better with Marky Roden, David Leedy, Mike McGarel, Peter Presnell, Ulrich Krause, and Shean McManus.
Networking
Connect 2016 was also very productive for me on the networking front. At my current employer they don’t have any more XPages projects in the works so I have to decide whether to stay or go. This conference really gave me clarity for the future. I don’t know how things will play out, but I had some conversations that were very encouraging. Along those lines, if anyone reading this is looking for a developer with 20 years of total experience and 3.5 years of XPages then please reach out to me at zavocki@hotmail.com.
Sessions
The quality of sessions this year was definitely on par with past conferences. The topic that really surprised me this year was Bluemix. Although I had seen sessions on it before, the progress that the team has made was very impressive. It has definitely caught my attention.

These were my favorite sessions:

  1. The XPages of Things: Integrate Bluemix into your XPages Applications for a World of Possibilities. I think that John Jardin blew everyone away with what he demonstrated in this session. For me, the relevance of BlueMix went way up with this session.
  2. Get Hands-On with XPages Apps for Bluemix – Martin Donnelly and Brian Gleason gave more details on what Bluemix with plenty of demos. Because I previously had been inspired by John, this session has more meaning for me.
  3. The Grid, the Brad, and the Ugly: Using Grids to Improve Your Applications – This session by super champions Brad Balassaitis and Paul Calhoun was very informative and the audience was extremely engaged. Even though I had a fair amount of experience with the topic I certainly learn quite a bit.
  4. Real-time Video Chat XPage Application using Websocket and WebTRC Technologies – first time attendee and hopefully future champion Csaba Kiss showed two methods of having a real time chat application inside of XPages. The material was comprehensive and he covered a lot, and certainly inspired the developer audience to think of ways to integrate this into new and existing applications.
  5. Once You Go Graph… Nathan Freeman is obviously extremely passionate and knowledgeable on this topic. I had been wanting to see this session at MWLUG, but it was presented opposite of the one I was giving. I first heard of graph databases two years ago, the first and only time I met the late great Tim Tripcony. He was just as passionate on Graph database and spent a half hour explaining them to me. I like sessions that inspire you to want to learn more on your own.


General Impressions

OGS

For the most part, I really liked the OGS, compared to past years it seems to take itself less seriously.

I was very unimpressed with the guest speaker Jason Silva. I thought his message was intellectual cotton candy, and visually distracting. I was very impressed with the case study from West Africa on how an XPages application has helped improve fair trading between farmers and the middlemen who deliver the product to market. 

The drama where they showed the new products being used was funny and well done. It was obviously contrived and very staged, but that is to be expected with this type of demo. I thought the break in the middle was a good idea.

Universal Studios

Whenever I go on rides at parks like Universal, I get reminded that I am not a kid anymore. Even though I got queasy, I  enjoyed spending time with John Jardin, Andre Horak, and Paul Withers on the Harry Potter ride. The castle there is extremely impressive as were the animated paintings. After that John convinced me to ride the dragon coaster. It might have been the fastest coaster I ever went on. I would have liked to ride it again but the stomach would not allow. 

The Venue

I had no problem with the venue. I hope that they continue it there next year, although nothing was announced. I like the fact that I could stay nearby at the Days Inn which was only a five minute walk. This year I am paying my own way to be at the conference so having reasonably priced hotel and food options nearby is a huge plus. When we were on Disney property, we had none of that. News like this doesn’t make we want to spend money on the mouse, even if they backtracked later due to public pressure. 

An Apology

I feel the need to apologize for my awful cough which I am sure was annoying to those sitting around me. I know that I was a distraction and I appreciate that everyone seemed to be understanding.

Final Thoughts


Overall, I felt a very positive vibe from those around me. It was encouraging to see many first time attendees, as well as some very engaged younger developers. The conference is alive and well, and I hope IBM does nothing radical to change that next year.

It was an big honor to have my photo on the big screen before the OGS

Wednesday, January 20, 2016

Looking Forward to IBM Connect 2016

In less than two weeks I am excited to attend IBM Connect 2016 in Orlando. It is now a full twenty years that I have worked in the yellow bubble.  I was just a newbie when I attended my first Lotusphere in 1996. I went again in 1999, and then not again for another fifthteen years until 2014. This will be my fourth time.

As is always the case, there are many great sessions this year. The sessions are only part of what makes the conference great, the other part is the people you meet.

These are my top 5 sessions that I am most looking forward to attending.


1) Real-Time Video Chat XPage Application Using Websockets and WebRTC Technologies:  This seems like a fascinating session and I am excited to hear from Csaba Kiss who I met at MWLUG this past August.

2) Optimus XPages: An Explosion of Techniques and Best Practices: I am excited to see my friend John Jardin again. He is a dynamic speaker with a passion to share knowledge.

3) The Grid, the Brad, and the Ugly: Using Grids to Improve Your Applications:  Brad Balassaitis's blog has been a huge help to nearly every XPages developer. It will be great to hear his latest take on the grid choices that we have now.

4) 'Marty, You're Just Not Thinking Fourth Dimensionally': Troubleshooting XPages: Paul Withers is a brilliant developer and I am really looking forward to his session.

5) Outside the Box: Integrating with Non-Domino Apps Using XPages and Java: This is an area where I have quite a bit of recent experience. It will be great to hear what Julian Robichaux and Kathy Brown have to say on the subject.

There are many other sessions I am looking forward to as well.  If you are still considering whether to attend the conference this year it is not too late. The nice thing this year about being off Disney property is that there are several nearby hotels within walking distance that have very reasonable prices.  

Thank You, Thank You, Thank You


I also have unfinished business in thanking those who nominated me for IBM Champion. It is a great honor to have been chosen this year. I want to specifically thank Mark Roden who told me 2 years ago that I could be a champion. I didn't know what to think at the time, but that confidence did motivate and encourage me,


Tuesday, November 17, 2015

Limiting Keyboard Input in XPages

One way to make your validation easier is limit the types of characters allowed in a specific input field. For example, if you have a numeric field you simply don’t allow the user to type a letter in that field. If you know that an email address cannot contain special characters, you can simply prevent the user from typing those special characters. I would caution that if using this technique for public facing applications, that the use of tooltips or helper text be considered.

Last Thursday I was told that in my application, the field was allowing the entry of numbers from the main keyboard but not the numeric keypad. I discovered that the behavior of the dojo combobox differs from that of the core controls. In this post, I will explain the usage of the keypress event in general, and then explain how to use it with a dojo combobox. 

Before I begin, I have to laugh at the irony of this new Stack Overflow question (http://stackoverflow.com/questions/33680515/how-to-prevent-special-characters-input-into-edit-box) about this very subject that appeared a few hours after working on this. Amazingly no one had answered it by the time I saw it, and of course it was fresh on my mind, so I answered it with what I was already going to put in this new blog post.

Keyboard Events


There are three key events that you can use. The onkeypress, and the okeydown, and the onkeyup. As the name implies these are keyboard events. In XPages you can assign client and/or server code to each. I would strongly caution for performance reasons against doing anything serverside that is more complicated then setting a scoped variable. The code that we want to use to limit certain keys is all clientside javascript.

Usage in an Edit Control



This code shown here will only allow numbers and the backspace key. In XPages, if applied to a core control, this also allows the numeric keyboard to work even though it uses different keycodes. The
keycodes for the numeric keyboard are 96-105. For an edit box the only event you need is the onKeyPress.

Usage in a Dojo Combobox


One of the nice features of the dojo combobox is that you can choose from the list or type in a value. You also get built in type ahead. The key events work differently in two specific ways though. If you just use the onkeypress event, then if the user types really fast they can bypass the event and type an unwanted character. These are the types of things the quality assurance people are happy to point out to you. The way to prevent this behavior is to put the code in both the onkeydown and onkeyup events.


How to selectively include or exclude any key


My example above on specifically includes numbers, your needs may differ. You can use http://keycode.info/ to easily figure out any keycode. Modify the code below to meet your specific requirements. This example only allows letters, numbers, backspace, and delete.

var keyCode = event.keyCode;
if((keyCode >= 48 && keyCode <= 57) || (keyCode >= 65 && keyCode <= 90)|| keyCode == 8 || keyCode == 46){
   event.returnValue = true;
}else{
   event.returnValue = false;
}

Thursday, October 1, 2015

Creating JSON objects in Java using the JSON.simple toolkit

I needed a way to create JSON objects in Java for displaying in a grid. There are several options for doing this that I could have chosen. There is GSON from Google, or I could roll my own using StringBuilder. After doing some research, I decided to use the JSON.simple toolkit because, the examples looked simple and straightforward to me.  In this post, I will explain how I used JSON.simple and give two real life examples.


Installation

To use JSON.simple you need to download the jar and add to your build path. The jar is available here: https://code.google.com/p/json-simple/


Creating a Single Object


In this snippet, contents of a NotesDocument are added to a JSON object and then that object is passed back to the caller of the method. Note this example uses the Name class from the original Notes,jar to format the Notes name. It is the java version of @Name.

Document doc = col.getFirstDocument();
JSONObject json = new JSONObject();

if(doc != null){
   Name name = session.createName(doc.getItemValueString("EmployeeName"));
   json.put("employeeName", name.getCommon());
   json.put("employeeID", doc.getItemValueString("EmployeeID"));
   json.put("employeeLocation", doc.getItemValueString("locationdesc"));
   json.put("employeeRole", getEmployeeRole(name.getCommon()));
}
returnValue = json.toJSONString();
...
return returnValue;

The result will look something like this:

{"employeeLocation":"Pensacola Milton","employeeRole":"Intern to the Intern","employeeID":"12345","employeeName":"Dwain Wuerfel"}


Creating a Collection of Objects


In this snippet, the contents of a multi-value document are traversed and a JSON object is created for each item. Many will recognize that I am grabbing the members of a Name & Address Book group. For each member I create a new object and then that object is added to a JSONArray object called ‘result’ which is then returned to the calling method. Each object will be a displayed on a separate row in the grid.

JSONArray result = new JSONArray();

if(nabDoc != null){
   Item item = nabDoc.getFirstItem("Members");
   Vector<String> v = item.getValues();

   for(String person : v){
   Name name = session.createName(person);

   JSONObject json = new JSONObject();
   json.put("employeeName", name.getCommon());
   json.put("employeeRole", employeeRole);
   json.put("employeeID", EmployeeID);
   json.put("employeeLocation", EmployeeLocation);
   result.add(json);
}
returnValue = result.toJSONString();
...
return returnValue;

The result will look like this if there are three JSON objects in the array:

 [{"employeeLocation":"Pensacola Milton","employeeRole":["Minion"],"employeeID":"12345","employeeName":"Dwain Wuerfel"}, {"employeeLocation":"Pensacola Milton","employeeRole":["Blog Author"],"employeeID":"91984","employeeName":"Steve Zavocki"},{"employeeLocation":"Pensacola Milton","employeeRole":["Cast Member"],"employeeID":"54321","employeeName":"Vernon Miles"}] 

Conclusion


As the name implies the JSON.simple toolkit is simple to use, and a good option to consider if you need to create JSON objects within your java code. In case you are interested in learning more about your other options, here is an article that compares three different json toolkits including JSON.simple.

Monday, September 21, 2015

Sorting a Java ArrayList of SelectItem Objects

Recently I had a task where I needed to read all the names from several groups in the Name & Address Book.  I needed to get all the names sorted and unique for presenting in a Combobox.

In this post, I will show you how I did this, but more importantly I will show how I used the Java Collections Framework to my advantage.

In case you aren’t aware, the SelectItem object is the object type that Java Server Faces (thereby XPages) uses for the values of a Combo Box. It contains a value and a label, of which the label is what is shown and the value is what is saved.

Because the SelectItem does not implement the Comparator interface, you cannot easily sort an ArrayList of SelectItems. You could write your own sorting method if you like using the instructions outlined in this blog post. I considered this but then thought of an easier way to accomplish the same thing.

Here is what I did to solve this: Instead of creating just an ArrayList of SelectItems, I also created one of Strings. Strings of course are easily sortable since the String class does implement Comparator interface. Prior to sorting the list, I need to removed duplicates. To do this, I first create a HashSet and assign the values to it. A Set in java does not allow duplicates, so assigning all the values to the HashSet was the easiest way to remove the dupes. After this is done, I assign all the values back into the ArrayList and then sort the list. I then create an SelectItem ArrayList with the unique sorted values.

Note: This would be a lot more complicated if I needed my SelectItem object to have different Strings for Label and Value. I would probably use a HashMap instead of an ArrayList<String> if this was the case.

Code Example


public List<SelectItemgetUserList(String schema){ 
1  List<String> options = new ArrayList<String>(); 
List<SelectItemsortedOptions = new ArrayList<SelectItem>();

try { 
  Session session = getCurrentSession(); 
  Database nab = session.getDatabase(session.getCurrentDatabase().getServer(), "names");

if (nab.isOpen()) { 
View view = nab.getView("Groups"); 
if (view != null) { 
Document doc = view.getDocumentByKey("Group 1"true); 
if (doc != null) { 
Item item = doc.getFirstItem("Members"); 
Vector<String> v = item.getValues(); 
for(String person : v){ 
Name name = session.createName(person);  options.add(name.getCommon()); 
} 
doc.recycle(); 
item.recycle(); 
else { 
log.error("Group 1 cannot be opened."); 
} 
doc = view.getDocumentByKey("Group 2"true); 
if (doc != null) { 
Item item = doc.getFirstItem("Members"); 
Vector<String> v = item.getValues(); 
for(String person : v){ 
Name name = session.createName(person); 
options.add(name.getCommon()); 
} 
doc.recycle(); 
item.recycle(); 
else { 
log.error("Group cannot be found, or opened."); 
} 
……………… //get names from third group 
} 
else { 
log.error("Address Book is not found, or able to be opened."); 
} 
catch (NotesException e) { 
log.error("EXCEPTION in getUserList(): " + e.toString()); 
e.printStackTrace(); 
} 

Set<String> hs = new HashSet<String>();
hs.addAll(options); 
options.clear(); 
options.addAll(hs); 

Collections.sort(options); 

for(String person : options){  
SelectItem option = new SelectItem(); 
option.setLabel(person); 
option.setValue(person); 
sortedOptions.add(option); 
} 
return sortedOptions; 
}

Code Explanation using footnotes:


1  - Declare two ArrayLists, one for Strings, and one for SelectItems.

2  - The values of a multi-value field are returned as a Vector. For each item in the Vector, I assign the item into the String ArrayList

3 - This uses the Name class to get the formatted name. This is part of the original Notes API for java, and is quite useful.

4 -  This is where I pass the contents of the String ArrayList into a HashSet and then back again. All Sets in Java are not able to contain duplicate values. 

5 - After the duplicates are removed, then I sort the list. If you try to sort before removing duplicates it won't be sorted after changing to a Hashset and back. As you can see, sorting a String List is very easy using the Collections class.

6 -  Lastly, I convert the ArrayList of Strings into an ArrayList of SelectItems for use in my combo box.

Last Words


In Java the Collections Framework is super useful and one of the strengths of the language. If you are learning Java it would wise to pay special attention to knowing what it can do for you.  

Please check comments of this post for some great tips on how to improve on what I posted.