tag:blogger.com,1999:blog-37633946778315651272024-02-19T08:40:14.411-08:00["rogiller", "blog"]Roger L. Dillerhttp://www.blogger.com/profile/02943467573406524963noreply@blogger.comBlogger25125tag:blogger.com,1999:blog-3763394677831565127.post-20239258661264750472019-07-15T10:53:00.003-07:002019-07-15T11:35:39.272-07:00Simple REST Api Throttling in Spring BootA couple weeks I set out to implement some basic sanity REST Api Throttling for our Spring Boot application at work... turns out it was much more of a rabbit hole than I expected. I wish I could expand on why in great detail, but I my time to write is limited at the moment.<br />
<br />
I recommend this "Stop Rate Limiting! Capacity Management Done Right" talk to get your head around the problem domain: <a href="https://www.youtube.com/watch?v=m64SWl9bfvk">https://www.youtube.com/watch?v=m64SWl9bfvk</a><br />
<br />
TL;DR; of the video:<br />
<ul>
<li>Key takeaway: <b>Limit concurrency, not request rate</b></li>
<li>Throughput != capacity</li>
<li>It's really hard to know the true capacity of a service</li>
<li>Learned about Little's Law <a href="https://en.wikipedia.org/wiki/Little%27s_law" target="_blank">https://en.wikipedia.org/wiki/Little%27s_law</a></li>
</ul>
My initial implementation was just a Guava <span style="font-family: "courier new" , "courier" , monospace;">RateLimiter</span> per subdomain (aka tenant). After watching the above video and reading various articles on the internet, I landed on the implementation below which uses a <span style="font-family: "courier new" , "courier" , monospace;">Semaphore</span> and <span style="font-family: "courier new" , "courier" , monospace;">RateLimiter</span> per subdomain:<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
</div>
<div class="separator" style="clear: both; text-align: center;">
</div>
<div class="separator" style="clear: both; text-align: center;">
</div>
<div class="separator" style="clear: both; text-align: center;">
</div>
<div class="separator" style="clear: both; text-align: center;">
</div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh8dSV7udG2SXQCC4FQj9Z00GyA7nyJqhyphenhyphenqwfXgiTiCKTkxoK6YC7o4xVx7aM7-5E5tacHM1YBIAO0-Hv1gFvqHI6sQGmHECSvd6ibWw4cy5DRBj8123qSbUY9mDycyc8ZPgjpT_S9KIc53/s1600/api-filter4.png" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" data-original-height="718" data-original-width="550" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh8dSV7udG2SXQCC4FQj9Z00GyA7nyJqhyphenhyphenqwfXgiTiCKTkxoK6YC7o4xVx7aM7-5E5tacHM1YBIAO0-Hv1gFvqHI6sQGmHECSvd6ibWw4cy5DRBj8123qSbUY9mDycyc8ZPgjpT_S9KIc53/s1600/api-filter4.png" /></a></div>
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<b><br /></b>
<b><br /></b>
<b><br /></b>
<b><br /></b>
<b>Points on the Implementation Above</b><br />
<ul>
<li>This <span style="font-family: "courier new" , "courier" , monospace;">RateLimitFilter</span> is at the very top of the stack (aka it's registration order is zero) so that no unnecessary throw away work is done in the case of a service denial</li>
<li>It is registered in our <span style="font-family: "courier new" , "courier" , monospace;">WebApplicationConfig</span> class via an <span style="font-family: "courier new" , "courier" , monospace;">@Bean</span> method that returns a <span style="font-family: "courier new" , "courier" , monospace;">FilterRegistrationBean</span> (see image below)</li>
<li>The <span style="font-family: "courier new" , "courier" , monospace;">Semaphor</span> acts as a "Leaky Bucket" in queue theory</li>
<li>The Guava <span style="font-family: "courier new" , "courier" , monospace;">RateLimiter</span> acts as the mechanism to keep requests per subdomain flowing at a consistent rate (which can cause the <span style="font-family: "courier new" , "courier" , monospace;">Semaphor</span> to "fill up" and deny requests</li>
<li>The filter sends a HTTP Error 429 if there are too many concurrent requests. <b>Be sure you have an external integration test against a live environment that can actually produce 429 failures!</b></li>
<li>Our production cluster is 3 VM's, so <b>per tenant</b> it effectively allows 30 concurrent requests at a stable rate of 12 requests per second <b>per tenant</b>.</li>
</ul>
<div>
This is in our <span style="font-family: "courier new" , "courier" , monospace;">WebApplicationConfig</span> class:</div>
<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjjsIZ7AYq9sG08WXH2oQC27JcD6UnZ0MrAUYXb24hvHz0D9ZqTUd4fPl2fBnNUf_x8fRpO6ZUFzcJrOiMeXSg4PewGQ4wvQVMIwmEBy3-yXSziJJWV-AqXAtqWAPcIa2sXO6ouijxD-ojK/s1600/Screen+Shot+2019-07-15+at+1.23.34+PM.png" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" data-original-height="356" data-original-width="1028" height="137" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjjsIZ7AYq9sG08WXH2oQC27JcD6UnZ0MrAUYXb24hvHz0D9ZqTUd4fPl2fBnNUf_x8fRpO6ZUFzcJrOiMeXSg4PewGQ4wvQVMIwmEBy3-yXSziJJWV-AqXAtqWAPcIa2sXO6ouijxD-ojK/s400/Screen+Shot+2019-07-15+at+1.23.34+PM.png" width="400" /></a><br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<b>Why I put the Api Throttling inside Spring Boot app vs somewhere "above the application"</b><br />
<ul>
<li>I wanted the "origin service" (aka our Spring Boot app) to have some "built in" self protection even if we eventually better protection "above the app"</li>
<li>Since the implementation is per subdomain (aka tenant), I have all the control right in the code base for easy tweaking/deploying later</li>
<li>We want to tie the # of Api Requests into a billing plan down the road. My assumption was this would be easier to do inside Spring Boot.</li>
</ul>
<div>
That's all I have for now. What do you think? I'd love to hear your feedback on this implementation and/or how you have solved this problem at your organization.</div>
<br />
<br />Roger L. Dillerhttp://www.blogger.com/profile/02943467573406524963noreply@blogger.com0tag:blogger.com,1999:blog-3763394677831565127.post-68244692423729576512018-11-24T14:39:00.002-08:002018-11-24T14:39:29.841-08:00Out with the Old, In with the NewSo I've had this old Drupal 6 website setup for <a href="http://rogerdiller.com/">rogerdiller.com</a> since 2009. It was built & designed for a very different time in my career. Back then, I was trying to attract consulting offers via the contact form. Now days, I would not consider consulting. Period. I have more than enough to do at my day job.<br />
<br />
My website provider has continued to raise prices on me for the last few years since I needed some kinda "extended PHP 5.2 support". I finally decided to today that I've "had enough". I stopped the website hosting contract and moved my domain to a simple "domain only" contract. I setup a simple <a href="https://about.me/">https://about.me</a> page for my basic info and redirect my <a href="http://rogerdiller.com/">rogerdiller.com</a> domain to that now.<br />
<br />
Gah, this is so much simpler (and boy, do I love simple). No more mind bending Drupal upgrade jazz to worry about and really, there is nothing to maintain or worry about now. Besides just making sure my <a href="http://rogerdiller.com/">rogerdiller.com</a> is on auto renew, which it is.<br />
<br />
I also revamped the theme on this blog. Now, to just develop a more regular blogging habit...Roger L. Dillerhttp://www.blogger.com/profile/02943467573406524963noreply@blogger.com0tag:blogger.com,1999:blog-3763394677831565127.post-66615904526064751912017-09-30T06:58:00.000-07:002017-10-06T07:35:48.525-07:00Statement on ExtJSIn late August the <a href="https://www.sencha.com/blog/exciting-news-sencha-acquired-by-idera-inc/" target="_blank">news</a> came out that Sencha was acquired by a company called IDERA. When I first saw the email, I was shocked & confused at the news. Was this a good thing or bad thing? I spent the following weekend googling for info on the internet, reading tweets, etc to try to figure out what it meant. There were rumors the engineering team was being let go, but nothing was conclusive and it remained that way for a few weeks.<br />
<br />
In the last week or so it has become abundantly clear. The Sencha engineering team has been let go. The evidence was all the Sencha engineers announcing their last day on social media.<br />
<br />
I work at <a href="https://www.flexrentalsolutions.com/" target="_blank">Flex Rental Solutions</a>, and we bought into ExtJS and its "one platform, no dependencies" philosophy a couple years ago. We are rewriting our Adobe Flash app starting with mobile first with plans to move onto desktop next year. We've had great success with our mobile app using the toolkit.<br />
<br />
However, with the news that the Sencha engineers are gone, we are seriously questioning whether we will stick with ExtJS. Our mobile product is about to ship, so we are not going to pivot for mobile in the foreseeable future BUT we are considering alternatives for desktop. We have been banking on the "modern" toolkit to get fully up to par with the "classic" toolkit (presumably in the 7.0 release). We want to be able to build phone, tablet, and desktop with a single toolkit and codebase, and do not want to use the "classic" toolkit (since it's basically the legacy toolkit). With the Sencha engineers gone, the "modern" toolkit parity seems highly unlikely to happen, at least on a timeline that works for us.<br />
<b><br /></b>
ExtJS is a great BUT highly unused framework these days. Nobody really talks about it in the tech community, at conferences etc. It's sad ExtJS is such a great framework that almost nobody has heard of. I fully believe that is due to bad management of the toolkit, and not the toolkit itself. Here are some of my recommendations to give ExtJS a shot at becoming relevant again:<br />
<b><br /></b>
<b>ExtJS should be free</b><br />
<b><br /></b>
Charging for the framework at all is just completely misguided. Even worse, you have to start with a 5 developer license pack. That pretty much rules out all the individual developers and anybody just looking to get an app off the ground. There is nothing wrong with having a company behind it (that makes money), but it should make money off support of the framework and other value added tooling, services, etc.<br />
<br />
<b>ExtJS should be open sourced</b><br />
<b><br /></b>
With ExtJS engineers gone, the only future ExtJS has is to be open sourced. Otherwise, the toolkit is just going to die. ExtJS is an incredibly powerful and complex toolkit. IDERA is kidding themselves if they think they can just pick up things where the Sencha engineers left off. Open it up to the community, and ExtJS actually has a shot at competing with the likes of React, Angular, Vue.js etc.<br />
<br />
<b>ExtJS needs to embrace mainstream JavaScript</b><br />
<b><br /></b>
It's been frustrating to me that ExtJS doesn't embrace the JavaScript ecosystem in terms of tooling and access to 3rd party JS libraries. ExtJS should just be a dependency that is declared in a NPM "package.json" file with build support via mainstream tools (such as Babel & Webpack). I know ExtJS likes to promote "one platform, no dependencies", but c'mon, sometimes you just want to bring in a node module that helps you do String manipulation or a multitude of other non-UI JavaScript operations that is not included in ExtJS or JavaScript.<br />
<br />
<b>What We'll Do at Flex Rental Solutions</b><br />
<b><br /></b>
Basically if full "modern" toolkit parity doesn't come out by early 2018, we will be forced to ditch ExtJS for desktop. This means that when our annual subscription comes around in June 2018, we will NOT be renewing. We have everything we need to build mobile in 6.2 & 6.5, so there will be no point in us renewing. We are already putting together a Plan B. We can already see there is viable path for us with React and mainstream JavaScript.<br />
<b><br /></b>
<b>Summary</b><br />
<b><br /></b>
So IDERA, are you going to make the right choices? There are tons of other companies banking on modern toolkit parity and for ExtJS to embrace mainstream JavaScript. You will see companies leaving in droves for React/Vue.js etc if you make the wrong choices. ExtJS is a fantastic piece of software. Please do what's best for ExtJS and all its dedicated developers.<br />
<br />
<br />
<br />
<br />
<br />Roger L. Dillerhttp://www.blogger.com/profile/02943467573406524963noreply@blogger.com0tag:blogger.com,1999:blog-3763394677831565127.post-52663892007705614632017-04-15T14:30:00.002-07:002017-04-15T15:33:00.556-07:00Why ExtJS UI Testing is HardConsider this simple ExtJS modern toggle field declaration below.<br />
<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhEH96U4v92Ke-N69vYDVoUGzjLY8akPP42E-BnwLKdT5Ui6kAhNDVcHS5cYBPr1rD_9AiEeUrgGCOlciEg_O8DGQdPtkvmtvhmJA-29jvTxi8fVOVr-PahFTnJQOM7YDBM_RRMEvRC21bf/s1600/extjs-toggle-field.png"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhEH96U4v92Ke-N69vYDVoUGzjLY8akPP42E-BnwLKdT5Ui6kAhNDVcHS5cYBPr1rD_9AiEeUrgGCOlciEg_O8DGQdPtkvmtvhmJA-29jvTxi8fVOVr-PahFTnJQOM7YDBM_RRMEvRC21bf/s640/extjs-toggle-field.png" /></a><br />
<br />
The above ExtJS code results in the following UI rendering display in a browser.<br />
<div>
<br />
<div>
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjKbsgzv8n2rSn5z-qpQO3ANGs3qR49J0OhDDaeTlER11rz5gy9dfOy52UqPvpTq2jZju8GMY20OPEedvNOhQhSRuGdfrGzx6eMKTJuAcQ7A1-rMeqGwa3YSCuQYFpmRtzXCySbMruzTDJn/s1600/togglefield.png"><img border="0" height="77" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjKbsgzv8n2rSn5z-qpQO3ANGs3qR49J0OhDDaeTlER11rz5gy9dfOy52UqPvpTq2jZju8GMY20OPEedvNOhQhSRuGdfrGzx6eMKTJuAcQ7A1-rMeqGwa3YSCuQYFpmRtzXCySbMruzTDJn/s320/togglefield.png" width="320" /></a><br />
<br />
Now, consider the HTML output from that simple ExtJS declaration:<br />
<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgC6so2CloVLiaeo4JOmA2qdOevLohoRmtTE3Ems-bws205F9NwHuAWcF6TIXzzhMmW0HDCGedd5YrFyMrnbgeqmHWsdQYCrSQossI6ub-0CNyCW4eHASv8ddIffyAFRhmQzcZxD5T1AvYR/s1600/Toggle-Field-No-Id.png"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgC6so2CloVLiaeo4JOmA2qdOevLohoRmtTE3Ems-bws205F9NwHuAWcF6TIXzzhMmW0HDCGedd5YrFyMrnbgeqmHWsdQYCrSQossI6ub-0CNyCW4eHASv8ddIffyAFRhmQzcZxD5T1AvYR/s640/Toggle-Field-No-Id.png" /></a><br />
<br />
Yeah, crazy. The reason for this HTML craziness is <b>because ExtJS does dynamic rendering</b>. You declare some simple JavaScript code, and it takes care of the rest, including making it look the same across browsers. In order to do that, the HTML it emits can be different from browser to browser. Essentially ExtJS is a <b>web abstraction layer</b> that takes care of rendering so you can focus on building your app.</div>
<div>
<br /></div>
<div>
Now, that is just a simple toggle field component. Enter an advanced data grid with lots of rows or a tree with lots of nodes and the HTML is going to explode way beyond what's shown above for the toggle field.</div>
<div>
<br /></div>
<div>
<b>Trying To UI Test this Jazz with Selenium</b></div>
<div>
<b><br /></b></div>
<div>
Selenium is designed to interact with DOM elements. It has different mechanisms to locate elements. The most reliable way to select a web element is by something unique such as an element id. However, in the case of ExtJS, developers are not supposed to set the "id" property as a potential duplicate "id" could crash or at least mess up the app. We can set the "itemId" in the ExtJS code, however that doesn't come through to the DOM at all. As a side note, I would like to know why ExtJS doesn't emit the itemId in some way to the DOM? If Sencha would change ExtJS to emit the itemId somehow into the DOM, locating unique top level div elements would be so much easier!</div>
<div>
<br /></div>
<div>
However, even if we did hard code the "id" or create a way to resolve the ExtJS itemId to an actual id (which is possible via JavaScript by calling the ExtJS component query Api), and it came through to DOM, there is a new problem. Take the toggle field example above. The "id" would resolve to the top level div with an id of "ext-togglefield-3". That is just the top level wrapper div for the form field and doesn't give us the id of the actual slider component. It's a couple div's down and nested a bit, with an id of "ext-toggleslider-3". This is completely dynamic HTML and there isn't any way to hard code that "id" even if I tried. Essentially, it's "inside" and unreachable from my ExtJS JavaScript declaration above.</div>
<div>
<br /></div>
Knowing the top level div id does help some, because then you could use Selenium look it up by id and then use a CSS selector and look for an "div.x-toggleslider" class inside that top level element. But this process is going to be different for every ExtJS component and is subject to change from version to version. Here is some Selenium Java code that would click on the toggle field above:</div>
<span style="font-family: "courier new" , "courier" , monospace;"><br /> //For purposes of illustration, assume the toggleFieldId below </span><br />
<span style="font-family: "courier new" , "courier" , monospace;">//was resolved in a reliable way and not hard coded!<br />//e.g. this toggleFieldId could be resolved via ExtJS itemId by<br />//invoking ExtJS JavaScript code<br />String toggleFieldId = "ext-togglefield-3";<br /><br />//get top level field by the resolved id<br />WebElement toggleField = driver.findElement(By.id(toggleFieldId));<br /><br />//now select actual clickable slider by CSS selector on <br />//the toggle field element<br />WebElement toggleSlider = toggleField.findElement(By.cssSelector("div.x-toggleslider"));<br /><br />//Now click the toggle slider<br />action.moveToElement(toggleSlider).click().build().perform();</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"><br /></span>
The code above will actually work. However, we have to dance down through a top level ExtJS component div and select the "real" clickable components inside it via CSS selectors to get to the real thing. This is going to vary greatly from component to component and could change from version to version. <br />
<br />
<div>
<div>
<b>Use a UI Test Tool Designed for ExtJS [like Sencha Test]?</b></div>
<div>
<b><br /></b></div>
<div>
It seems this dynamic rendering craziness is why tools are created to help UI test ExtJS. Sencha built their own tool called "Sencha Test" which basically takes away all the DOM selection grunt & guess work away by creating an Api to select and manipulate components. The Sencha Test equivalent of the above code would be this:</div>
<br />
<span style="font-family: "courier new" , "courier" , monospace;">ST.field('#tablet-inventory-model-view-expendable')</span><br />
<span style="font-family: "courier new" , "courier" , monospace;">.setValue(true);</span><br />
<div>
<span style="font-family: "courier new" , "courier" , monospace;"><br /></span></div>
The "#tablet-inventory-model-view-expendable" above is an itemId we set on the ExtJS side and then from Sencha Test you can just target that direct and reliable itemId and set the value to true! That's it! You don't have to worry about figuring out the correct top level id and then finding the "real" clickable component via a CSS selector like my Java code example earlier.<br />
<br /></div>
<div>
This is just a simple example and as you can imagine, with data grids, trees, etc, the complexity is going to explode. With growing complexity, Sencha Test is going to shine even more.</div>
<div>
<br /></div>
<div>
<b>So What Do You Do?</b></div>
<div>
<b><br /></b></div>
<div>
My team is still trying to figure that out. We'd love to use tools that are agnostic of the underlying web framework, however it's just highly complicated and frustrating dealing with dynamic DOM output from ExtJS. We are giving Sencha Test a look over as it appears to make life much easier, but it's own animal and you'd need to learn it's Api and ways of doing things.<br />
<br />
I'll try to write another blog post in the future once we figure out our approach. Stay tuned!<br />
<br />
If anybody has any ideas they'd like to share on how to UI test ExtJS, please comment below! Cheers!</div>
Roger L. Dillerhttp://www.blogger.com/profile/02943467573406524963noreply@blogger.com1tag:blogger.com,1999:blog-3763394677831565127.post-2251465374728008172016-02-03T19:37:00.000-08:002016-02-03T19:37:03.489-08:00Video Chat == Trust<b>This post is written from the context of remote teams. If you are in the office with your co-workers it's not as applicable.</b><br />
<br />
Everybody instinctively seems to know that when you get in the same room as your co-workers, you get more accomplished in terms of planning & strategy.<br />
<br />
Why is that?<br />
<br />
You have the same voices that you do on the phone. You can create a group conference call and discuss with your voices just like you do in a room.<br />
<br />
But everybody knows it's not the same. In person communication always works better.<br />
<br />
But why?<br />
<br />
Because eye contact and body language. When you only have voice, you have a small fraction of the data that you do in person. This makes it much harder to get your points across because you're unable to tell if your listeners are understanding, connecting, objecting, etc. Not to mention you don't have nice collaborative things like whiteboards.<br />
<br />
But yet people are still resistant to video chats. Video chats allow a much greater percentage of communication data to flow (vs just voice) thus allowing much more productive meetings. But it puts people out of their comfort zone so they would sooner not do it.<br />
<br />
This frustrates me (but I do empathize with those who object... more on that in bit).<br />
<br />
We are human, people. We connect via eye contact and body language. This creates trust & connection.<br />
<br />
Trust. This is probably the most important word for remote teams.<br />
<br />
Without trust, a team is dysfunctional.<br />
<br />
Why in the world in these days of modern technology would we cut off the most vital means of communication data when we don't have to?<br />
<br />
To me, not using video in this modern age of 2016 is equivalent to being in your office with your door shut and talking to a person outside in the hall with just voice. How silly would that be? But yet we refuse to do video because it makes us feel uncomfortable.<br />
<br />
Bottom line, it's because of fear. We are scared to look someone in the eye via video because it puts us out of our comfort zone. I've been there. There was a time when I was literally freaked to even think about turning on my video. I think I may have broke out in a sweat at times just thinking about it.<br />
<br />
But eventually I started trying it. And it was super uncomfortable.<br />
<br />
But eventually it got better. After you do this for a while, you'll begin to wonder why in the world you were so resistant.<br />
<br />
However don't take my word for it... just google "successful remote teams" and see how many articles mention video chat. It IS a critical part of remote team success.<br />
<br />
Conquer your fears. Do video chat with your remote co-workers. Build trust. You'll thank me someday. :)Roger L. Dillerhttp://www.blogger.com/profile/02943467573406524963noreply@blogger.com0tag:blogger.com,1999:blog-3763394677831565127.post-50250408863859038312016-01-26T06:28:00.001-08:002016-01-26T06:28:10.269-08:00Leadership == CommunicationA question I've often pondered is "what is leadership"? Is it a state, is it making decisions, is it a title, is it management?<br />
<br />
Turns out I don't think it's really fundamentally any of those. One thing I have discovered for certain, you don't need a "leadership" title to be a leader.<br />
<br />
If you are reading this, you are a leader in some form. You might be the newest person in your company but you can lead in some way.<br />
<br />
When I break down leadership to it's most basic element, I come up with one word.<br />
<b><br /></b>
<b>Communication.</b><br />
<br />
And really, what is communication? It is information sharing. As a leader, to facilitate communication, you have to ask questions. And then listen... like a lot. You have to deeply absorb what people around you are saying. Once you've done that, you will eventually get to the point where you begin to come up with suggestions and solutions to solving the problems around you.<br />
<br />
Leadership is having the audacity to be vulnerable. It means once I've communicated with those around me and I think I have a solution, I'm going to throw my idea out there regardless of what my co-workers think. It means I will allow my "good" idea to be chewed on by the team and turned into something even better (or thrown away).<br />
<br />
This is super hard, because when you think you have a good idea, and it gets ripped to shreds, it hurts. But, it's how you get better. You pick yourself up again, rinse and repeat. Eventually something will stick and you will begin to have an impact.<br />
<br />
In fact I believe a properly functioning team is when everybody is leading. It means everybody initiates communication and is trying to solve the problems around them.<br />
<br />
It's just not possible to lead without communication. If someone "leads" without communication, at best it is merely management.<br />
<br />
So if you are still wondering if you are a leader (because you don't have the title), let me ask you... do you have the ability to ask questions? If your answer is yes, than yes you can be a leader.<br />
<br />
So get up, get out of your comfort zone and go start asking some questions.<br />
<br />
Question, listen, absorb, innovate. That's the leadership cycle. Go do it!Roger L. Dillerhttp://www.blogger.com/profile/02943467573406524963noreply@blogger.com0tag:blogger.com,1999:blog-3763394677831565127.post-52430430598442328742015-04-25T10:25:00.000-07:002015-04-25T10:25:30.722-07:00Embracing JavaScript & the WebSo back in October 2014 I wrote a post about <a href="http://rogiller.blogspot.com/2014/10/managing-web-complexity.html" target="_blank">Managing Web Complexity</a>. In that post I discussed web abstractions that allow you to write in a solid engineering language such as Java and take care of generating all the "web stuff". The main tools that I am familiar with that do this are GWT and Vaadin.<br />
<br />
For years I have been on the side of the fence solidly FOR server side web abstractions. My main line of reasoning was something along the lines that "the web is too finicky & complex for large enterprise web applications, and JavaScript stinks". Over the last half year or so, I have changed course quite a bit. I have began a journey where I am learning the fundamental building blocks of the web. I've studied CSS and lately have been doing courses on JavaScript. Yes, you read that correctly, JavaScript. I've even dabbled with node.js (oh the thought!!). Believe me, node.js is not for the large enterprise app but it sure is a nice way to learn JavaScript. As an aside, I think node.js could work well in a microservices environment for certain kinds of microservice applications. If what you need is super fast responses with small data payloads, then it would be a good candidate. But, building a large monolith app with node.js? No way, that would not end well!<br />
<br />
One of the big triggers for this change of course was learning about EXT.JS. While I had seen the name around before, I never took a good look at it. Turns out, it does quite a good job at managing web complexity cause all you do is write JavaScript, you don't have to deal with HTML & browser idiosyncrasies. EXT is really the jQuery of the enterprise. It's been around a long time, it's stable & mature, and it's not going away. These other JavaScript frameworks like Angular or React may just fade after a few years. Plus they just don't have the out-of-the-box UI toolkit that is needed for large enterprise web applications.<br />
<br />
Another angle is separation of concerns. I think any UI needs to be completely separate from the server side & be completely back end implementation agnostic. In a world of many possible clients (Desktop web, mobile, integration clients, etc), this forces a good communication architecture with the back end.<br />
<br />
With these server side frameworks, you are completely tied to the back end. In the case of Vaadin it's even worse because by default, any client side action has to go back to the server to do even the most simple UI interaction. That's bad.<br />
<br />
By having server side agnostic clients, you could literally rewrite the back end if needed. Even though that would be a huge undertaking for any decent size application, it's totally doable, and probably easier than rewriting both the UI & back end at the same time. Easier because you have the front end "contract" and you just need to reimplement that "contract". It could also be a very necessary thing in this day and age with domains getting larger & the sheer size of data increasing rapidly. It's very possible that more & more relational database applications will need migrated to better storage systems.<br />
<br />
So is JavaScript an awesome language? Not really, but once you get used to it, it's tolerable. As long as you are working with a framework such as EXT or jQuery, it's much better. It's easy to rat on JavaScript, but in reality it has won, so we should just stop trying to avoid it with these "compile to JavaScript frameworks". Cheers to the web!Roger L. Dillerhttp://www.blogger.com/profile/02943467573406524963noreply@blogger.com0tag:blogger.com,1999:blog-3763394677831565127.post-12663446085398949752014-11-11T13:26:00.000-08:002014-11-11T13:33:35.553-08:00Software Is HardNOTE: I wrote most of this blog post back in April 2014 but never published it. I am publishing it now because I think it has a certain amount of value. It might be perceived as somewhat pessimistic in tone but I'm really just trying to be realistic. Software development is not easy, and I think it's healthy to be open and honest about frustrations you face in any career.<br />
<br />
---BEGIN POST----<br />
<br />
Yes, software is hard. Programming isn't necessarily hard (although it can be till you've learned a language well enough) but working, functional software is hard.<br />
<br />
Here are some reasons that make software hard (at least to me):<br />
<ol>
<li>Software is inherently not flexible. Software is incredibly precise. There is no ambiguity, even though the same actions may produce different results, it is only because settings or data somewhere were slightly different. As a result, it doesn't adapt very well.</li>
<li>Understanding a business process and then translating into working code is incredibly difficult. Especially if you haven't worked directly in the industry your software is used.</li>
<li>Software is abstract, it's an idea and not very visualizable.</li>
<li>Communicating about abstractions is hard.</li>
<li>Terminology varies, without good terminology we don't have "handles" to grab onto.</li>
<li>Until you have a codebase entirely in your head, there are just things you don't know. You're never quite sure if you handled something in all the needed areas.</li>
<li>Shortage of time. It seems there is usually not enough time to complete something or least a perceived shortage of time due to the massive amount of pending feature requests.</li>
<li>Interruptions. As a developer, you have special insight into problems and you will be interrupted to help with production problems & questions. Interruptions really slow down the coding process and lead to errors and scattered thought processes.</li>
<li>Other mental demands. Chances are you have a life outside of coding (hopefully) and there can be general life stress from other people and events in your life. These things also compete for your mental capacities and have an impact on your focus & productivity.</li>
<li>Software doesn't stay constant. You may master a language or API, but there is always something new to learn. The principles stay the same but it is still a large task to master a new language or UI toolkit. Currently I have to be good with Java, SQL, BI, ActionScript, web services, integrations, etc let alone all the API's & frameworks such Spring, Hibernate, QuickBooks SDK, JasperReports, etc.</li>
</ol>
<div>
Of course there are many process related things that can make software hard but I'm not going to go into all of that in this post. Even if you have excellent processes the above points will usually still apply. It's just part of the business. You can go along way in helping yourself by just becoming aware of these pain points.</div>
<div>
<br /></div>
<div>
A good way to help is to maintain a good work life balance. Don't over work and don't over goof off. Learn to push through the resistance but also learn to recognize when you just need to take a break. Sometimes you just need something to break up the routine. Once in a while start earlier than normal or wait till after lunch to get started. Go out for a bike ride before work or maybe just take a random unplanned day off.<br />
<br />
Ultimately I stay in software development mostly because it is a challenge, not because I love it everyday. Of course there are days when I'm having a complete blast but that is not the majority of the time. The point remains, software is hard.</div>
Roger L. Dillerhttp://www.blogger.com/profile/02943467573406524963noreply@blogger.com0tag:blogger.com,1999:blog-3763394677831565127.post-3433128915741552622014-10-18T06:44:00.000-07:002014-10-18T06:44:48.215-07:00Managing Web ComplexitySo the wonderful world of the web technologies is great. HTML5, CSS, JavaScript, you get the idea. You can build many wonderful things with these. Enter a tool like jQuery, and you can do things even easier and better. You have plethora of JS frameworks to help you build a website or a web app... Backbone, Angular, Ember, etc. I believe these tools & technologies work well for a large swath of web targets. However, not all. I'll breakdown how I segment the web to make this more understandable. I think the web falls into the following three categories with some overlap in between.<br />
<br />
<b>Websites</b><br />
Websites are documents. In fact they are primarily what the web tech family was designed for. It fits well with the DOM concept. It was to facilitate a cross-platform way to display information to the world in a quasi standards based way. This does not mean the content is static but rather interact with the user to a certain extent. Dynamic content may displayed with JS or PHP. But the overarching idea of this category is to get information out. Examples are corporate websites & personal websites.<br />
<b><br /></b>
<b>Websitey apps</b><br />
This is when websites begin to function more like an application. I don't particularly like the term "websitey application" but that's all I can come up with now. In this category, the "websitey application" is very interactive. User's have accounts, they do persistent actions as in order stuff, change stuff, add content, etc. This is the beginning of where the concept of the UI being a document begins to get a little shaky but still holds up decently well. Examples would be Amazon, eBay, Drupal & Wordpress sites, and really any site with ecommerce. Web tech & tools hold up pretty well for most of these as the complexity is still limited however the document or DOM concept begins to show it's weaknesses when the application is larger. As I said before, the DOM was intended for displaying content, not really for complex dynamic & interactive scenarios. At this point JavaScript becomes somewhat of a hack to manipulate the DOM into doing what needs done.<br />
<b><br /></b>
<b>Enterprise business apps</b><br />
These are full screen business tools. The concept of "website" is just not adequate. The app takes the full browser area, no header or footer, just a menu system, and a work area. These are really web implementations of what back in the day would have been full screen desktop business applications. Examples would be QuickBooks Online, Xero Accounting, Flex Rental Solutions, and thousands of other applications that fly unknown under the cover of the enterprise. The idea of directly using many of the web tools & technologies really shows their weaknesses here. Why? Complexity. The large enterprise app has a tremendous domain size and structure. This results in large numbers of components on the UI side. It's important in this area that the UI layer be self documenting in the form of packages (namespaces), component names, inheritance, and lot of the concepts on the backend that make development sane. Without structure, it literally becomes hard to find the component that you need to work on. In JS, there is no concept of class per file, so you can have many "objects" embedded within one JS file. That leaves you to a basic text search & find to be able to find your data (DTOs) & UI components. Bottom line, the large enterprise can implode in this space if a way is not found to manage complexity. And no Backbone is not always sufficient for this.<br />
<br />
<br />
So what's the solution for complex web apps? Honestly at this point I'm not totally sure. In abstract terms, the solution is a tool that abstracts away from web technologies that allow you to code to an API instead of the direct implementation. This might mean using an enterprise proven language to compile to JavaScript such as GWT. I see web technologies as a low level "language" to be built on top of to unleash it's true power. Yes, there are drawbacks to this, but I think the good far out weights the bad. Just like in the sense that there are probably advantages to writing certain solutions in assembly language, but in general it's a given that higher level languages offer a tremendous productivity benefit.<br />
<br />
However, I want to look further. I find the concept of web abstraction compelling but I'm squeamish if it's really the long long term future. As in will it work well in 10 years. I feel that maybe the root problem of doing large Enterprise web apps is the DOM. I watched a <a href="https://www.youtube.com/watch?v=-TDg6fChFPU" target="_blank">youtube video</a> (watch it, it's good) the other day about web frameworks and one guy made the comment something along the lines of "if you were to build a UI toolkit today, it would look nothing like the DOM". I find that fascinating. I feel the DOM is kinda a misfit for web applications but it has so much inertia going for it now, that it may be years before people start to seriously question the DOM.<br />
<br />
Post-DOM is going to take a long time. I could easily see it being close to a decade before it reaches critical mass. In the meantime, I want to see awesome web abstraction tools. I think Vaadin & GWT have a compelling use case. I have reservations about Vaadin latency & performance but I think it's UI concept is solid.<br />
<br />
To me, any good UI toolkit needs to be powerful but yet at the same time kinda just fade into the background and allow you to focus on solving business problems. You should not have to think about browser idiosyncrasies, compatibility issues, and structural complexity.<br />
<br />
Cheers to awesome web abstractions, managed web complexity, and the post-DOM way of building internet applications whatever that may be!Roger L. Dillerhttp://www.blogger.com/profile/02943467573406524963noreply@blogger.com0tag:blogger.com,1999:blog-3763394677831565127.post-60291918494441961322014-04-25T08:22:00.000-07:002014-04-25T08:29:32.658-07:00The Programming DilemmaSoftware is code. Code is structure. Structure is meaning. Meaning requires structure. Almost by definition, structure does not change or adapt or otherwise it would lose meaning. So, in order to simulate "adaptable-ness", you have to make it configurable. But there is still structure, because there are still unchanging structures that information must flow through.<br />
<br />
You could in theory make software completely dynamic (as in get or send anything from or to a system) but then you would have to do some kind of "programming" on the client side in order to use it. For example, say I want to make it possible from the client side to be able to get any information possible out of my software system. One option is just make every piece of data available in every possible known combination (a herculean task). Or create some kind of "query" language to get the data out of my system. In essence, the application just becomes a domain specific language on top of your database.<br />
<br />
Programming is supposed to make it easier to to do things. Users want to point and click to make things happen. They don't want to write code to make it happen. But then people want things to adapt to their needs. So you add configuration. The tradeoff is that now the system is harder to understand how to use. Taken to the extreme for flexibleness, your application becomes a maze of knobs and switches. Which oddly enough, to setup, feels a bit like programming something. So you end up programming the program. I thought the point of programming was to not have to program?<br />
<br />
I've come to the conclusion that an application is really only 100% useful for one company max. As soon as you involve more than one company, there are differing opinions on how things should be done. There are differing opinions within a company, but a least at a company level, policies can be adjusted. To support more than one company, you have to either be dogmatic and say "you have to do it this way" or make a configuration option. As soon as you begin down the road of configuration, it becomes harder and harder to know how to use the software. It's a problem that if is not checked will bring the software to it's knees and it will die a slow hard death.<br />
<br />
Programming doesn't really solve problems very well. It solves one problem and creates ten other ones. It is inherently self-defeating. I've said it before and I'll say it again, "software is hard", and yes it always will be.<br />
<br />
P.S. I think it is wise to keep an eagle eye out for what NOT to program rather than what to program. There is no shortage of things to program. It takes gutsy, courageous leadership to say "we are not going to program that because it will create to many additional [programming] problems".Roger L. Dillerhttp://www.blogger.com/profile/02943467573406524963noreply@blogger.com0tag:blogger.com,1999:blog-3763394677831565127.post-84334212359974461342013-06-11T10:48:00.000-07:002014-04-25T08:26:11.930-07:00Getting your iPhone 4,4S, 5, or 5S fully working on Straight TalkIf you want to use your iPhone 4, 4S, 5, or 5S on Straight Talk, it's usually pretty easy, or I should say was easy (as of this writing I don't think Straight Talk is offering any AT&T compatible SIM cards for purchase on their website). All you normally would have to do is install the correct configuration profile from <a href="http://www.unlockit.co.nz/unlockit/" target="_blank">http://www.unlockit.co.nz/unlockit/ </a>and voilĂ you had data. But not full MMS, only iPhone to iPhone over iMessage.<br />
<br />
Since I'm picky when it comes to my phone, not having full MMS functionality did not sit well with me. The solution I came across was to use a t-mobile sim to activate the cellular data settings. The process I used is detailed below.<br />
<br />
First some preliminaries:<br />
<ol>
<li>Get your iPhone factory unlocked. Either through AT&T <a href="https://www.att.com/deviceunlock/client/en_US/termsAndCondition" target="_blank">here</a> or by purchasing a factory unlock service on <a href="http://www.ebay.com/sch/i.html?_trksid=p2050601.m570.l1313.TR0.TRC0&_nkw=iphone+factory+unlock+service&_sacat=0&_from=R40" target="_blank">eBay</a>. I had to do the eBay unlock service because the AT&T unlock didn't work for me. Either way, once one of those unlock methods work, you'll need to restore you phone in iTunes for the unlock to be effective. It will tell you that your phone is unlocked when the restore completes. I believe it is required in order for the Cellular Data Settings to come up when you use the t-mobile SIM later.</li>
<li>Get an inactive T-Mobile micro SIM. eBay is great way to get one, just make sure it is a micro SIM, not a standard size SIM. Otherwise you will have to cut down the standard size sim to micro sim size, so save yourself the trouble and purchase a MICRO SIM.</li>
</ol>
<div>
Now for the actual process:</div>
<ol>
<li>Turn off wifi. Keep your existing APN configuration profile in place. It's good to have it there just in case the APN settings reset randomly. This has happened to me a few times.</li>
<li>Open the Notes app so that it is in the background for later.</li>
<li>Insert T-Mobile SIM into iPhone. Wait a few seconds and go to Settings > General > Cellular > Cellular Data Network. If you don't see the Cellular Data Network menu item, it might be because your phone is not unlocked.</li>
<li>Switch to Notes app. Do this by double tapping home button and select the Notes app. Stay in the Notes app.</li>
<li>Insert Straight Talk SIM. It's important that you stay in the Notes app for at least a minute as different things flash up in the upper left corner of the screen. Wait till it says HOME and stays on HOME.</li>
<li>Switch back to Settings. Do this by double tapping home button and selecting Settings app. Settings should still be on the Cellular Data Network screen.</li>
<li>Enter Straight Talk settings. The settings <a href="http://www.unlockit.co.nz/mobilesettings/settings.php?id=242" target="_blank">here</a> should do the trick.</li>
<li>Go back to General. Hit the back button in the upper left corner to get back to the General screen. Your settings should now be saved.</li>
<li>At this point your phone should be good to go but you may need to reboot the phone for everything to take effect.</li>
</ol>
<div>
Some other things to think about:</div>
<div>
<br /></div>
<div>
You may find that updating to a new version of iOS, even if it is only a minor version upgrade will reset the settings. If that happens, just follow the process above again. Also, I would be wary about upgrading to the next major version such as iOS 7. There's no guarantee this workaround will still work.</div>
<div>
<br /></div>
<div>
Hopefully this process works for you, it did for me. However, if it didn't, you can always revert back to installing the Straight Talk profile from <a href="http://www.unlockit.co.nz/unlockit/" target="_blank">http://www.unlockit.co.nz/unlockit/</a> and still have data & MMS iPhone to iPhone.</div>
<br />
Update 11/05/2013:<br />
As of the iOS 7.0.3 update my Straight Talk SIM just works, no APN settings or config profiles needed. I still keep the APN config profile installed just in case. This is for the newer LTE SIMs, I don't know if this works for the older ones.<br />
<br />
Straight Talk has AT&T compatible SIMs for sell now.Roger L. Dillerhttp://www.blogger.com/profile/02943467573406524963noreply@blogger.com0tag:blogger.com,1999:blog-3763394677831565127.post-13275778521484486852012-06-07T11:20:00.000-07:002012-06-07T11:20:45.689-07:00Font Extensions<br />
One issue in a system that I work on that was kind of side stepped around for awhile is the issue of custom fonts in reports, specifically reports built with the Jasper Reports framework. For a while we were just building all our reports in a standard font which was included in the build so this worked fine.<br />
<br />
However, when we build custom reports for customers, they sometimes want text to be in specific fonts to match their branding. This is a completely reasonable requirement, but we just needed a sure fire way to deal with it.<br />
<br />
In past times we would just take the font and install it on the customer's server however this was brittle since as soon as you would move the customer to another server, it would break their custom reports. Also this approach was problematic in rendering the PDFs correctly on any machine.<br />
<br />
So the best way is to just include the fonts in the build. Fortunately Jasper Reports includes something called font extensions that make this very easy. Basically you just put a properties file in the default package called "jasperreports_extension.properties" and Jasper will automatically find the file. This file just sets a couple properties and tells Jasper where to find the font XML configuration file.<br />
<br />
Example jasperreports_extension.properties:<br />
<br />
<br />
<div class="p1">
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"><span class="s1">net.sf.jasperreports.extension.registry.factory.fonts=</span>net.sf.jasperreports.engine.fonts.SimpleFontExtensionsRegistryFactory</span></div>
<div class="p2">
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;">net.sf.jasperreports.extension.simple.font.families.frsfamily=<span class="s2">fonts/frsfontsfamily.xml</span></span></div>
<div class="p2">
<span style="font-size: x-small;"><br /></span></div>
<div class="p2">
Next you create a "fonts" directory, place your True Type Format fonts in there, and create an XML file that configures the fonts.</div>
<div class="p2">
<br /></div>
<div class="p2">
Example XML font config file:</div>
<div class="p2">
<br /></div>
<div class="p2">
</div>
<div class="p1">
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"><span class="s1"><!--?</font--><span class="s2">xml</span><span class="s3"> </span>version<span class="s3">=</span><span class="s4">"1.0"</span><span class="s3"> </span>encoding<span class="s3">=</span><span class="s4">"UTF-8"</span><span class="s1">?></span></span></span></div>
<div class="p2">
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"><span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"><span class="s1"><</span>fontFamilies<span class="s1">></span></span></span></div>
<div class="p3">
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"><span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"><br /></span></span></div>
<div class="p4">
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"><span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"><span class="s3"> </span><span class="s1"><</span><span class="s2">fontFamily</span><span class="s3"> </span><span class="s5">name</span><span class="s3">=</span>"NewsGothicBT-Roman"<span class="s1">></span></span></span></div>
<div class="p5">
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"><span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"> <span class="s1"><</span><span class="s2">normal</span><span class="s1">></span>fonts/News Gothic.ttf<span class="s1"><!--</font--><span class="s2">normal</span><span class="s1">></span></span></span></span></div>
<div class="p5">
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"><span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"><span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"> <span class="s1"><</span><span class="s2">bold</span><span class="s1">></span>fonts/News Gothic Bold.ttf<span class="s1"><!--</font--><span class="s2">bold</span><span class="s1">></span></span></span></span></span></div>
<div class="p2">
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"><span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"><span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"><span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"><span class="s3"> </span><span class="s1"><</span>pdfEmbedded<span class="s1">></span><span class="s3">true</span><span class="s1"><!--</font-->pdfEmbedded<span class="s1">></span></span></span></span></span></span></div>
<div class="p2">
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"><span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"><span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"><span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"><span class="s3"> </span><span class="s1"><!--</font-->fontFamily<span class="s1">></span></span></span></span></span></span></div>
<div class="p3">
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"><span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"><span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"><span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"><br /></span></span></span></span></div>
<div class="p2">
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"><span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"><span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"><span class="s3"> </span><span class="s1"><</span>fontFamily<span class="s3"> </span><span class="s5">name</span><span class="s3">=</span><span class="s4">"Planer"</span><span class="s1">></span></span></span></span></div>
<div class="p5">
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"><span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"><span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"> <span class="s1"><</span><span class="s2">normal</span><span class="s1">></span>fonts/Planer_Reg.ttf<span class="s1"><!--</font--><span class="s2">normal</span><span class="s1">></span></span></span></span></span></div>
<div class="p5">
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"><span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"><span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"><span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"> <span class="s1"><</span><span class="s2">bold</span><span class="s1">></span>fonts/planerdemibold.ttf<span class="s1"><!--</font--><span class="s2">bold</span><span class="s1">></span></span></span></span></span></span></div>
<div class="p2">
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"><span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"><span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"><span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"><span class="s3"> </span><span class="s1"><</span>pdfEmbedded<span class="s1">></span><span class="s3">true</span><span class="s1"><!--</font-->pdfEmbedded<span class="s1">></span></span></span></span></span></span></div>
<div class="p2">
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"><span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"><span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"><span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"><span class="s3"> </span><span class="s1"><!--</font-->fontFamily<span class="s1">></span></span></span></span></span></span></div>
<div class="p3">
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"><span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"><span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"><span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"><br /></span></span></span></span></div>
<div class="p2">
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"><span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"><span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"><span class="s1"><!--</font-->fontFamilies<span class="s1">></span></span></span></span></span></div>
<div class="p2">
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"><span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"><span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"><span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"><br /></span></span></span></span></div>
<div class="p2">
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"><span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"><span class="s1">Jasper reads the above XML and registers the fonts. Whenever the above font names are referenced in a report, the TTF fonts are used and embedded in the PDF itself (notice pdfEmbedded=true above) so that the PDF will be rendered correctly on any system that opens it.</span></span></span></div>
<div class="p2">
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"><span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"><span class="s1"><br /></span></span></span></div>
<div class="p2">
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"><span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"><span class="s1">So from now on whenever a custom font is needed, we just drop the TTF font files in the fonts directory, configure them in frsfontsfamily.xml and they are available everywhere.</span></span></span></div>
<div class="p2">
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"><span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"><span class="s1"><br /></span></span></span></div>
<div class="p2">
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"><span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"><span class="s1"><span style="font-family: inherit;">Our next step might be to create a way to dynamically load fonts onto a live system allowing for more flexibility but for now we are happy with being able to include fonts in the build </span>guaranteeing<span style="font-family: inherit;"> that they will be available and embedded in the PDFs.</span></span></span></span><br />
<div>
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"><span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"><span class="s1"><span style="font-family: inherit;"><br /></span></span></span></span></div>
</div>Roger L. Dillerhttp://www.blogger.com/profile/02943467573406524963noreply@blogger.com0tag:blogger.com,1999:blog-3763394677831565127.post-21132383953004025862012-02-27T13:48:00.000-08:002012-02-27T13:48:23.666-08:00Transparent Field Encryption/DecryptionRecently I have been working on expanding <a href="https://www.flexrentalsolutions.com/">FRS</a> integration with QuickBooks to include the Online Edition. While working on the transport pipe for QBOE (QuickBooks Online Edition), a realized requirement was the need to store a QBOE connection ticket. Something like this is usually a very simple task involving adding a new field to the appropriate domain object.<br />
<br />
However in this case, one of the security rules that QBOE requires of an application is to store the connection ticket in an encrypted state. This is a common security requirement. Since the ticket acts as a key to QBOE, we don't want anybody with database access to get their hands on the actual ticket.<br />
<br />
The first thought was to simply create a utility class to handle the encryption/decryption, possibly in a getter or setter. Another thought was to create a custom hibernate type that would handle the encryption/decryption by making use of an encryption utility class.<br />
<br />
Upon doing some searching I came upon this: <a href="http://www.jasypt.org/">http://www.jasypt.org/</a> Basically Jasypt is just a java library that makes encryption extremely easy at the data layer. In fact all you need to do is get the appropriate jars on the classpath and do just a little configuration in the hibernate configuration, and voilĂ encryption/decryption just works.<br />
<br />
Here is an example of setting up the custom type in the hibernate configuration:<br />
<br />
<div class="p1">
<span style="font-family: 'Courier New', Courier, monospace;"><span class="s1"><</span><span class="s2">typedef</span><span class="s3"> </span><span class="s4">name</span><span class="s3">=</span>"quickbooksEncryptedString" <span class="s4">class</span><span class="s3">=</span>"org.jasypt.hibernate3.type.EncryptedStringType"<span class="s1">></span></span></div>
<div class="p2">
<span style="font-family: 'Courier New', Courier, monospace;"> <span class="s1"><</span><span class="s2">param</span> <span class="s4">name</span>=<span class="s5">"algorithm"</span><span class="s1">></span>PBEWithMD5AndDES<span class="s1"><span class="s2">param</span><span class="s1">></span></span></span></div>
<div class="p2">
<span style="font-family: 'Courier New', Courier, monospace;"><span style="font-family: 'Courier New', Courier, monospace;"> <span class="s1"><</span><span class="s2">param</span> <span class="s4">name</span>=<span class="s5">"password"</span><span class="s1">>encyption-password</span><span class="s1"><span class="s2">param</span><span class="s1">></span></span></span></span></div>
<div class="p1">
<span style="font-family: 'Courier New', Courier, monospace;"><span style="font-family: 'Courier New', Courier, monospace;"><span style="font-family: 'Courier New', Courier, monospace;"><span class="s3"> </span><span class="s1"><</span><span class="s2">param</span><span class="s3"> </span><span class="s4">name</span><span class="s3">=</span>"keyObtentionIterations"<span class="s1">></span><span class="s3">1000</span><span class="s1"><span class="s2">param</span><span class="s1">></span></span></span></span></span></div>
<div class="p3">
<span style="font-family: 'Courier New', Courier, monospace;"><span style="font-family: 'Courier New', Courier, monospace;"><span style="font-family: 'Courier New', Courier, monospace;"><span style="font-family: 'Courier New', Courier, monospace;"><span class="s1">typedef<span class="s1">></span></span></span></span></span></span></div>
<div class="p3">
<span style="font-family: 'Courier New', Courier, monospace;"><span style="font-family: 'Courier New', Courier, monospace;"><span style="font-family: 'Courier New', Courier, monospace;"><span style="font-family: 'Courier New', Courier, monospace;"><span style="font-family: 'Courier New', Courier, monospace;"><span class="s1"><br /></span></span></span></span></span></span></div>
<div class="p3">
<span style="font-family: inherit;">And the corresponding property mapping:</span></div>
<div class="p3">
<span style="font-family: 'Courier New', Courier, monospace;"><span style="font-family: 'Courier New', Courier, monospace;"><span style="font-family: 'Courier New', Courier, monospace;"><span style="font-family: 'Courier New', Courier, monospace;"><span style="font-family: inherit;"><br /></span></span></span></span></span></div>
<div class="p3">
</div>
<div class="p1">
<span style="font-family: 'Courier New', Courier, monospace;"><span style="font-family: 'Courier New', Courier, monospace;"><span style="font-family: 'Courier New', Courier, monospace;"><span style="font-family: 'Courier New', Courier, monospace;"><span style="font-family: 'Courier New', Courier, monospace;"><span class="s1"><</span><span class="s2">property</span><span class="s3"> </span><span class="s4">column</span><span class="s3">=</span>"qb_online_connection_ticket"<span class="s3"> </span><span class="s4">name</span><span class="s3">=</span>"quickbooksOnlineConnectionTicket"<span class="s3"> </span><span class="s4">type</span><span class="s3">=</span>"quickbooksEncryptedString"<span class="s3"> </span><span class="s4">length</span><span class="s3">=</span>"1000"<span class="s1">/></span></span></span></span></span></span></div>
<div class="p1">
<span style="font-family: 'Courier New', Courier, monospace;"><span style="font-family: 'Courier New', Courier, monospace;"><span style="font-family: 'Courier New', Courier, monospace;"><span style="font-family: 'Courier New', Courier, monospace;"><span style="font-family: 'Courier New', Courier, monospace;"><span class="s1"><br /></span></span></span></span></span></span></div>
<div class="p1">
<span style="font-family: inherit;"><span class="s1">Besides getting the Jasypt jars on the classpath, that is really all there is to it. With the above configuration the "</span>quickbooksOnlineConnectionTicket" property is automatically encrypted when it is saved to the database and then automatically decrypted when it is retrieved. So from a coding perspective nothing changes. You can simply "set" the ticket and "get" the ticket whenever you need to.</span></div>Roger L. Dillerhttp://www.blogger.com/profile/02943467573406524963noreply@blogger.com0tag:blogger.com,1999:blog-3763394677831565127.post-50471048665595294962011-05-13T19:25:00.000-07:002011-05-14T10:19:03.915-07:00School UpdateI haven't blogged for a long time on the WGU school thing (in fact I haven't blogged much at all recently due to much busyness) but it has been coming right along. I am down to my final six classes and it appears I will be done this fall. It has been quite the ride. I have covered a ton of material in the last year and a half. <div><br /></div><div>Two of the six classes remaining involves the final capstone project. My intention is to design & complete a small iPhone app to fulfill the capstone requirement. I am looking forward to getting into the world of mobile applications... it's been a long time coming.</div><div><br /></div><div>Overall, WGU has been a good experience. I have gained a bunch of IT certifications one of which was the Sun Certified Java Programmer (SCJP). I had been wanting to achieve that one for a long time prior to even starting school. I have expanded my world quite a bit with general education studies. At times it was easy to fight their relevance, but I think they have a valid purpose... at least most of them anyway.</div><div><br /></div><div>I am looking forward to completing the degree this fall. After that, I intend to utilize the degree as a foundation for my further pursuits in the field of software engineering. It's hard telling where the journey will lead.</div>Roger L. Dillerhttp://www.blogger.com/profile/02943467573406524963noreply@blogger.com0tag:blogger.com,1999:blog-3763394677831565127.post-12224893027843484652010-11-01T18:35:00.000-07:002010-11-02T05:27:52.627-07:00JasperReports & the Format Factory<span class="Apple-style-span"><span class="Apple-style-span" style="font-size: small;"></span></span><span><span></span></span><span><span>The more I work with JasperReports, the more I admire the project altogether. It seems like every time when I'm like "I wonder if JasperReports can handle that" it does, and it does it well.</span></span><div><span><span><br />Recently one of those issues had to do with localization, specifically date & number formatting. If you have worked with JasperReports you'll probably know that you can format dates & numbers with the pattern (e.g. "MM/dd/yyyy") attribute on a text field element. That is just fine when the pattern is known at design time. But what do you do when the patterns need to be localized or in other words dynamic?</span></span><div><span><span><br />No you can't use a String parameter as a pattern. The pattern attribute on a text field does not accept an expression, only a string literal. Another solution might be to have your application twiddle the JRXML and inject the proper patterns. But that would be hacky and could easily be error prone.</span></span></div><div><span><span><br />Enter the Format Factory. The Format Factory concept is simple but powerful. The FormatFactory is an interface in the net.sf.jasperreports.engine.util package that you implement to create your own date & number formats.<br /><br /><span class="Apple-style-span" style="font-size: x-small;"><span class="Apple-style-span"></span></span></span></span></div><span class="Apple-style-span"><span class="Apple-style-span" style="font-size: x-small;">public class MyFormatFactory implements FormatFactory {</span></span><div><span class="Apple-style-span"><span class="Apple-style-span" style="font-size: x-small;"><br />public DateFormat createDateFormat(String pattern, Locale locale, TimeZone timeZone) { </span></span><div><span class="Apple-style-span"><span class="Apple-tab-span" style="white-space:pre"><span class="Apple-style-span" style="font-size: x-small;"> </span></span><span class="Apple-style-span" style="font-size: x-small;">//create your date format here </span></span></div><div><span class="Apple-style-span"><span class="Apple-tab-span" style="white-space:pre"><span class="Apple-style-span" style="font-size: x-small;"> </span></span><span class="Apple-style-span" style="font-size: x-small;">return your-date-format ;</span></span></div><div><span class="Apple-style-span"><span class="Apple-style-span" style="font-size: x-small;">}</span></span></div><div><span class="Apple-style-span"><span class="Apple-style-span" style="font-size: x-small;"><br />public NumberFormat createNumberFormat(String pattern, Locale locale) { </span></span></div><div><span class="Apple-style-span"><span class="Apple-tab-span" style="white-space:pre"><span class="Apple-style-span" style="font-size: x-small;"> </span></span><span class="Apple-style-span" style="font-size: x-small;">// create your number format here</span></span></div><div><span class="Apple-style-span"><span class="Apple-tab-span" style="white-space:pre"><span class="Apple-style-span" style="font-size: x-small;"> </span></span><span class="Apple-style-span" style="font-size: x-small;">return your-number-format ; </span></span></div><div><span class="Apple-style-span"><span class="Apple-style-span" style="font-size: x-small;"> }</span></span></div><div><span class="Apple-style-span"><span class="Apple-style-span" style="font-size: x-small;"><br />}</span></span><div><div><div><span><span><span class="Apple-style-span"></span></span></span><div><span><span></span></span><div><div><span class="Apple-style-span" style="font-size: x-small;"><span class="Apple-style-span"></span></span><div><span class="Apple-style-span" style="font-size: x-small;"><span class="Apple-style-span"></span></span></div><div><span><span><br />Essentially, your application takes over format creation instead of the JasperReports engine itself.</span></span></div><div><span><span><br />The best part of all this is your ability to create formats based on your own defined constants. You'll notice that the two methods in the class above have a "pattern" parameter. That is the pattern that you assign to the textfield. </span></span></div><div><span><span><br />You might say, hey I thought we weren't using explicit patterns anymore. You're right. But, we have to give a hint as to how the textfield needs to be formatted, so we would use format constants (e.g. SHORT_DATE, LONG_DATE, TIMESTAMP, etc). The constants are assigned to our text fields pattern attribute and get passed to our FormatFactory where we determine how to create a formatter based on those constants. Kinda cool, eh?</span></span></div><div><span><span><br />You might also notice the timezone & locale parameters in the methods above. Those are also parameters you can pass into the report itself which in turn get passed in to the format factory to assist you in creating the appropriate forma<span><span></span></span>ts. For example, when you create a date format you'll need to know the time zone since that is an important part of actually formatting a date.</span></span></div><div><span><span><br />The Format Factory is a fantastic feature. This is especially true for large applications that already have formatting logic implemented in the application allowing you to reuse your existing format logic.</span></span><h2 style="font-family: 'Times New Roman'; font-size: medium; "><span class="Apple-style-span" style="font-size: small; "><br /></span></h2></div></div></div></div></div></div></div></div></div></div>Roger L. Dillerhttp://www.blogger.com/profile/02943467573406524963noreply@blogger.com0tag:blogger.com,1999:blog-3763394677831565127.post-73350815542103726002010-05-14T14:13:00.001-07:002010-05-14T14:24:12.528-07:00Thoughts on Flash from JobsSo I just happened to log onto Apple's site today and noticed this article on Flash by Steve Jobs:<br /><br /><a href="http://www.apple.com/hotnews/thoughts-on-flash/">http://www.apple.com/hotnews/thoughts-on-flash/</a><br /><br />So in summary here is why Flash isn't going to be on iPad, iPhone & iPods.<br /><br />1) Flash is not an "open" standard<br />2) Apple mobile devices can already access tons of video content<br />3) Flash's reliability, security and performance on Macs is not good<br />4) Battery life<br />5) Flash and touch interface not a match<br />6) The dependability of a third party between Apple and developers<br /><br />This sounds reasonable to me but I wonder if there still aren't other behind the scenes reasons. I'm sure Apple wants to collect all revenue through the App Store. What do you think?Roger L. Dillerhttp://www.blogger.com/profile/02943467573406524963noreply@blogger.com1tag:blogger.com,1999:blog-3763394677831565127.post-32782906983389342152010-01-26T15:50:00.000-08:002010-01-26T16:09:51.016-08:00Learning SpringI am officially starting to learn the Spring Framework. Until recently the projects I have been working on have not been using Spring so I had no driving reason to learn it. Since I am so busy with school (<a href="http://www.wgu.edu/">WGU</a>) & work there is almost no way I could learn it unless it is involved in one of my projects. Now that I am involved in a project with Spring, it is a great way to learn it.<br /><br />I am starting to wrap my mind around the central idea of the Spring Framework which is Inversion of Control & Dependency Injection. Now that I'm starting to understand the framework, I realize that it truly is a great idea. In prior development I always had thoughts about the tight coupling between different areas of the application and wished I could do something about it.<br /><br />Not that Spring wiring isn't cool enough, but Spring also includes some other very cool features such as Data access support, job scheduling, mail support, web flow, etc.<br /><br />So I'm looking forward to getting a deep understanding of Spring & getting an app working from scratch with Spring.Roger L. Dillerhttp://www.blogger.com/profile/02943467573406524963noreply@blogger.com0tag:blogger.com,1999:blog-3763394677831565127.post-4310043544696563742009-11-25T19:49:00.000-08:002009-11-25T20:22:30.942-08:00Independent Software ConsultantAs of October 2009 I am (drum roll) an Independent Software Consultant. The "Independent" part is because I am not attached to any particular business entity and I will be marketing my skills as an individual. See my website at <a href="http://www.rogerdiller.com">www.rogerdiller.com</a>. I have chosen the independent route mainly because I am a full-time student... it's just not possible to hold down a full-time position and still have adequate time to study. I don't know exactly what route I'll take after finishing my degree... it depends on a variety of factors.<br /><br />As far as work, I have had the privilege of working with some great new clients in the last couple months and have been expanding my skillset much to my delight! :-) Most of my new work in the last couple months has involved the ZK Ajax Framework. Of course I am very pleased being that I am a big supported of ZK (when is the world going to wake up to ZK?!). Here are some new things that I have been delving into: Web services (Axis2,GroovyWS), Spring, and ZK Web Flow.<br /><br />School (<a href="http://www.wgu.edu">WGU</a>) has been going great as well. I love the competency based model of <a href="http://www.wgu.edu">WGU</a>. I am able to simply study the areas that I am not as familiar with and upon passing some pre-assessment exams I can take the final exam and move on. Currently I am scheduled to take my first 2 exams next week. Hopefully all goes well. :-)<br /><br />Overall I have more than enough to do. Between juggling projects and studying as much as possibly there sure is plenty to do.Roger L. Dillerhttp://www.blogger.com/profile/02943467573406524963noreply@blogger.com0tag:blogger.com,1999:blog-3763394677831565127.post-34200687369026990732009-10-02T18:21:00.000-07:002009-10-02T19:27:26.147-07:00WGU is good stuff!!Well yesterday I started on my BS in Information Technology degree program with Western Governors University and I must say I'm very impressed! Everything is very straightforward and intuitive. I started with the required first course for all new students which is called Education Without Boundaries (EWB). It was a very informative course (I completed it today) which gives you a ton of information about the school, study strategies, time management skills, etc.<br /><br />WGU has created a very good environment for learning. You are assigned a mentor for your entire time there and also have mentors for the individual course you study. There are communities where you can meet other students, ask questions or whatever you feel like. WGU even has their own instant messenger to communicate with other students, mentors, and to join into live discussions. You have access to tons of information, books, articles, magazines, you name it. You can get books sent to you on loan. Something I found very cool was you can get access to lot's of software for cheap or free. For example I can get Windows 7 Pro for $30!<br /><br />All in all even though independent learning is not for everybody, I think a lot of people could find the WGU experience enjoyable.<br /><br />Stay tuned... I intend to continue to blog about my educational experience as I study with WGU.Roger L. Dillerhttp://www.blogger.com/profile/02943467573406524963noreply@blogger.com0tag:blogger.com,1999:blog-3763394677831565127.post-79572451257594848912009-09-08T07:22:00.000-07:002009-09-08T12:25:30.713-07:00Learning TDD, BDDIn the last couple weeks I have dived head first into automated testing, specifically Test Driven Development or TDD. It's been quite the journey so far. At first TDD concepts seemed hard to grasp but a balance of reading and video began to bring it together for me. For example the idea of only writing code to fix a failing test is a hard one to grasp when you have spent almost 3 years developing code without even thinking about a test. It was hard to think in terms of what a "unit" test is not. Borrowing from <span class="as">Michael Feathers blog</span>:<br /><p style="font-weight: bold;">A test is not a unit test if:</p><div class="vegies"><li><span style="font-size:100%;">It talks to the database </span></li><li><span style="font-size:100%;">It communicates across the network </span></li><li><span style="font-size:100%;">It touches the file system </span></li><li><span style="font-size:100%;">It can't run at the same time as any of your other unit tests </span></li><li><span style="font-size:100%;">You have to do special things to your environment (such as editing config files) to run it.</span></li></div><br />Writing tests around legacy code is another big challege. Being that my project is defined as legacy code because it doesn't have unit tests, I have the task in front of me in getting it covered by tests. It won't happen without quite a bit of refactoring!<br /><br />I watched a video on Behavior Driven Development or BDD. It is essentially doing TDD well. The focus of BDD is focusing on testing the behavior of a system not necessarily having your tests mirror the exact structure of the classes you are testing. In this way your tests become the specification for your production code.<br /><br />Here are some points/tips I've observed:<br /><ul><li>Testing first helps you to think critically about what you are trying to write.</li><li>It is impossible to know everything upfront. Do what you know now, thinking decently far in context but not to far.</li><li>Don't over engineer.<br /></li><li>Agile & TDD allows for tight collaboration with the customer... a good thing!</li><li>Tests are the "glue" that holds an application together.</li><li>Unit testing is testing the smallest components which are classes/methods.</li><li>Customer is in control which is very motivating for them.</li><li>Solve the RIGHT problem RIGHT!</li><li>Over the long term effort required to write tests will pay off vs having to maintain untested code.</li><li>Developer can feel confident about work.</li><li>Refactoring is changing structure without changing what the code does.</li><li>Keep unit tests as simple as possible.</li><li>Tests are atomic and isolated.</li><li>Create "test list" from requirements, from this we can know if we are "there yet".</li><li>Tests are like examples.</li><li>Concentrate on testing the behavior of your program not necessarily mirror the exact structure of the class you are testing.</li></ul><br />All in all I believe TDD is a superb idea and a process I am adopting in my projects.<br /><br />Life Update:<br />In my last blog post I wrote about moving and pursuing a degree. We arrived in Gosport, IN on August 4. Originally I was planning on starting school on Sept. 1 but since our apartment was not quite ready I pushed it off another month. So I am scheduled to begin my degree program on Oct. 1 with WGU.Roger L. Dillerhttp://www.blogger.com/profile/02943467573406524963noreply@blogger.com0tag:blogger.com,1999:blog-3763394677831565127.post-91809678070662370122009-07-20T09:26:00.000-07:002010-09-07T08:15:42.753-07:00Moving and Pursuing EducationSo since I wrote my last blog a lot of new developments have taken place. For quite some time I've been wanting to get my Bachelor's in C.S. and finally that dream is taking form. A couple things that have kept me from moving ahead with a degree is cost of living while earning degree and a real solid reason for doing it other than for just personal gratification. We are solving the cost of living problem by moving to Gosport, IN and living on our relatives property in an apartment type setup. I will still be doing part time development for my current company which will provide us the funds to pay for our expenses and hopefully enough to cover the cost of education. As far as a real reason for earning the degree it seems like in the software field the need for at least a Bachelor's degree is becoming more and more of requirement. After talking with several people it became very clear to me that this was what I needed to do. So if everything continues to move along smoothly we will be moving August 3,4 and on September 1 I will be starting on my degree with Western Governors University (<a href="http://www.wgu.edu/">www.wgu.edu</a>). The main reasons I choose this school is because they are competency based and relatively low cost. All of my experience that I have gained in the field will help me get through faster. They charge at a flat rate every 6 months so the more aggressive you are the less you will need to dish out. So I'm very excited about increasing what I know and getting a more rounded out and broader education!Roger L. Dillerhttp://www.blogger.com/profile/02943467573406524963noreply@blogger.com0tag:blogger.com,1999:blog-3763394677831565127.post-41319034834969020462009-04-24T19:16:00.000-07:002010-03-10T14:06:45.755-08:00ZK & AJPWow so I haven't posted in like forever... so much has happened since I last posted... so much saweet new technology learned... it's just to bad I haven't captured all that on here. So one of the saweetest technologies I've been learning recently is the ZK Ajax Framework... if you never heard of it at least check it out!! <a href="http://www.zkoss.org/">www.zkoss.org</a>. It makes building dynamic web pages so cool. Primarily it's a presentation layer technology... what Swing is for Desktop J2SE apps, ZK is for J2EE web apps. You can bind ZK components to your Beans very easily, fetch data dynamically as needed, etc. All the server communication is transparent to the developer... you don't have to worry about ANY server communication stuff. Anyway so we are developing an application with this technology and therefore needed a container to run it in. To make a long story short we ended up using Apache webserver & Tomcat together using the AJP protocol. I spent all day today getting it all figured out (trust me it's no walk in the park) but I successfully got Apache & Tomcat working together!! Yah!!<br /><br /><span style="font-weight: bold;">Update:</span> I believe I used this <a href="http://www.zkoss.org/smalltalks/clusteringI/clusteringI.dsp">document </a>to get things configured... hopefully that helps.Roger L. Dillerhttp://www.blogger.com/profile/02943467573406524963noreply@blogger.com2tag:blogger.com,1999:blog-3763394677831565127.post-62121458035791645872008-08-30T19:43:00.000-07:002009-12-24T21:37:21.734-08:00iPhone, Employee ModuleSo I got my iPhone a couple weeks ago and wow this thing lives up to all the hype!! There isn't much iPhone can't do... from surfing, music, video, GPS, fabulous email you name it has it! About the only thing I have a pick about is it needs a turn by turn navigation app (which is supposed to be coming). It does have a google map app so that will suffice for now. I amazed at the App Store.... there are just so many applications on there pretty much anything you could want! I give this phone 2 thumbs up!!<br /><br />As far as work I'm rolling on the Employee module for the accounting system. It looks like it's gonna be a tough one to program. I think it's going to be more complicated than the rest of the application combined. I've started on the essentials... CRUD for an Employee. After quite a long time of part time programming on this I am full bore on this app all the way to end of the Employee module.Roger L. Dillerhttp://www.blogger.com/profile/02943467573406524963noreply@blogger.com0tag:blogger.com,1999:blog-3763394677831565127.post-45089637476266883202008-08-14T18:50:00.000-07:002009-12-24T21:39:36.102-08:00Lazy Fetching, Sequences, iPhoneSo life is very busy right now at work... so many things to do, not enough people to do them. I've been working very hard on our Accounting system lately. I've largely gotten this application converted to Hibernate but there are still areas that need to be converted. One notable change this week was my strategy on handling hibernate sessions.... after realizing that I had to enable lazy fetching the question was how do I manage the sessions so that the data can be retrieved whenever needed? I decided to take the route of one session per panel and that seems to be working. It was a lot of work, all data action methods needed to be changed to accept a session parameter among tons of other changes. Another cool thing I did related to lazy fetching is that on Vendor/Customer list panels the the addresses and contacts are retrieved as the user scrolls down the table! This is achieved in the table model by setting the address & contact column values in the getValueAt method. Therefore only the displayed rows are set and then when the user scrolls the getValueAt method is called which sets the address/contact columns for the newly displayed rows. Very cool huh?<br /><br />Another notable task this week was sequences.... I wrote a pretty complex method which gets the last reference number for a document, finds the last run of numbers in a String (the String can have any characters), increments this number, and then reinserts this number back into the String replacing the old number without misplacing any other characters.<br /><br />I'm getting an iPhone this week y'all!! It shipped today and hopefully should arrive at the AT&T store on Saturday. I like my iPod touch but I'm looking forward to having an iPhone where I can get email, surf, etc from anywhere, make calls, you name it. The iPod touch is fun till you don't have wifi and then to it gets kinda useless.Roger L. Dillerhttp://www.blogger.com/profile/02943467573406524963noreply@blogger.com0tag:blogger.com,1999:blog-3763394677831565127.post-78152102899282800362008-08-09T07:34:00.000-07:002008-08-09T13:51:40.846-07:00Android Mobile PlatformWow this Android platform has me really wound up... it seems like so far it would be the best platform to write a mobile application. Check out this link: <a rel="nofollow" href="http://www.developer.com/java/j2me/article.php/3763991">http://www.developer.com/java/j2me/article.php/3763991</a>. Of course what I like best about this platform is that it is written in Java. What I've always hated about writing applications in Java for higher end mobile (CDC) devices is the lack of support for Java. I've gotten Java applications to run on Windows Mobile 5 but the look and feel totally lacks and if you want to tap into native API's such as the GPS API it would be a real pain. With Android, Java would be the native language! Also there is no distinction between native applications and developer-created applications. They all have access to the same API's so if you didn't like the applications that came with it you could just build your own! I'll be watching this platform very closely!Roger L. Dillerhttp://www.blogger.com/profile/02943467573406524963noreply@blogger.com0