Thursday, December 26, 2019

Are you a Full-Stack or T-shaped developer?

When I first started programming as a profession in 2000, the idea of a cross functional developer was still in an infancy.  However, I suppose, the idea originated with the mainframe.  There, you would find a COBOL developer who knows SQL.  Mainframe developers know those two programming languages due to the coupled nature of SQL and COBOL.  It didn't make much sense to have a DBA or SQL-only expert come in an 'install' SQL to your COBOL program.  In today's world those two concepts compose two parts of the three-tier architecture application; business logic and persistent storage.

No one talked about full-stack or T-shaped developer just 17 years ago.  Today, it's a big deal.

Term review:
Full-Stack Developer:  A developer who can easily cross tiers of an application by creating usable solutions.  The three tiers commonly associated are presentational, business logic and persistence.  This developer has skills in: JavaScript, HTML, CSS, an OO-language like Java or C#, and SQL or noSQL database concepts.  It is also becoming increasing clear that some sites may skip over the OO-language in preference of JavaScript for their business logic tier.  What's also become useful in a DevOps world as well are skills related to configuring the platform where all of the above is going to run.

T-shaped Developer:  A developer who has a breadth of knowledge (the top line of the T) and a depth of one or a few skills within that knowledge (the down line of the T).  To a degree the Full Stack and the T-shaped developer go hand in hand.  However, a T shaped developer may also include skills related to project management, business analysis and people management.

I look for both types of developer depending on the role being hired for.  If I'm looking for a pure developer; a coder with headphones on most of the day, churning out commit after commit, and interfacing with other developers, then I'm looking for the Full-Stack variety.  If I'm looking for a lead or senior developer, then I'm looking for the T-shaped developer.

What do you need to get there?
First, I think a Full-Stack developer becomes a T-shaped developer over time.  This is a natural progression as you become more experienced and have the social skills to push properly for your vision.  Therefore, T-Shaped is really a very experienced Full-Stack developer!

So how do you become a Full-Stack developer?  Lots of training.  I think you have to spend time on your own to find the bits, pieces and parts that make up the above description.  The world is about websites and mobile applications; you can make your own on your own time.  There are plenty of tutorials to cover all of the technologies involved in a Full-Stack developer.  You just have to invest the time.  Finally, I think you have to put yourself in a professional position to do all of the above as well.  Interviewers like experience that involves for a business and what you do on your own.  You have to have both.  That will set you apart from others.

Conclusions:
A full stack developer is a T shaped developer!  Being human we are unlikely to be able to master many disciplines at a high level of performance in each.  Full-Stack Development is a starting point.  You can get going on the three tiers and see where that takes you as you go deeper and deeper into software development life cycles.  Good luck!

Sunday, March 12, 2017

The Most Overused Term in Software Development

The POC ... Proof of Concept.

You're boss/architect/design authority comes to you on Tuesday after that three day weekend and says "I was reading up on Spring Boot this weekend.  Looks neat.  Should solve some problems for us.  Lets do a POC."

You roll your eyes ... internally for fear of losing your job.

The reality is that Spring Boot and most other Open Source Software you can name is proven to work!  The concept is that you want to use Spring Boot and you need to provide proof that it works is just silly.  Really, what your boss is saying is that they want you to learn about that software and get to work implementing it.

Now, does the POC exist?  Yes, of course it does.  Let's say that same boss comes up to you and proposes combining two or three pieces of software that no one has EVER done before or has some new pattern of software to create, then yes, that's a proof of concept.

So next time, gently correct this misuse of POC to training.

Saturday, December 10, 2016

Intellij and React Native Projects

If you want to add your existing React Native project to your Intellij project as a module do the following:


  1. File > New > Module
  2. Click Static Web > Static Web
  3. In the 'Content Root' box, enter the location of the existing React Native directory.
  4. Click Finish
The reason you have to do it this way is that the Intellij Import Module from Existing Sources wants to find a source / setup for the module.  The problem is that you've got three different code streams in your React Native project:  1) Java for Android, 2) iOS XCode files and 3) React JavaScript files.  My experience has been that the Intellij scanner picks Java over JavaScript and ignores the rest of the directories.


Back to Comcast, No more AT&T

Well, I'm back to Comcast.  Can't beat 75 Mbps for $49 a month for a year.  AT&T just can't keep up with speed and prices.  Since we've cut the cord and stream just about everything, the extra Mbps are really great around here.

I did run into a bandwidth issue with my older Netgear N600 router.  The router was not giving us a good chance to get a hold of the 75 Mbps over wireless.  The router was working fine over an Ethernet connection.  On wireless though, you would get anywhere from 15 - 20 Mbps on any wireless device.  I concluded that only an upgrade in the router would fix the issue.  I bought a Netgear Nighthawk AC1900.  Wow, what a difference!  I suspect the underlying issue was that with 2 iPhones, 2 iPads, 3 laptops, 2 Kindles, 2 Rokus and a PS3 we hit the limits of the N600.

Finally,  I just realized that for the first time in 16 years I won't be paying anything to a traditional landline company (Southwestern Bell, AT&T).  At one point we had, Uverse and AT&T wireless.  I calculated that we were paying them about $340 a month in services and equipment.  You would think someone at AT&T would notice that and come-a-knockin', but I won't be waiting by the phone for a call from them.

Anyway, happy for a year.  Let's see what kind of deal I can get next year!  I had my eye on a three year deal for $50 with 150 Mbps!

Saturday, October 1, 2016

I've gone Mac

I've had some form of a PC since 1986.  I used to think Mac was terrible.  It was a special animal that didn't play well with others.

Then I got one.

In early August, I was wanting to build an iOS app.  My wife had come up with an idea for one and I knew that a native app was needed for full integration of the requirements.  I first built a web app to get it going.  I had picked out a MacBook Pro with 256 GB HD and 8 GB of RAM.  I have to say that a Mac is the way to got these days.

Pros:

  1. It is fast.  With the SSD drive, Intel Core i5 processor and 8 GB of RAM, you won't be without speed.  Compared to my platter drive, Intel Core i7 and 8 GB of RAM on my HP, I never feel a slow down while it is trying to figure out whats going on.  
  2. The screen is killer.  It's so sharp it's hard to believe that I could have been doing with out it.  My HP Envy 17 is terrible.  To some degree I think that's because I wound up turning the brightness down pretty far to save battery.  In general though the Retina display is just that sharp.
  3. The battery keeps going and going.  With the HP Envy I would fret about being on the battery as I watched it go down during my commute.  I would definitely have to charge it overnight to use it the next day.  Now, I can use it for two days (approximately 8 hours of usage) before I need to plug it in to charge.
  4. Integration.  I have an iPhone 6s Plus and the great thing is that my Mac works with my iPhone like never before.  If I get a phone call my Mac can pick it up, assuming were both on the same WIFI connection.  I can FaceTime and send iMessages through my Mac as well.
  5. Weight.  I was commuting with the HP Envy 17 plus my work laptop.  I think the total weight was about 12 pounds in my back pack. The Mac is so light that I barely know its there.
Cons:
  1. It is a bit smaller.  I do miss the screen real estate of the Envy 17.  This MacBook is the 13" model.  I didn't want the 15" model due to cost and reduced battery performance.  I also loved the additional numeric keypad on the HP Envy.
  2. It's one of those things of when you need it, you need it.  There is no optical drive on the Mac.  I had to burn a CD (gasp!) for my wife's car and I had to use her computer to do it.  A few times as well, I've thought about plugging into my Ethernet port on my router.  I would need an additional adapter to do that.
All in all, great machine.  I use my computer even more often now!

Saturday, February 6, 2016

Shaving the cord

All in, we were paying $175 for AT&T Uverse TV, Internet and Phone.

In terms of the cost, we didn't have a trouble with the bill.  We had trouble with the value.  As you scroll through the list of channels you realize that you watch about 25% of them and wonder if anyone watches some of the more extraneous ones.  Phone service was $45 a month for unlimited calls across the country.  While I believe in the 'home phone' I don't think it should cost that much.  Internet is in the 18 Mbps range for about $30 a month under the bundle.

We could afford it.  Keep going on until the bundle deal runs out.  Why though?

Courtney and I decided to trial run a 'cord shaving'.  Here is what we did:
  1. We disconnected the Uverse DVR from the TVs.
  2. We bought a Mohu Sky 60 and I installed it in the attic.
  3. We bought a Roku Stick for one TV.
  4. We planned on using Amazon Prime, Hulu, Sling and CBS All Access for streaming services.
  5. We already had a Chromecast.
At least in the trial run, we wanted to keep recording our shows on the Uverse DVR if we didn't like how it was working out. The antenna supplies digital over the air (OTA) signal to all TVs in the house.  The quality is fantastic and it's FREE TV.  The theory on the antenna was that if it didn't work out, we could still use the antenna in some capacity.  The Roku Stick is usable anywhere in the house and we figured what it provided, again, if we didn't like how it all works, we could still use it.  The Chromecast helped with the TV in our master bedroom.  We used the Chromecast to send to the TV the services we wanted to watch using our phones.

If the trial worked out, we planned on adding another Roku and switching phone to Ooma.  The additional Roku was to give a unified experience across TVs in the house.  Chromecast depends on applications being coded to be able to cast to the nearby dongle.  The problem I found is that the casting can be spotty with connection issues or quality.  

The trial lasted about a week.  We were sold.  There really wasn't anything that we were missing from Uverse TV that we couldn't get over the internet. We could watch football for free on a high quality signal. The shows that we really watched were there on the streaming services.

Costs:


Category Item Up front cost Monthly cost
Air Antenna Mohu Sky 60 $160 None
TV device Roku Stick $49 None
TV device Roku 2 $59 None
Service Amazon Prime None $8.25 ($99 a year)
Service Hulu None $7.99
Service SlingTV None $19.99
Service CBS All Access None $5.99
Device Ooma Telo $150 None
Service Ooma None $5.62
Total $418 $47.84

With the Uverse Internet cost of $59 a month.  I'm at $106.84 for Internet, Home Phone and TV.  A savings of about $70 a month.


Pros:
  • Buy the television programming that you watch
  • Own the equipment that you use
  • Freedom to choose the equipment that you use
  • Better quality with OTA
Cons:
  • If the internet is spotty, your TV watching may be interrupted
  • Up front costs are high
  • You cannot pause live TV
In short, this shave project was a success.  Now, where's that remote?

Sunday, November 1, 2015

Back to iOS: my year long review of Android.

In July 2014, I had enough of iOS.  See my post from then: I've gone Android

Now, in November of 2015, I'm back with iOS and an iPhone 6 s Plus.  Here are my observations of having an Android phone.

  1. Security.  I've noticed that there are lot more discussions on viruses and malware in the Android ecosystem than you've ever heard about from Apple.  I found it awful that my text message client had to guard against 'Stagefright'.
  2. Fragmentation.  It's awful.  It's very hard to get a good experience with Android when manufacturers like Samsung roll their own applications. Take the Clock application; something so basic and simple, yet Samsung required themselves to rewrite it for TouchWiz.  What does this really mean?  Slower time to market with major updates.
  3. Application Updates. Believe it or not constant application updates are annoying.  Every night my phone would be updating to the latest version of some application.  I don't know why this is completely necessary.  However, I have to believe that the changes are necessary to keep the applications working with the changing environment including point #1.
  4. Major Updates.  Google released Android Lollipop to the manufacturers on 11/3/2014.  It wasn't until April 2015 when I got the image pushed from AT&T.  As a software developer, I know that this is good turnaround time assuming that the first time Samsung saw the code was on 11/3/2014.  Reality might be that Samsung saw developer previews as early as June 2014.  As a consumer, however, this is dog slow.  Why did it take so long?  First see point #3.  Second, don't forget that in the Android ecosystem, the carrier pushes your update to you.  I know that AT&T also included some of their applications in that image.  Finally, just before I got Android 5.0, AT&T upgraded me to Android 4.4.4.  Why was that necessary?
  5. Bloatware. I don't need another account to login to, Samsung account.  I don't need another place to store information.  That's what Googles services are for.  I don't need any of the AT&T applications that were automatically included in the version of Android I had.
  6. Customization.  How could that be such a bad thing?  Android is way better at it than iOS, but I feel as if ability to customize comes at the cost of battery life.  Example, it always seemed to me that an application that you replaced was still running in the background anyway. I used Nova Launcher instead of TouchWiz for most of my 16 month experience.  At one point, the widgets were not updating while on Nova and I finally figured out that when applications were updated, the launcher would some how restart and defer to TouchWiz to update the content in the widgets.  I fixed this by clearing out the data in application manager for TouchWiz.  It was a hard to find fix.  Finally, Android gives you the option to choose default applications for a lot of what you do.  Like Windows, this allows you to use Google Chrome over the built in Internet browser from Samsung.  The problem is that it's not a very good defaulting system.  Repetitively, I was asked what my default for this action should be.  Should Android open the link in Adobe Reader, Google Drive Reader, or Google Chrome?  You could touch Always and that should use that application permanently, but it never seemed to work seamlessly.
  7. Other Phones. A few months ago, I was looking at what would be my next Android phone.  I was dead set on a Moto X Pure Edition due to a lot of the issues mentioned above.  Supposedly, the camera was decent even though Motorola has had a poor history with their cameras.  A lot of the reviews mentioned that this is the phone to have if you want a 'pure' Android experience and a bit more than a Nexus phone.  This point proves that there is just too many choices out there.  This is where Google needs to take back Android and make it "this is the OS, you can't make it your own manufacturers!"  That way, the choice comes down to hardware.  Screen size and quality, faster processors, better cameras, faster fingerprint readers, etc. now become the choices in your Android phones.
  8. Battery. In the waning days of my experience with Android,  I had gone back to TouchWiz and turned off some of the other customizations I had because the battery would drain to 20% before 5 PM after a full charge the previous night.  One day it was drained to 20% by 12 PM.  I can't say why this was.  When I looked at the built in battery monitor, it basically said the major culprit was Android System and Android UI.  In previous reviews, it had been ESPN and Bluetooth.  How could Bluetooth consume 15-20% of your battery when it was only connected to another Bluetooth devices for less than 30 minutes earlier in the day?  I suspect some update caused Bluetooth to behave this way.  I also suspect another update fixed this.  I can't say which one though.  ESPN I uninstalled completely due to battery drain.  I didn't see a fix that I could do.  With Bluetooth, I turned it off for awhile, deleted any connections I had, etc.  This was a temporary fix.  The best battery life I got was when I reset my phone completely.  As you might expect once you start adding in all of the applications you like/need then you start to experience an abnormal battery drain.
In short, it wasn't a rosy experience.  Do I have anything good to say about Android?  Yes, it was different than what I had before. Integration with Google services is good, but I don' t really think it is 100 times better than what you get from iOS applications for Googles services.  Difference is good for awhile until that difference has issues.  Then it's just annoying and you go back to what works. 

Saturday, April 11, 2015

Linux, Windows 8.1 and Virtualization

I'm a Linux fan.  I like it's simplicity.  I like getting back to the command line.  However, I've just dumped Ubuntu and Linux Mint for Windows 8.1.

Backstory
In early 2014, I bought a new HP Envy 17.  It's a beast of a computer, Core i7, 8 GB RAM, 1 TB hard drive, and so on.  Good developers machine, I'd say.  I knew I could order it with Windows 7 for an extra cost, but I also knew that I had a full copy of Windows 7 Ultimate (Steve Ballmer Special Edition no less!) that I could use.  So I decided I would chuck Windows 8 and dual-boot Windows 7 and Ubuntu 13.10.

For the most part, I don't like Windows 8.  Clearly, Microsoft build this interface to serve tablets and laptops.  I'm not a fan of a touch screen laptop so I'd never have any real use of the Windows 8 "Metro" interface.  Further, I believe Windows 7 is still in good shape from what it does and how it performs.

Initially, with the dual-boot setup, I was content with the configuration.  At this point I knew nothing of running a virtual machine with VirutalBox.  I had a bit of a bug with how I had configured the system.  Apparently, I turned off UEFI and SecureBoot when all I should have done was turn off SecureBoot.  I think I thought they worked hand in hand and needed to be off together or that Linux and Windows 7 were compatible with UEFI.  Either way, the gremlin in the system was that the clock tended to be reset to GMT.  I couldn't figure out whether it was Ubuntu or Windows 7 causing that issue, but it was annoying none the less.

In the fall, I was tempted to try Linux Mint instead of Ubuntu.  I know that Linux Mint is based on Ubuntu, but the interface is what is drastically different.  Another mistake made...I wound up deleting my Windows 7 partition while installing Linux Mint.  That was awful.  Fortunately, I discovered that Linux Mint came with Oracle's VirtualBox pre-installed.  I decided to check it out and see if I should make it work with Windows 7.  It was grand.  I could get everything I wanted out of the VM without having to reboot to get into Windows 7.  When I switched to Mint I had an issue with slow wireless connectivity.  It was almost unusable sadly.  After some Googling I found that Mint was a bit behind on the Linux Kernel and an upgrade would fix the slowness.  It was a good fix.

Around December last year, I started having this issue with the wireless losing the ability to deliver Internet content, but the connection was still strong and connected.  I Googled a lot and found that a lot of folks were having issues with Linux and the Realtek wireless card.  I found an updated driver that I installed.  It helped a bit, but not a conclusive fix.  I upgraded Kernels again, no help.  It was very frustrating.  I would say for a given session with the computer the browser would drop pages 5 -10 times.  Eventually they would come back, but it was enough to slow and prevent a good flow of doing something.

About three weeks ago,  I had enough.  I decided that I would give Ubuntu 14.10 a shot and see if that fixed the issue.  My first task was to split my home directory to a separate partition.  This is a really good idea if you want to switch distributions often or even clean install the next iteration of your favorite distribution.  Once that was done, installation of Ubuntu was a breeze including the customization of the partitions to use.  Once I had everything setup,  I noticed that the same problem started happening again.  This time around, it was less often, but annoying still.

Then, I was done.  I realized through this that I had given up a bit too to use Linux.  First, this laptop came with Beats Audio.  In this case, it's three distinct speakers that can be used to improve sound.  While HP has software to help manage the sound and power consumption of the speakers, Ubuntu nor Mint have anything for Linux.  In fairness, I found some instructions on setting the speaker pins to the correct values to utilize the speakers, but since there was no power management, the speakers were on 100% of the time and using more power on battery.

Current
Just three days ago,  I backed up the home drive from Ubuntu and factory reset the computer.  With Windows 8.1 booting to the traditional Windows interface, consistency with the wireless card,  Beats Audio in place and the positive boot up speed,  I'm happy again.  I can still run my VMs now that I know more about it.  In fact, I booted up my Windows 7 VM to get some files off of there.

Now, it's off to Windows 10.  I've just loaded it onto VirtualBox....

Tuesday, December 30, 2014

Dish Network

I started with Dish Network service in 2006.  I can't complain too much about their product over the last 8, almost 9 years, of service.  They've raised their prices, and been willing to work with you on some new prices.  All satellite services will have the issue with weather equaling 'no service' so that's not a complaint to get into.

During this time, I have only had two boxes.  The first was before the major HD revolution.  When I got a new 1080p TV, I wanted the box to match, this was 2008.  Since then, I have seen over-the-air updates of the box software as new features roll out and I appreciated that.  The days of static code in a set-top box are long, long gone and I'm thankful for that.  However, the technology got old, the menu wasn't in HD and was slow to respond.  Further, my former Dish Network box (VIP722) was above my PS3 and if you just happened to leave the PS3 on, it would overheat.

As far as HD, the quality was lower than I've seen on other systems including my new Uverse service.  My wife's parents have the Hopper/Joey system and it appears that my set-top box issues may have been better with that setup, but I really didn't want to pay more for what appeared to be the same channels.  The one thing I did like was that I had one box for two TVs.  I don't like the rent-a-box model, although I do now pay $8 for an additional Uverse box, but I do recall that the Hopper/Joey was more expensive than Uverse.

The final straw was this years issues with network contracts.  I abhorred the idea of losing CBS, even if for a minute.  Dish, you should not have an issue with losing a channel that folks can get for free!  I know other channels were lost for a bit and added back.  I do appreciate Dish fighting for the best prices, but somethings I just can't get past.

When I disconnected, I already had the Uverse setup all in place, the representative on the phone did everything he could to keep me as a customer.  He said that I qualified for a $45 a month bill discount for 10 months because I was a customer for so long.  My first thought was that I had to call to get that discount.  If I was such a valued customer, I think they should have reached out to me. Also, I suspect the discount had more to do with the fact that I was cancelling than my tenure as a customer.  Of course, he was mostly nice until he realized that he couldn't do anything more for me.  Then it was like 'bye' and I was like 'do I get money back?'  Here's the kicker.  He told me that when I returned the box through shipping, I would have to pay $17 for the shipping or get my own shipping.  So let me get this straight, you just offered me $450 in discounts to stay a customer, but now that I'm leaving for sure, I have to pay you $17.  Unreal and goodbye...

Comcast

Back in 2012, I decided to switch from AT&T Phone and DSL to Comcast Cable Internet and VoIP.  While the transition was smooth and the pricing was good, the service was mostly OK.  When the service worked, and it worked 90% of the time, it was good.  Speed was excellent and the phone was clear.

This year, and mostly this year only, we had some service issues.  On two occasions we had a complete outage.  On the first one, we called and they wanted to send a technician out.  The outage was technically a massive slowdown to no response.  We were connected according to the modem, but pages weren't loading at all or the page loads were slow.  Our neighborhood has a Facebook page and many other Comcast subscribers were reporting the same issue.  Finally, Comcast picked up on the issue, either through all of the calls or through their own health checks, and fixed the issue.

When my contract ended this year, I called and negotiated a new rate.  I believe I got the 'new customer rate' and somehow that meant that my phone number would get disconnected so that they could reconnect it.  Further, in order to get the rate, I had to add a $2.50 or $3.50 a month protection plan.  Overall, the new rate was cheaper by $30 than the expired contract rate so I okay'ed it.

I didn't have much trouble disconnecting.  They didn't try to keep me as a customer too much.  That's just fine with me.  When I cancelled, I already had the Uverse equipment so I wasn't going to bend to their temptations.

AT&T Uverse and My Home Network

At my house, we recently switched away from Comcast for Internet and Phone.  For television, we had Dish Network.

I'm pretty impressed with the Uverse experience.  Internet is fast enough with 18 Mbps plan.  I've seen maximums in the 25 Mbps range as well too.  TV is clear and HD picture is better than Dish Network.  I've heard that Dish has the worst HD quality of the major providers.  In one month of usage, I haven't experienced any bad network connectivity with the TV signal.    Overall, though I'm very happy over my Comcast/Dish Network configuration.

I did a diagram of the configuration using Gliffy.


The diagram shows that I have decent separation between the TV network boxes and the Data/Computer network.  I doubt it really matters, but it seems logical to separate the two.  The N600 is necessary because I have an external storage drive that the NVG589 does not support.  Further, the GS108 switch and the N600 are on separate floors in the house.  I tried to connect the N600 to the GS108 switch, but the computer was not getting any internet responses.  I suspect that is because the TV was taking most of the traffic and somehow leaving the router out of the picture.

I've recently added another router to the picture to help with wireless range in the house.  My second floor had an RJ-45 jack in the third bedroom that goes into the basement.  I connected that to the N600 and then configured the N300 to use the same wireless details (on a different channel) as the N600.  Voila! Instant range extension!  I was looking at the 'wireless repeater' functionality, but since I had the RJ-45 jack this was a no-brainer to use.

Sunday, August 10, 2014

I've gone Android!

I had two iPhones.  I didn't think that the iPhone 6 was going to offer anything revolutionary. I realized that from a hardware perspective I was going to get about the same phone. In general, the big ticket items in a phone have been figured out. After big ticket comes small features that you probably don't need anyway. Therefore, in my mind, the last major difference is software. I figured that iOS 8 would look much like 7 as the previous versions looked all similar.

The Galaxy S5 started looking really good to me. I really do think it was just a different interface than what I was used to. Further, I was all 'Google up' with my services. Between Gmail, Drive, Contacts, and Calendar, the switch was easy. I never stored a contact locally. I always used my Google calendar for events. I've even expanded to use Picasa more with my back catalog of iPhone pictures. I uploaded every single song I have to Google Play Music for free.

It was a good switch, but hey I still have my iPad!

Saturday, July 27, 2013

Using CXF Interceptors to measure WebService or REST Service time


Let's say I have this simple service:

@WebService
public interface Hello {
     

      String sayHello();

      String sayGoodbye();

}


I want to know how often and how long sayHello() is executed compared to sayGoodbye(). I could add:

@WebService
public interface Hello { 
      
      @Profiled(tag = "sayHello")
      String sayHello();

      @Profiled(tag = "sayGoodbye")
      String sayGoodbye();

}

In this fashion, I would use Perf4Js @Profiled annotation and it would log messages telling me each time a sayHello() or sayGoodbye() method was called. However, that's not enough. I've just cut out the time of one of the most important parts of WebServices, XML processing.

Enter the CXF Interceptor, assuming of course that I was using CXF, I can write a custom interceptor by extending AbstractPhaseInterceptor<Message>, a fairly generic extension that would apply to JAXWS and JAXRS services. The new in interceptor would start a new Perf4j StopWatch (log4j or slf4j implementation if you please) and the new out interceptor would stop the StopWatch which would force the log record.  With the interceptor, I can also control the phase at which the interceptor is invoked.

Now my service would look like this:

@org.apache.cxf.interceptor.InInterceptors (interceptors = "net.halverson.interceptor.TimerInInterceptor" ) 
@org.apache.cxf.interceptor.OutInterceptors (interceptors = "net.halverson.interceptor.TimerOutInterceptor" ) 
@WebService 
public interface Hello { 
     
      String sayHello(); 

      String sayGoodbye(); 
}

But how do I know whether sayHello() or sayGoodbye() was called.  I suspect I could access the Message object in the interceptor and find out, but maybe I want more control than that.  That Message object is hanging around while my service is called and I can even place some of my own objects in it, however,  my service implementation does not have access to the Message object and I doubt I would ever want it to.

How then can I update the StopWatch with a 'tag' or 'message' for Perf4j to log?  A ThreadLocal will do.  Remember how we started the StopWatch in the in interceptor and stopped it in the out interceptor, we can use a ThreadLocal to place the StopWatch into that thread variable state and access the object across the thread without having to pass the object along the method calls in the stack.

Something like this:

public class ServiceTimer {

      private static final ThreadLocal<Slf4JStopWatch> stopWatch = new ThreadLocal<Slf4JStopWatch>() { 
              @Override
              public Slf4JStopWatch initialValue() {

                    return new Slf4JStopWatch();
              }

};

      // execute in the in interceptor, ServiceTimer.getStopWatch().start();
      // execute in the out interceptor, ServiceTimer.getStopWatch().stop();
      public static SLF4JStopWatch getStopWatch() {
            return stopWatch.get();
      }

      
      // for clean up in the out interceptor
      public static void removeWatch() {
            stopWatch.remove();
      }
}

Then in the service implementation of Hello interface:

@Service

public class HelloImpl implements Hello {

      public String sayHello() {
            ServiceTimer.getStopWatch().setTag("sayHello");

            return "Hello!";
      }

      public String sayGoodbye() {
            ServiceTimer.getStopWatch().setTag("sayGoodbye").setMessage("blah!");

            return "Goodbye!";
      }

}


In the end you'll get a two log records like this after the service is executed:

2013-07-27 10:45:45,328 INFO (http-8181-1) (TimingLogger) start[1374939945321] time[7] tag[sayGoodbye] message[blah!]
2013-07-27 10:46:03,565 INFO (http-8181-1) (TimingLogger) start[1374939963562] time[2] tag[sayHello]


See full code example here:
Github

Case # 123403984-1: JavaScript v. JSP

Opening: I've been a back-end developer (database, messaging, services, etc) all of my IT career and only done front-end (web page, scripts, graphics, etc) stuff on my own time. This week, I've exposed myself to more practical HTML, JavaScript and REST services with JSON delivery. I had previously been coding the viewing of the data in JSPs with an MVC format when needed. I've realized that the JSP / MVC model has it's uses, but the flexibility of JavaScript is what drew me in. I really liked how I could separate the presentation layer (what you see on the screen) from the data collection / back-end layer and make reusable services where you could effectively write new pages without disturbing the existing ones or the REST services behind them.

For JSP: I think the largest win here is when your page has a lot of manipulation to do and you want to run that on the server side instead of the client side. I'm sure your server cluster is more powerful and can deliver that page better than a client side rendering. The other argument I think is necessary here is hiding how the page was really built. When I write the JSP, it looks nothing like what is delivered to the consumer as all of the Java is replaced with HTML. I think that is a big positive for JSPs.

Against JSP: With JSPs, I've found that I've been a bit hard pressed to test my pages. To truly find out if my page is working, I have to start up my web app server and try to break it. When using MVC or just a servlet to deliver the page, I've found that I'm locking in the page to be delivered with the service that I just coded.
For JavaScript: In general, you can just do more with the manipulation of the page. This week, I've been able to prevent the default actions on buttons, make AJAX get and post calls, create new HTML and more. Further, with jQuery you can do a lot of JavaScript actions more simplistically. Since it's HTML and script code that is decoupled from the web app server, I can write the code in gedit/Notepad and test in the browser while my web app server is always up.

Against JavaScript: For me, the notation is a bit clunky to get started with. The use of functions compared to Java methods doesn't really match up where it's still called 'Java'. The other draw back is that you have to get used to how a browser processes a page to manipulate it. This is very different for a back-end developer.

Summation: JavaScript is another tool in my box now and I think I might have to use it more than I used JSPs. I do like how I can build those REST services and use them at will. I like how I can develop a new page to replace the old one without disturbing the existing one or writing a new service. Testing is a big win since I don't have to recycle the web app server when I make changes.

Friday, December 28, 2012

WD MyBook Essential in Linux

After some searches on Google, I found the best solution to mount the WD MyBook Essential to my Ubuntu 12.04. First, I'm using the drive over my Network. The drive is connected to my router via USB and accessible to all connecting computers. I'm not using a password to login to the drive.

Procedure:
1) Open a terminal
2) sudo mkdir /media/directory-you-want-to-mount-to
3) sudo gedit /etc/fstab
4) When the gedit window opens, add the following:
//router-ip-address/USB_Storage/directory-you-want-to-mount-from /media/directory-you-want-to-mount-to cifs guest,_netdev 0 0
5) Save
6) sudo mount -a
7) If successful, you should see the drive mounted on you desktop. If not successful, I'm guessing that you'll get a message from 'mount' command. I'd recommend that 'mount -a' works before restarting, you might have issues with logging in if you don't.

Notes:
- I read that '_netdev' is used to wait until the network connection is available to finalize the command.
- If you need a secured login, see http://opensuse.swerdna.org/susesambacifs.html#permsec
- I've recently had to include 'sec=ntlm' before 'guest' above in order to make the connection.  Without it, I was getting an input/output error.

Saturday, December 1, 2012

WAS 8.5

WAS 8.5 for Developers is 2.4 GIGABYTES installed on Ubuntu Linux. That's crazy! Tomcat is, what?, 50 MB.

Sunday, July 8, 2012

WebSphere and Logging

I've recently had some experience configuring WebSphere to use logging other than Jakarta Commons Logging (JCL) that is natively included in WAS.  I found a lot of blogs, forum posts, and tech write ups from IBM on the subject.  None were very satisfactory to me.  Therefore, I set out to find out how it worked.  I created an EAR with three different WARs in it.  Each WAR contained different types of logging that you might use in your application.

Environment
WAS 7.0.0.0 (it's actually WAS for Developers although that shouldn't matter)
Windows 7 64bit
Eclipse Java EE Indigo
Maven 2
Spring 3.0.0

Project Setup
was-logger
-> was-logger-ear
-> was-logger-jcl-war
-> was-logger-log4j-war
-> was-logger-slf4j-war (with log4j as the implementing logger)

I used the Maven project/module model to help build my resulting EAR file and dependency management.

was-logger-jcl-war
This WAR contains only the applicationContext.xml, web.xml, and Spring JARs.
I created a class called LogEvent.  The class is loaded by Spring as a bean and performs a simple loop to display 10 messages.  The point of the loop was to easily find those messages amongst others.


package org.foo.bar.jcl;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

public class LogEvent {

private static final Log log = LogFactory.getLog(LogEvent.class);

public void initialize() {

for (int i = 0; i < 10; i++) {
log.info("Testing commons logging #" + i);
}
}

}


The resulting log records will appear in the SystemOut.log file.  Like this:

[7/8/12 8:12:14:701 CDT] 0000000a LogEvent      I org.foo.bar.jcl.LogEvent initialize Testing commons logging #0
[7/8/12 8:12:14:701 CDT] 0000000a LogEvent      I org.foo.bar.jcl.LogEvent initialize Testing commons logging #1
[7/8/12 8:12:14:716 CDT] 0000000a LogEvent      I org.foo.bar.jcl.LogEvent initialize Testing commons logging #2
[7/8/12 8:12:14:716 CDT] 0000000a LogEvent      I org.foo.bar.jcl.LogEvent initialize Testing commons logging #3
[7/8/12 8:12:14:716 CDT] 0000000a LogEvent      I org.foo.bar.jcl.LogEvent initialize Testing commons logging #4
[7/8/12 8:12:14:716 CDT] 0000000a LogEvent      I org.foo.bar.jcl.LogEvent initialize Testing commons logging #5
[7/8/12 8:12:14:732 CDT] 0000000a LogEvent      I org.foo.bar.jcl.LogEvent initialize Testing commons logging #6
[7/8/12 8:12:14:732 CDT] 0000000a LogEvent      I org.foo.bar.jcl.LogEvent initialize Testing commons logging #7
[7/8/12 8:12:14:732 CDT] 0000000a LogEvent      I org.foo.bar.jcl.LogEvent initialize Testing commons logging #8
[7/8/12 8:12:14:732 CDT] 0000000a LogEvent      I org.foo.bar.jcl.LogEvent initialize Testing commons logging #9


If you have one application in the environment this might be ok. If you want to customize or use different and better loggers, then you'll want to read further.

was-logger-log4j-war
This WAR contains the log4j.xml, commons-logging.properties, applicationContext.xml, web.xml, log4j JAR, and Spring JARs.  I basically created this WAR with the same class, LogEvent, but backed it up with log4j Logger instead of the commons-logging Log class.


commons-logging.properties file contains some information to route commons logging over to log4j.  In other words, Spring uses JCL and the point of the properties file in my WAR is get Spring to use log4j instead.  However, it didn't work from a Spring perspective.  The messages from LogEvent were routed to the file specified in my appender.


2012-07-07 22:04:13,712 [WebContainer : 3] INFO  (LogEvent)  - Testing log4j logging #0
2012-07-07 22:04:13,715 [WebContainer : 3] INFO  (LogEvent)  - Testing log4j logging #1
2012-07-07 22:04:13,715 [WebContainer : 3] INFO  (LogEvent)  - Testing log4j logging #2
2012-07-07 22:04:13,715 [WebContainer : 3] INFO  (LogEvent)  - Testing log4j logging #3
2012-07-07 22:04:13,715 [WebContainer : 3] INFO  (LogEvent)  - Testing log4j logging #4
2012-07-07 22:04:13,715 [WebContainer : 3] INFO  (LogEvent)  - Testing log4j logging #5
2012-07-07 22:04:13,715 [WebContainer : 3] INFO  (LogEvent)  - Testing log4j logging #6
2012-07-07 22:04:13,715 [WebContainer : 3] INFO  (LogEvent)  - Testing log4j logging #7
2012-07-07 22:04:13,715 [WebContainer : 3] INFO  (LogEvent)  - Testing log4j logging #8
2012-07-07 22:04:13,715 [WebContainer : 3] INFO  (LogEvent)  - Testing log4j logging #9


So why didn't it work?  I'm not sure. I think one thing that happens is that Spring attaches to the JCL logger before it gets a chance to hook up with log4j.  There is a part of the ContextLoaderListener to load log4j.  There is also a defined listener to load you log4j configuration.  I haven't played with that, but I fear that it is only really going to apply to Spring.  What about other frameworks (like CXF) that use JCL as well?  Read on.

was-logger-slf4j-war
This WAR contains the log4j.xml, commons-logging.properties, applicationContext.xml, web.xml, log4j JAR, slf4j JARs and Spring JARs.  There is also another JAR that seems to be key, jcl-over-slf4j-1.6.6.jar.


When the slf4j logging facade is used on top of log4j, Spring and my application information are routed to the file defined in my log4j.xml file.

2012-07-07 22:04:14,143 [WebContainer : 3] INFO  (ContextLoader)  - Root WebApplicationContext: initialization started
2012-07-07 22:04:14,291 [WebContainer : 3] INFO  (XmlWebApplicationContext)  - Refreshing Root WebApplicationContext: startup date [Sat Jul 07 22:04:14 CDT 2012]; root of context hierarchy
2012-07-07 22:04:14,486 [WebContainer : 3] INFO  (XmlBeanDefinitionReader)  - Loading XML bean definitions from class path resource [applicationContext.xml]
2012-07-07 22:04:14,778 [WebContainer : 3] INFO  (DefaultListableBeanFactory)  - Pre-instantiating singletons in org.springframework.beans.factory.support.DefaultListableBeanFactory@56c556c5: defining beans [logEvent]; root of factory hierarchy
2012-07-07 22:04:14,863 [WebContainer : 3] INFO  (LogEvent)  - Testing slf4j logging #0
2012-07-07 22:04:14,863 [WebContainer : 3] INFO  (LogEvent)  - Testing slf4j logging #1
2012-07-07 22:04:14,863 [WebContainer : 3] INFO  (LogEvent)  - Testing slf4j logging #2
2012-07-07 22:04:14,864 [WebContainer : 3] INFO  (LogEvent)  - Testing slf4j logging #3
2012-07-07 22:04:14,864 [WebContainer : 3] INFO  (LogEvent)  - Testing slf4j logging #4
2012-07-07 22:04:14,864 [WebContainer : 3] INFO  (LogEvent)  - Testing slf4j logging #5
2012-07-07 22:04:14,864 [WebContainer : 3] INFO  (LogEvent)  - Testing slf4j logging #6
2012-07-07 22:04:14,864 [WebContainer : 3] INFO  (LogEvent)  - Testing slf4j logging #7
2012-07-07 22:04:14,864 [WebContainer : 3] INFO  (LogEvent)  - Testing slf4j logging #8
2012-07-07 22:04:14,864 [WebContainer : 3] INFO  (LogEvent)  - Testing slf4j logging #9
2012-07-07 22:04:14,886 [WebContainer : 3] INFO  (ContextLoader)  - Root WebApplicationContext: initialization completed in 740 ms


Conclusions
I like my logging configurable outside of the WAS Admin Console.  In most production environments, you're not going to have any kind of permissions to change items in the Admin Console.  Then you would have to engage someone in a support area who does have access and they might not be as up to date on your application and what your request is.  Log4j and slf4j give you greater flexibility in defining your logging solution.  I like the slf4js ability to route any framework over to the log4j configuration.

Appendix - Class Loading
This discussion wouldn't be complete with some mention of class loading.  A lot of posts I saw mentioned that setting the class loader to PARENT_LAST,  I have done that for another application for the purposes of CXF, but for this test application, I did not.  Therefore, you can get different logging without changing the classloading order.

I've posted the code at the following link. was-logger

Wednesday, July 4, 2012

DSL

I've been an AT&T DSL customer since 2001. At that time it was with SBC in the Kansas City area. I have a @swbell.net email address to this day. When it was initially rolled out it was $49.95 1 year contact for 1.5 Mbps down. Over time that price went down. I think it took 3 years to get a price break.

Now, it's $43 for existing customers on 6 Mbps no contract. They've raised the price the past couple of year's a dollar here and two dollars there. The reason they give is the same. Something to do with keeping up with market conditions.

To be fair they do include WI-FI at Starbucks, McDonald's, etc for when you use a laptop. For me though that doesn't happen often enough to pay for it included in the $43. Further, you can't separate the two  features.  I suppose that's because most people would separate the two and no one would pay for it.  Then they'd have to drop the feature.

I'm leaving you, AT&T, for Comcast.  I can't ignore the short term deals and the chance to compete for my business with deal negotiation.  I found a two-year contract @ $39.99 for the first 12 months and $56.99 for the second 12 months for phone and internet.  In the end, with taxes, I'll still end up paying less for faster internet (max 20 Mbps!) and the same phone features.  Install is on 7/10.  My wife has put me in charge of this task to switch over.  Which means that not only do I have to monitor the install and make sure everything works just as it does currently, I'll also be the complaint department when it doesn't work right.

Monday, July 2, 2012

iPhone and Gmail

I use my iPhone to manage personal appointments much as one would use their corporate mail server to manage meetings.

My wife and I have Gmail accounts. Our phones are both set to use gmail as an Outlook Exchange server. What that extra distinction allows for is the ability to send and receive calendar entries and accept or deny them as you would within an outlook client on your computer.

When my wife has an appointment she invites me to it and it appears in my calendar after I accept it, for example.

The limitations are that 1) your mail server (e.g. Hotmail, Yahoo, etc) has to support Microsoft Exchange and 2) the scheduler has to know that ahead of time. It's works really well with my wife and I though.

Log4j dynamic log level changes

Recently, I've been working with a colleague on implementing a solution to use Spring JMS to pass messages to other JVMs in a clustered environment for the purpose of setting log4j logging levels to something else.  For example, by configuration file, I've got 'org.foo.bar' logger set to level INFO.  I've found that during some production issue I need to set 'org.foo.bar' to level DEBUG.  Without redeploying the application, I want to set that level for every JVM in my cluster.  I don't want to have to go to each JVM and set that level I want to go to one and let the application handle the rest.

We're using WebSphere 7.0 for z/OS and taking advantage of the included SIBUS. SIBUS is an all java implementation of MQ. I don't believe it is as robust as MQ, but for this purpose it is good enough.

This solution was chosen over others because it can all be implemented within our application except for the SIBUS configuration. We discussed using JMX, but found that we would have potential security limitations. Further we could switch out SIBUS for MQ if need be without application changes.

The solution includes a JSP page to display and set the different log levels for each logger defined. The page reads the loggers that are defined at runtime and code time. The server processes requests from the JSP and builds the message to be processed. A listener processes the message in each JVM to update the logger.

A challenge we ran across was that in WAS z/OS the messaging bus runs as a parallel task (adjunct) to the application  server (servant).  Those tasks start in parallel when a bounce of the server is performed.  We discussed with IBM the possibility of existing implementation to serialize those start ups such that the adjunct starts before the servant.  They didn't have that as a current implementation and suggested that we open an enhancement request.  The challenge is that Spring JMS is looking for the messaging bus to be active during startup.  If the messaging bus is not active, Spring JMS will try to refresh the connection at intervals that you set.  The key to all of this is that Spring JMS run in a separate thread than the thread that is used to start the application context.  If they run in the same thread and the messaging bus is not found on a bounce, the application will fail to start.  IBM recommended some code that is part of their documentation to search for the messaging bus and delay further processing until it is found.  The logic is WebSphere specific and we wanted to remain platform agnostic.

Follow the information in this developerWorks article to a tee and you should have no issues.

http://www.ibm.com/developerworks/websphere/techjournal/0609_alcott/0609_alcott.html

Credit to Srini Ivaturi for this solution. It was his design. I helped with the implementation.