Sensible Development - Refreshed
Sensible Development - a blog by https://flowlogix.com

blake kathryn

Janaina Medeiros

Origami Around
Peter Solarz
Lint Roller? I Barely Know Her

if i look back, i am lost

❣ Chile in a Photography ❣
let's talk about Bridgerton tea, my ask is open
One Nice Bug Per Day
AnasAbdin
$LAYYYTER
Three Goblin Art
todays bird
almost home

titsay

izzy's playlists!
Mike Driver

Andulka

tannertan36

seen from United States

seen from United States
seen from United States
seen from Belgium

seen from United States
seen from Germany

seen from Philippines

seen from Malaysia
seen from United States

seen from Türkiye

seen from Italy
seen from Netherlands

seen from Netherlands

seen from Georgia

seen from United States

seen from Türkiye
seen from Bangladesh
seen from Germany

seen from United Kingdom

seen from United States
@sensibledev
Sensible Development - Refreshed
Sensible Development - a blog by https://flowlogix.com

Anya is live and ready to show you everything. Watch her strip, dance, and perform exclusive shows just for you. Interact in real-time and make your fantasies come true.
Free to watch • No registration required • HD streaming
Sensible Java Coding Standards
General
Never, ever, ever copy-and-paste source code. If I had my way, the copy/paste function in the editor would be disabled.
Never copy a file to create a new file, always use File->New
use as few lines of code as possible to accomplish the mission
Stick to the standards
Use highest-level tool that accomplishes the mission
Use JavaEE for messaging and transaction management
Use JPA O/R mapping to the highest degree possible, but not any higher
Use JPA relationships rather than separate queries
Never, ever, ever copy-and-paste source code
Don't use workarounds, since we use almost 100% open-source software
Adhere to Immutability Standards
never use static mutable state and use immutable objects
Check before introducing new infrastructure or "infrastructure"-y code. The requirements are probably already met by the environment. If in doubt, ask.
Keep the trunk clean. Source trunk should be production-ready at any time.
Use java.time.* as in LocalDateTime/LocalDate etc. classes instead of java.util.Date and companions. The latter is considered deprecated
Do's
Use Project Lombok for getters/setters/equals/hashCode and other boilerplate
Use @SneakyThrows to avoid catching checked exceptions
Use JPA CriteriaQuery or JPQL instead of native SQL
Use XA transactions where necessary
Use JavaDoc
Use meaningful variable names
Use immutable objects
Dont's
Never, ever, ever copy-and-paste source code (can't say this enough times)
Don't catch/log/hide system exceptions, let the infrastructure handle them
Don't catch generic Exception or Throwable directly. Catch only specific exceptions by using Java 8 multi-catch or @SneakyThrows
Don't write your own getters, setters, equals or hashCode, delete these even when generated by IDEs. Use Lombok to handle them
Don't use native SQL or stored procedures
Never, ever, ever copy-and-paste source code (can't say this enough times)
Don't introduce new infrastructure without checking first what already exists
Don't break the trunk builds and functionality
Don't use meaningless variable names, such as ttt, ccc, xxx, etc.
Don't create "defensive" code that checks parameters passed by infrastructure. Let infrastructure do user input checks instead
Don't use "defensive" null checks. Use @NonNull instead
Don't use static mutable state in objects, use @Singleton instead, or nothing at all
#DevOps architecture suggestions?
What combinations of products would You recommend using? (vagrant/ansible/puppet/chef?) Current system state: - AWS (RH Linux) - Manual system setup (system name /etc/ files (hosts/sysconfig/init.d etc.) - Manual SW install (Java, GlassFish, Apache, etc) - Manual system updates (yum update) - cron/rsync script to sync systems with pertinent files - Jenkins for dev/test S/W builds, but manual prod builds - manual, multi-step app (re)deploy & upgrade (undeploy, restart-cluster, deploy) - downtime while app redeploy - manual SQL scripts w/manual rollback - Internal monitoring by app itself (via email) - Performance is acceptable - network management is done by AWS Goals: - Auto system setup - Possibility of auto-scaling - Auto SW install - Auto SW / System updates - Repeatable machine / SW builds - migrate away from rsync script? - Jenkins for prod SW builds - automate app deployment & eliminate downtime - Automate tooling for app deploy - blue/green cluster deploy? - OR standalone instance redeploy? - Coordinate w/Apache mod_cluster - OR shutdown network listener while upgrading - SQL scripts / SP automation w/Rollback & versioning Strategies for new tooling: - prefer Java (or anything JVM) for all tooling - IF JVM not possible, avoid languages that start with ‘P’ - Avoid perl - Avoid JavaScript (node.js based tools) - Prefer ruby over python
My Journey with #tapestry5 and #JavaEE
Conclusion
As I looked at the big picture, it turned out to be easier to convert the whole app from T5.3 to JSF and PrimeFaces instead of T5.4, and that's what I did. This turned out a great decision. Everything is compatible, future JavaEE versions are easily adoptable, all integrations do not require heroic efforts to implement or maintain and even JavaScript and Ajax with JQuery even started to be fun to develop.
My Journey with #tapestry5 and #JavaEE
Part 17 - Conversion to Tapestry 5.4
After about 2 and a half years of using Tapestry 5.3, T5.4 was starting to take shape. It has a brand new JavaScript framework based on JQuery, Bootstrap and requireJS. I figured that it was a good direction to be headed, so I started a pilot project of converting my code into 5.4. Good news was that there were not much Java code changes required, well, it was good and bad because all the same issues in Tapestry-IOC were still present in 5.4. At least it was Java 8 compatible. In order to take advantage on the new JS framework, all infrastructure and patches that I made to make T5.3 usable had to be completely rewritten in T5.4, which was not a simple task. After spending about a month researching and updating all components to T5.4 (again undocumented) JS infrastructure, I finally got things to work, kind of. Partly because of Bootstrap layout engine in T5.4, all the pages looked wrong. I tried to figure something out to generically fix the layout, but it turned out what I had to do is manually fix up all the pages. BeanEditor and company had particular layout issues, and every on of those looked wrong with no way to fix it. Suggestions I was getting from Tapestry community was to stop using BeanEditor.

Anya is live and ready to show you everything. Watch her strip, dance, and perform exclusive shows just for you. Interact in real-time and make your fantasies come true.
Free to watch • No registration required • HD streaming
My Journey with #tapestry5 and #JavaEE
Part 16 - Java 8 compatibility
When Java 8 came out, it seemed to me the most stable release ever. I had no issues upgrading any of my software to Java 8, and the new features such as Lambdas and Streams were a wonderful additions.
Unfortunately, it took over a year and a half to release a stable version of Tapestry that supported Java 8. Why? Nobody just cared! T5.4 alphas / betas supported Java 8, but not production versions. All that had to be done is to upgrade the bundled ASM package, but nobody bothered to do it in over a year.
It’s obvious by this that nobody is really doing any active development out there with Tapestry anymore, and thus there was no outcry about Java 8 compatibility. Where does this leave Tapestry? I don’t know, but this would leave a big pit in my stomach if I was depending on Tapestry.
My Journey with #tapestry5 and #JavaEE
Part 15 - Ajax table issues and other Ajax missing features
As I was working with Ajax, especially tables / grids, it became obvious that Tapestry’s implementation is not very modern. This isn’t really addressed in T5.4 as features remain the same. Ajax table looks dated, just has one silly-looking pager on top, and if you want to customize it, good luck.
Tapestry claims many features, and there are indeed many, they are just mostly based on very old JavaScript that hadn’t been upgraded in years.
There is nobody that has the time to sit down and update the components, as it is a big job, and community contributions would be flatly rejected for “code-dumping” or “compatibility” reasons, I guess.
My Journey with #tapestry5 and #JavaEE
Part 14 - yuicompressor dependency issues
This is a plea to all projects, including Tapestry 5: If you are going to be including any dependencies in your own .jar, use “jar-jar links” or something similar to rename internal dependencies so they don’t clash with the original work.
Tapestry likes to compress JavaScript, which is good. Unfortunately, it uses yuicompressor library that’s bundled with an old version of Rhino, which conflicts with everything else we are trying to use. I had to resort to packaging my own yuicompressor with jar-jar links to be able to run any of the code.
Tapestry is not the only offender to this. GWT is a big one, among many other open-source projects.
Please, don’t do this, publish a list of your dependencies via ivy/maven instead.
Thank you
My Journey with #tapestry5 and #JavaEE
Part 13 - Tapestry-security
How to secure web applications has always been a non-trivial task. Tapestry has a module, called Tapestry-Security that simplifies things and integrates Apache Shiro with Tapestry.
As I was starting to use Tapestry-Security in-depth, however, the ugly parts of Tapestry-IOC integration came reared its ugly head again.
Apache Shiro is usually configured with shiro.ini file, which is a simple text file that presents a Java-beans-based standard configuration, is easily understood, and is used by many people. All the examples within Shiro are presented using this configuration file. Unfortunately, Tapestry-Security discards this configuration method in favor of Tapestry-IOC-based method, which is poorly documented and very hard to understand. As more security requirements were added, it became a battle to figure out just what combination of annotations, code, and where to put it all. None of these efforts paid off, and like anything with Tapestry-IOC, crazy errors were a result of seemingly simple modifications, and were impossible to figure out. Since Shiro/Tapestry-IOC/Tapestry-Security combination is rarely-used one, there was no one to help with the setup, and the more rigorous security requirements had to be abandoned in this context.
After the switch to JSF, however, Shiro, with it’s standard configuration, worked as expected, and I was able to build all of the security requirements in the application very quickly.
My Journey with #tapestry5 and #JavaEE
Part 12 - Tapestry5 design - One Class per Page vs. JSF possibilities
Now that JSF is my primary environment, I started noticing that Tapestry's design choices are not necessarily the best ones and are unnecessarily limiting. Let's take an example that in Tapestry, one page has access to one, and only one backing class. In case of JSF, you can access as many beans as necessary. The JSF way seems to be more flexible and saves code, as Java classes can be reused across pages

Anya is live and ready to show you everything. Watch her strip, dance, and perform exclusive shows just for you. Interact in real-time and make your fantasies come true.
Free to watch • No registration required • HD streaming
My Journey with #tapestry5 and #JavaEE
Part 11 - JSF 2.2 changes everything
At some point in late 2013, JSF 2.2 along with Java EE 7 was released. The major feature of JSF 2.2 is HTML 5 support, and ability to write JSF applications in standard HTML5 syntax as opposed to JSF tags. If you remember, the reason I chose Tapestry in the first place was so I could write pages in standard HTML, and give them to a web designer to refresh look and feel, and not break existing dynamic features of the pages. JSF 2.2 release finally started to support this feature. I like that Java EE environment, so this development prompted me to re-evaluate JSF as my tool set, especially since Tapestry was now causing me so much pain. Along with JSF, I could use PrimeFaces and OmniFaces, which eases the JSF development burden significantly. Along with this development, Tapestry was working hard on T5.4, which I tried head to head with JSF 2.2 as well. The question became this: which would be easier and better long-term Tapestry 5.4 with JQuery support or JSF with PrimeFaces and OmniFaces. After about a month, it became clear that converting to JSF would be easier than converted to Tapestry 5.4, so decision was made to convert the application to JSF instead of Tapestry 5.4
My Journey with #tapestry5 and #JavaEE
Part 10 - Working with Thiago
At this point, I got tired of monkey-patching every issue I found with Tapestry, which was many. The problem with my approach was that I had to copy/paste many JavaScript code snippets, and all that work would be incompatible and would break when tapestry code is modified in the future versions. What I needed is a permanent fixes that would be part of Tapestry's code. I tried to pay Thiago, a Tapestry committer to put in fixes that I desire directly to Tapestry. Thiago was friendly and good to work with, but he still wouldn't fix the more ambitious fixes that would really improve usability, which frustrated me. He did fix a few of simple issues that I reported. At the end of the day, some minor issues were fixed, but overall I can't say that situation was helped significantly by my time and monetary contributions.
My Journey with #tapestry5 and #JavaEE
Part 9 - Calendar component woes
Tapestry has couple of great features, such as BeanEditor and automatic calendar functionality in all the date fields. I was excited to use these features since it would save me writing a lot of code.
Unfortunately, as I started working with calendar, I found that its usability and user experriene was lacking. Looking at the JavaScript code behind it, I found out that it was circa 2001, clearly very old. I wouldn't mind this if the usability was ok, but it wasn't.
Here are some issues with the calendar:
Defaults to European month/year, (Ex: 2013 November instead of November 2013) and no way to change that
If a mistake is made typing the date manually, there is no way to bring up the calendar again to fix it, which is a big user experience no-no
Date highlight color cannot be customized
Missing lots of features compared to modern calendar, like JQuery DatePicker
Many small usability issues relating to the way the JavaScript code was written, mostly because it's old and doesn't take advantage of modern browser or JavaScript features
I tried to work with Tapestry committers to improve the calendar, but got the standard "compatibility" excuse for not touching the calendar component, which is basically a standard push-back I always get from Tapestry committers, along with "code dumping" Supposedly, there is a way to generically replace calendar on all date field components, which I tried. Unfortunately, I ran into the usual IOC roadblocks, as well as undocumented JavaScript API which made this replacement strategy basically impossible. I even tried paying one of the tapestry committers to improve the situation, to no avail.
I wound up writing a module to monkey patch a lot of these problems, but there are many more that remain. At the end of the day, calendar was barely usable with my patches, but just barely.
#Reactive #Programming - The Hot new thing or are we going back to Windows 2.1-style cooperative multitasking?
Apparently I've been living under a rock, and just crawled out of it, but reactive is all the rage right now. Maybe I am showing my age, but reactive seems like cooperative multitasking. So, my question is... Why do it and why all the fuss around it? Let me give you a bit of background... I have tried to build a complex high-performance reactive system about 10 years ago. It seems like a long time ago, but the reality is that Linux kernel has not changed all that much in that time, nor the environment in which user-space programs run under Linux, so the takeaway from my experience then fully applies to the systems environment today.
Let's list the supposed advantages of a reactive system:
Don't need as many threads as client connections
memory footprint is decreased due to fewer threads
capacity is increased due to decreased resource usage (threads being the resource)
What are reactive's disadvantages?
Programming model is much more complex
Potential for increased latency due to less threads processing concurrent connections
Lower throughout and higher latency (will discuss this below)
Let's compare what both user-level and kernel-level steps that are required for a synchronous, blocking, multi-threaded system vs. non-blocking reactive system. The task here is to do one cycle either through event loop in case of a reactive system, or perform one read/write in a synchronous blocking system, which accomplishes the same thing.
Blocking / Thread-Pool:
(users space) read/write() - calls into the kernel
(kernel) multiplex multiple blocked threads and dispatch ones that are ready to read/write
(kernel) fill in read() result or send out the write() result
(user space) return from read/write() with data sent or filed in
Reactive / Non-Blocking / Single-threaded:
(user space) set up select/poll/epoll/kqueue/etc. data structures with appropriate descriptors
(user space) call poll() or it's relatives
(kernel) figure out which descriptors are ready to read/write and dispatch
(user space) fill in poll() etc. results into appropriate data structures
(user space) user program parses poll() results and dispatch appropriate user code
(user space) user code calls read/write with appropriate descriptor
(kernel) fill in read() result with data or send out the write() result
(user space) return from read/write() with data sent or filled in
(user / kernel) repeat steps 6 through 8 for other descriptors
As you can see, the steps involved in reactive architecture are more involved, and there are a lot, really a LOT more steps involved to do the same task. Also, in case of a blocking system, all the tasks are exactly the ones the kernel is does very well, and kernel is optimized to perform exactly those tasks. This can't be said for a reactive system, as the tasks are done that are not optimized to be done this way. Reactive architecture executes much more slowly, using much more CPU resources for the same task, and the benchmarks support this. There are also latency issues since there is a single thread dealing with multiple connections, latency is naturally increased. The benchmarks used are basically a load test.
Of course, real life is not like a load test. There are HTTP 1.1, WebSocket, and other scenarios that require many idle connections. This is where reactive has it's only advantage. Let's talk about this and other advantages that reactive has: Idle connections, and only idle connections can be handled effectively in a reactive way. Web server knows when a connection is likely to be idle, i.e. after an HTTP request is done in HTTP 1.1, and server can put that connection in a pool that's handled by a poll() loop in a separate thread. The connection is never marked non-blocking. This way, when a connection stops being idle, it can be put back in a thread pool which will process it in a regular, blocking way. Another false advantage of reactive is lower memory footprint. This can also be mitigated by setting thread stack size low for the connection processing thread pool.
Conclusions:
Reactive really has no place in user non-infrastructure code
User Code should be written in a threaded, blocking way, at least in a web, request-response environment. Exception to this would be service orchestration, but it would still be handed synchronously, just in a separate thread using a Future-based APIs
Reactive can be used in a web server infrastructure only, and only to handle idle connections
Stack size can be lowered in the connection processing threads by the web server infrastructure to reduce memory footprint
My Journey with #tapestry5 and #JavaEE
Part 8 - @Ajax annotation and ajax delay feedback for users
As I was writing more and more Ajax-enabled pages with Tapestry, it became clear that it was missing an @Ajax annotation. This annotation would correctly interpret return value from action methods, along with graceful degradation or other functionality. There was a blog already on how to create such an annotation, but I was wondering why something like this wasn't already part of Tapestry itself. Unfortunately, after working with Tapestry committers I was unable to get the code submitted to Tapestry with a standard 'code dumping' excuse. I guess this is why the original blogger's solution to this problem was never incorporated into Tapestry itself either. As far as the code itself, it was fairly complex to develop this annotation. It involved battling with Tapestry-IOC and some JavaScript, which wound up incompatible with Tapestry 5.4
Some Ajax action methods were taking some time to execute. I was trying to show feedback to users such as an hour glass. I was surprised that this functionality wasn't already built into Tapestry. Once again I tried to work with Tapestry committers to get something like this into core Tapestry to no avail. I wound up writing it myself with help with a blog or two. Again, it wasn't easy. Had to battle with Tapestry's undocumented JavaScript scaffolding, Tapestry-IOC, etc. Had to monkey-patch a some Tapestry's JS files. Not good. End product wasn't compatible with Tapestry 5.4 as well.
Overall, Tapestry's Ajax support seems half-baked and isn't realty usable for production software without a lot of workarounds, patches or custom code.

Anya is live and ready to show you everything. Watch her strip, dance, and perform exclusive shows just for you. Interact in real-time and make your fantasies come true.
Free to watch • No registration required • HD streaming
My Journey with #tapestry5 and #JavaEE
Part 7 - Community Participation
Since I was pretty deep into Tapestry by now, I wanted to get some annoyances and fixed incorporated into Tapestry source code. Almost immediately, I got pushback. To be fair, every new open source project I try to contribute to has some aversion to new contributions, but this was above and beyond. The excuse du jour was ‘compatibility’. I did realize that Tapestry has political issues with breaking compatibility, but most of my contributions would not break compatibility anyway, and I felt like this excuse was overused. Another common excuse was ‘code dumping’. Basically, if the code was not written by the PMC members, any contribution was rejected based on one of these excuses, but whenever a PMC member wanted to do something, ‘compatibility’ or ‘code dumping’ excuses went out the window.
I felt like my valuable time was wasted trying to contribute. I gave up soon after and published my own module, which required hacks and workarounds, but it worked.
As a byproduct of trying to contribute to Tapestry, I took a good look at the source code. Although it was good, there were a lot of Not-Invented-Here-isms in the code. I saw a clear tendency to rewrite parts that are already written by some other open source project, for, what I thought, are silly reasons. But at the end of the day, it all made sense, since if Tapestry committers weren’t willing to accept willing contributions, they wouldn’t incorporate existing code from other projects for the same reasons.
On the other hand, when trying to contribute to JavaEE, I was welcomed right away. The attitude really shined, and I was able to contribute valuable bug fixes without too much hassle.
These days, the not-invented-here attitude has no place in software development world.
My Journey with #tapestry5 and #JavaEE
Part 6 - Zone update color
When Tapestry dynamically updates web pages in Ajax, the updated section, or a Zone in Tapestry's parlance, gets highlighted. I liked that feature and wanted to keep it, but the color of this highlight was hardcoded yellow and wasn't fitting into my web site style.
I decided to change it, which didn't sound like it would be a big deal. How wrong I was. The color was so tightly integrated within Tapestry's infrastructure and was hard-coded. It was impossible to change without overriding a big tapestry infrastructure JavaScript file.
That's what I had to do, and also integrated with Tapestry-IOC so I can get the color passed as a parameter to components.
Unfortunately, it took days and days of debugging to get it right.