I'm starting a project and I thought I'd document parts of it as I go along. So this isn't a treatise on server side Java so much as a rebuttal by example.
See, I once worked for a company that asked me and two other developers to start building the next generation of their flagship product. They wanted web services with a browser-based user interface, and it fell to the three of us to decide on the technologic and architectural direction. I came to the meeting expecting to walk back out with a charter to build a set of SOAP services implemented using Java.
Fortunately, one of guys suggested I look into REST. That turned out to be a huge pivotal moment, and the services layer I produced was elegant and easy to consume. Thank goodness for that, because the other major decision that came out of those meetings was, in my humble but experienced opinion, a disaster.
These other two developers -- good friends and respected colleagues -- advocated using Embarcadero's Delphi (it's a Delphi shop) over switching to Java and using off-the-shelf technologies. For context, this discussion was about 8 years ago. Their argument? "Java is dead."
Because I was voted down, I had to use Delphi Pascal to roll my own REST services, cross-database persistence layer with data dictionary and SQL generation, and the tools and test suites for each. Keep in mind this was 8 years ago. The REST facility and JSON library in Delphi was utterly broken, so badly that no one was using them and Embarcadero didn't bother to bring them up during conferences, so I couldn't rely on those. It took quite a while and, when viewed from a company perspective, very expensive in terms of time and money. Don't get me wrong, I'm supremely proud of the product that we built, but that time could have been spent somewhere else.
Add to that the fact that Delphi developers are an increasingly rare breed, whereas, thanks to Java's huge (and still growing) market share, you can't walk down a busy sidewalk of a major city swinging your arms without hitting a Java programmer. They spent more on developers and couldn't ever get enough of them because of that fateful decision. (Just recently they began investing in inexperienced H1B employees fresh out of college and firing all of the people that had 10+ years of experience, a move which may very well end up sinking that company... but I digress...)
After developing the REST services and the business object framework, I kind of hit a wall. There weren't any other fun projects at the company. I was leery of relying on Delphi for anything anymore because *that* is a dying system, and frankly at my age I thought it best to try to move into management. To be fair, the company tried to throw me a bone, but there weren't any real management positions to speak of that were available, and eventually we parted ways. Which turned out great for me. I'm still doing what I love, and making a good living at it.
So this project is my way of showing that, yes, the development would have been faster, more functional, and would have supported more operating systems. I mean, hell, if you do it right you can run a JVM with J2EE containers on an Android cell phone or a Raspberry Pi. It scales easily, and moving it to a Linux instance on cloud services is trivial.
August 1st, 2016: Setup
After thrashing around a bit doing some research, I decided to go with a development environment that I'm not entirely experienced with but am comfortable in. On a Windows 10 laptop, I installed VMWare 12 (which those developers also said was a dead product... smh...) and created a Mint VM. I dropped in the latest Eclipse and Tomcat 9, and started up a project using JAX-RS for REST support and JPA as the persistence framework. Most of the startup headache came from getting Eclipse to debug in Tomcat. Which still isn't working... But it compiles the WAR file and drops it in the right location, and Tomcat picks it up, so there's that. Minus the setup, it took me about 30 minutes to create my first REST service persisting customer data.
To compare and contrast, it took 6 months to get the basic framework and tool chain for the Delphi REST services stabilized and capable of performing the same function.
November 27th, 2017: Framing
So things got busy, I had to put this aside, and over a year later, about two weeks ago, I finally picked this back up in earnest. And now I've got a JAX-RS application started that can read and write data REST-fully. I messed around with a couple of "plug and play" REST frameworks, only to find that they were over-simplified or just did REST wrong. And, really, they just exist to cut out a few steps but, given the difficulty in setting them up and getting them functioning, it seems like a false economy.
A large part of the time over the last two weeks was just spent getting my IDE set up. After a lot of trial, error, and Stackoverflow, I can now setup an environment using Eclipse, Tomcat, and MySQL in no time, create Dynamic Web Application project in Eclipse, convert it to a Maven project, add the JAX-RS facet, update the Maven pom.xml with the dependencies I need, and I'm off to the races. And I got the debugging thing worked out.
Total time required for environment set up: About 2 hours.
At this point I've built a small framework for resources, data access objects, an XML driven data dictionary, and beans that requires minimal code to add a new resource. My next step is to build a small utility to display the hundred-plus tables I've designed into my schema in a list, allow me to select the ones I want to support (all of them) and generate the initial code for them. And yes, that would be MUCH faster than going through the list one at a time building the code.
Total time required to design and implement database schema and code up a framework for basic XML-configured resources: About 2 weeks. As opposed to months re-inventing the wheel in Delphi back in 2009. And, since I'm using Tomcat, I can use Struts 2 to define some pretty slick server side functionality for the UI. All with the ability to deploy the application on any operating system that will support a J2EE container. Not only are the off-the-shelf possibilities endless, but if I need some help, finding a competent Java developer will be easy and quite probably cheaper than it is to find competent Delphi help.
I recently set out to hire a subcontractor for Delphi work, only to find that the only viable candidate that contacted me wanted more per hour than I was charging. Don't get me wrong, he's really good and probably worth it, but it was an eye opener and confirmed my position that the decision on choosing a software development technology should be based in part on industry support for that technology -- how easily can you hire resources knowledgeable in that technology.
December 7th, 2017: Resource Generation
After getting back from spending a week in Hawaii, and all the preparation beforehand that the trip required, I got back into this and immediately focused on a utility to generate resources. In my TGEdit utility, I completed, in about 4 hours, a utility that will read the schema for an existing table and generate the Java and data dictionary XML to support it. I then copy the generated files into the correct directories, recompile Silverboat, and run.
That's it. With a 4 hour investment, I'm now supporting 188 resources. Not bad. If I was really going to get fancy, I'd have created a data dictionary utility that could create/update the schema, especially since, before I'm done, I'll have to modify the data dictionary descriptions to set some of the flags that have nothing to do with the physical layer, but since I already have a schema in place this was the fastest path for this project.
Truth is, I have a highly sophisticated data dictionary utility already built into TGEdit, but I'm not using that for this project yet, because TGEdit expects all the DD configurations to be stored in a single library file. Which is great if you want to prevent someone from tinkering with your meta data, but it means more work, and I'm short-pathing this as much as possible.
December 17th, 2017: Framework completed and functional
Had to step away for a few days to get caught up on some stuff, but over the last couple of days I found a few hours to complete the framework. It now successfully implements a very simple, streamlined, near-RESTafarian REST interface with the just the verbs to support CRUD: POST, GET, PUT, and DELETE, respectively. For GET, it supports URL parameters "cols" to control the columns returned, "filters" to specify one or more filter criteria, "sorts" to control data order, and "start" and "maxrows" for pagination.
As I mentioned in my last entry, I had built a code generation utility to generate the resource classes. While debugging the interface, that utility ended up saving me hundreds of hours. To allow me to continue using that facility, should I ever need it, I'm plan to make a small change in the abstract resource class to allow me to implement business rules and validations as decorator classes, keeping them separate from the job of wiring URL segments to the abstract resource logic.
I also implemented a simple login mechanism. I'm going to skip implementing SSL/TLS for now (I'm not storing customer data or state secrets) and instead jump straight to modifying an existing application to use Silverboat to mirror some tables. That's going to take a little while. This application has been around for 15 years, and some of the third party components have been end-of-lifed or their companies have gone out of business, so I can't migrate the application to a modern development environment with a high amount of pain.
December 29th, 2017: Calendar reporting
Merry Christmas!! The break from programming was a welcome one. Now I'm back in the game and burning up the keyboard.
One of the reasons I started to attack this project with gusto was because I came up with a use for it. I wrote a simple point of sale system for salons a long time ago, and I had always intended to push some of the data up to a network server to make the appointment book accessible via browser. Well, I finally got around to it.
Copyright (c)2016, 2018 Todd Grigsby, all rights reserved