
Experience Put into Words
Notes on Architecture, Experience, and AI
A technical blog on software architecture, developer experience, and applied AI, written from the perspective of an experienced software engineer.


Finite and Infinite Startups
Three weeks ago, Adam Wathan, the creator of Tailwind CSS, released a podcast containing an honest confession – "We had six months left" – and an explanation of why they had to let some folks go. For days, my social media feeds buzzed with discussions about the subject. I saw everything from "AI is killing startups" to "he doesn't know how to run a company," and even ridiculous accusations of deliberate exaggeration (why say 75% when it "only" affected three people). I never cease to be amazed by how many people fill the gaps left by scant information with assumptions and rush to judgment.

Multi-Hat Disorder - Building Personal Website Like an Enterprise App
While I’ve been focused on helping companies grow, my personal brand has taken a hit. I’ve never been interested in being an influencer or a showman, but I’ve come to realize that technical expertise alone isn’t enough anymore. It seems that, in today's world, a "personal brand" carries as much, if not more, weight than the substance itself.

Operational vs. Strategic DevX
It is 2022, and Developer Relations (DevRel) and Developer eXperience (DevX) teams are to be found in almost any organization whose offering has anything to do (even if very little) with software developers. Many prominent examples prove that DevX-done-well significantly contributes to the organization's success. Way more organizations hope to replicate the success story by merely "sprinkling a DevX spice" on top of their traditional marketing/sales-driven practices.

The macroscale of micro frustrations
I have experience with two GPS navigation systems. My Android phone has Google Maps. My car also has one, powered by TomTom. All things being equal (as when I drive my car) both are in direct competition. I have to put my trust in one of them. I can't objectively tell which one is better. Yet, somehow I tend to use one of them often and avoid the other.

From DevRel to Developer eXperience
At the time of writing this, the DevRel team at AxonIQ consists of four people (including me). We are two Developer Advocates, a Community Platforms Developer, and a Learning Experience Designer. The flat structure makes perfect sense at this team size. But our plans are huge, and four people can only cover so much ground. Clearly, the team needs to grow.

What dev heck?
There are a lot of publications explaining how crucial DevRel (Developer Relations) and DX (Developer eXperience) are for software vendors. It seems more, and more of them establish such teams. The goals they hope to achieve probably vary a lot. Yet, according to the 2021 edition of State of Developer Relations report, most often, such teams report to marketing. Is DevRel a fancy name for developer-focused marketing then?

Data classes in Java
I recently joined AxonIQ to help them evolve their Developer Relations to the next level. One of the things I am currently evaluating is the steepness of the adoption curve of Axon Framework and Axon Server. One of the things that catch my attention was that, in almost all examples and demos, the classes representing events, commands and queries are written as Kotlin data classes (here is an example).

Conference Tracker
I try hard to keep track of conferences around the world. Mainly in a Google spreadsheet but also in a calendar shared with my team. I always thought that if all the DevRel folks were to share and merge their spreadsheets (or whatever else they use) into one single place, it would literally save days of work.

Would you attend one of those talks?
After several years of traveling around the world to speak at conferences, I needed a break. I have no idea what people like Venkat Subramaniam or Josh Long or Philipp Krenn are made of, but the assembly line that made me, certainly didn't use the same material. Luckily 2019 offered me that break and allowed me to focus on other things. It was great time but also kind of sad as I like to share the little things I know with other people and I like even more to learn from the people I meet. So I'm planning to be back on the road in 2020.

Fire alarm at software conference
I guess if you do something often and long enough, you get to experience all possible scenarios eventually. Leaving the conference venue due to fire alarm going on, was not necessarily on my bucket list but now I can both add it and scratch it off at the same time. It happened last week in Malmö, Sweden.

The fruits of our labor
I usually do rather technical talks around software architecture and design. Unless one is а famous storyteller, IT conferences would rather take one
more "What's new in the latest version of XYZ technology" than risk a bet on something that may end up anywhere between boring and sales pitch. I don't blame
them but that is why it is not often that I'm given the opportunity to speak about culture, purpose and all those non-measurable, soft, human things. Therefore
I'm extremely grateful Let's Manage IT invited me and trusted me to give exactly this type of talk. Knowing that I'll likely not have
the opportunity to present it anywhere else, I decided to convert it into a blog post and publish it here.

Java EE, EE4J, OSGi, ... and the paradox of choice
Not so long ago, I had very interesting conversation with someone who works on Java SE. At some point we discussed the donation of Java EE to Eclipse Foundation. I don't quite remember what statement I was making when I got this response (not a precise quote):


Cleaning up my GitHub mess
You know how it goes. You continuously stack stuff in the most convenient place (shelf, drawer, desk, ...) and it's all fine, up until the moment you no longer can find what you need. That is the day when you need to put everything else aside and clean up your mess. Not sure if it is Conway's Law to blame but this seams to happen to my repositories on GitHib. And today was the day when I no longer could recall which repo is under which account, where it resides on my local hard drive and if it's actually in sync. So today was my GitHub cleanup day. Just in case you need to cleanup yours or if you use one of my projects and something is no longer where you expect it to be, here is what changed.

What to expect in post-JPMS Java world
The atmosphere around Java 9 (and most notably JPMS a.k.a. JSR 376 a.k.a. Jigsaw) is getting really hot. Java community seams to be divided into 3 camps "developers who honestly believe JPMS can simplify modularity", "developers who have been dealing with modularity long enough to clearly see the issues Java platform architects don't want to see" and "developers who don't care (for now)". I personally think the 3rd group is by far the largest and this is the main issue and the main reason for the noise. Why? Because those are the developers who never cared about modularity. Most of them still don't care, but now they will be forced to learn about modularity. The question is what will they learn? Real modularity as described in Modulariy Maturiy Model or limited version of it wrapped in a package with a label "simple" on it?

Getting feedback live
I have spoken at quite some conferences over the last years. Part of the talks were just me speaking with some (hopefully not too ugly) slides behind me. Some were live demos. Either way, I'm almost never happy with my talks and therefore constantly looking for ways to improve. But in order to improve, first you need to know what your audience like and don't like. It all comes down to feedback and constructive criticism. Some conferences are quite good at collecting feedback. Polish Confitura is on the top of my list, sending me a document that not only shows how people voted but also all the comments from their online survey. Most conferences though don't bother to give feedback to speakers. Some don't ever bother to collect it. It's therefore been on my mind for a while to try to find a fun and easy way for attendees to provide feedback during (not after) my talk.

All Those Little Things
As developer advocate, I do a fair amount of traveling. Most of my journeys start with about an hour long drive to the airport. It's nice highway, not a big deal, easy to do it without needless stops. Yet I like to make one stop, get myself out of the car for a while, grab a coffee, smoke, ...


Micro-services or μServices
Yesterday someone very well known and respected in Java world (I didn't ask him for permission, so I'm not mentioning his name), approached Liferay's booth at JavaOne. He expressed his concerns about the word "μServices" in the message printed on our booth's wall. I wasn't there at the time this happened. I spoke with my colleagues few minutes later, as the non-developers were getting worried we made a terrible and embarrassing typo. As a non-native English speaker I wasn't quite sure what the exact argument was, but it was clear to me the person believed we should have used "micro-services" instead. I urged to reassure my colleagues this is not a typo but an important differentiator in today's buzzword driven world.

Java: 21 & Legally drunk!
I've stated that before but allow me to repeat myself: jPrime is one of my favorite conferences. I've been there two years in a row and to quote Karol Kaliński "it costs about 80 EUR, but can easily compete with western Europe conferences in terms of quality". This year, apart from great talks, fantastic atmosphere and the cute new Bulgarian JUG logo there was one more thing I was pleasantly surprised by, namely the conference's headline "Java: 21 & Legally drunk!".

Lessons learned from speaking at conferences
Time has come to resurrect the blog (again)! I was never much of a blogger but 3 years is ... oh well, almost a lifetime in software industry. It's not that I don't have anything to write about (quite the opposite in fact), it's just that I have always preferred more interactive communication. So for the last 3 years I was concentrating on presenting my thoughts and experience on various conferences rather than posting them here. A huge mistake apparently which someone pointed out to me recently. On the bright side - I learned a few things about being a conference speaker and I'll share them here. If you think going down that road, here is what to expect.



How to use CustomGlobalMarkup portlet to add image slider on every Liferay page
The original purpose of CustomGlobalMarkup portlet was to provide convenient interface for adding 3rd parties javascript code (like Google Analytics, Geminus, ClickTale, Crazy Egg, ...) to every page. However since it allows to add any markup it can be used to do some other cool things. For example - image slideshows.




Simple mobile device emulator in Firefox
After my "Pluggable mobile device detection" presentation during Liferay Europe Symposium a lot of people asked about the mobile device emulator I was using. The truth is, it's not a real "emulator" but a simple combination of html page and a Firefox user script. However, it does the trick and for most people seems to be good enough (at least for a start). So, I made a promise to share it and finally found the time to blog about it.

Liferay - preserve GWT portlet state between reloads
One of the problems with GWT (which is even more noticeable in portal environment) is preserving it's state between page reloads. In a GWT-only application (or single portlet on the page case) one can give user no other option but using only GWT controls to practically avoid page reloads. In most cases however this is not really possible nor wise thing to do. In portlet environments in particular, reloading the page is a very commmon thing to do, giving all portlets a chance to refresh their content after some action has taken place. The thing is, GWT portlets will, by default, render their initial state, which may not be what user expects.

Liferay GWT portlet - replacing GWT-RPC with JSON
This is a continuation of my previous post Liferay GWT portlet - how to make it "instanceable" and use GWT RPC. The approach described there uses Liferay specific functionality called PortalDelegateServlet. This way one can easily use GWT RPC which somewhat simplifies client-server communication. However if you need to develop a JSR 286 portlet you need a more standard compatible way of doing AJAX calls. For this reason JSR 286 defines serverResource method and this post will show how to refactor the code to replace GWT RPC calls with exchanging JSON messages using serverResource method.


Liferay GWT portlet - how to make it "instanceable" and use GWT RPC
Every once in a while somebody asks about writing Liferay portlets in GWT. It seems a lot of people are successfully using GWT with Liferay but surprisingly I couldn't find any complete tutorial on the subject. There are a of course tutorials explaining the basics but what they concentrate on, is how to build single-instance and client-side-only portlets. This is good enough to get you started but chances are sooner or later you'll need to place two instances of the same GWT portlet on the same page and/or implement GWT RPC to make use of the Liferay services.


Liferay plug-ins adapted to work with Liferay 6.0.5
As soon as Liferay 6.0.5 was released I decided to adapt my plug-ins to the newest framework version. But as we all know, being determined to do something is not the same as having the time to do it. The good news is, a few days ago I finally quit saying myself "never mind, you'll do it tomorrow" and started getting things done. And now I'm happy to announce that Custom Global Markup, Tailgate and Liferay-UI Taglib Demo are already upgraded to work with Liferay 6.0.5.

Just added 'J' in front of WebThumb
Yep, good guess, a Java API to bluga.net webthumb in now available. Making your Java application display website thumbnails is now something really easy to implement. Get your API KEY form bluga.net webthumb, download JWebThumb and start requesting and fetching thumbnails with just a few lines of code.

More "Simple" than "XStream"
I guess every Java developer dealing with JAVA/XML serialization/deserialization knows about XStream. I was using it for years until yesterday. What happened yesterday? I found out XStream dos not work out of the box with GAE. Well is's not exactly XStream's fault. A lot of stuff does not work properly with GAE due to its limitations and odd security restrictions. But my hope to quickly find patch/workaround, went away as soon as I realized the problem was reported to XStream over an year ago (http://jira.codehaus.org/browse/XSTR-566) and there is still no good solution.




Creating Liferay portlet with liferay-maven-sdk
This post will demonstrate how liferay-maven-sdk can be employed to build a Liferay portlet using Liferay's Service Builder feature. For this purpose we will create service-builder-portlet which is capable of displaying a list of players and adding a new player to this list. The model, persistence layer and data access services will be generated by Service Builder.


ATG session tracking cookies and subdomains.
If an ATG based web application is available under few subdomains (domain.com, www.domain.com, shop.domain.com) keeping track of session cookies across subdomains may be a challenge. Session tracking cookies (like jsessionid) usually do not have domain property set, which means they are sent back to exactly the same host they came from. So if visitors switch to another subdomain while navigating through the application they would most likely end up having a new session. Depending on what information session holds, the number of visitors and how many simultaneous sessions the server can handle, this may or may not be a problem.


Simple Java program to merge Excel survey results
A friend of mine recently asked me about merging survey results, which reminded me I had similar problem about an year ago and have written a peace of code to solve it. It's not a framework or user friendly application and it's not well documented. It was written in a couple of hours to solve particular problem, but in case anyone is interested here is so called SpreadSurvey.

Tagging the latest version of previously tagged files in CVS
Some time ago a set of files ware committed to CVS repository and tagged (lets say with TAG1) . These files have changed a few times since then. Today I needed to tag the latest versions of all files that have ever been tagged TAG1 with TAG2.