What kept our small team of Java software engineers highly productive for five years

For the past five years I’ve been leading a small group of highly productive Java software engineers. Together, we maintained three medium to large sized enterprise applications. We developed many features, finished a number of big projects, and did huge refactorings. In addition, we lived through two product launches for the general public.

Two of the applications were well structured monoliths while one of them was a well structured modular monolith. Together they had a total of 150 independently deployed units.

Here are what worked best for us.

  • Involving everyone in the decision making process
  • Continuous Integration
  • Maintainable integration tests
  • Visibility into the CI/CD pipeline
  • Module dependencies instead of repository coordinates
  • Calendar Versioning

Involving everyone in the decision making process

We had weekly meetings with team members where we talked about everything that seems interesting to us. We discussed every architectural decision in those meetings.

Continuous Integration

I highly recommend Martin Fowler’s article on Continuous Integration if you are not familiar with the concept.

We didn’t protect development branches in any of our repositories. Everyone worked on their local branches and pushed to origin whenever they wanted. We never mandated merge requests. We ended up integrating our changes a few times a day which helped us eliminate a lot of bugs at early stages during development.

I suggest you follow these discussions on Twitter: @kief, @martinfowler

Furthermore, original author of git-flow recently updated his article adding a “Note of reflection“.

Maintainable integration tests

We started building two integration test suites at first. One using SoapUI and another using JUnit. After a while JUnit test suite proved to be much easier to maintain than SoapUI projects. SoapUI stores projects in a single file. Keeping and diffing that ever changing file in Git is hard. As a result, we kept our SoapUI test suites only for local testing and built our complete integration test suite with JUnit.

Visibility into the CI/CD pipeline

Jenkins doesn’t provide a decent UI/UX. Blue Ocean looks modern but it doesn’t work if you have a lot of pipelines. We had 600.

An email notification from Jenkins for an unstable job doesn’t provide enough motivation for developers to fix the underlying issue. On the other hand when a beautiful dashboard reflected on a big screen goes ugly because of an unstable job people will notice. We developed that dashboard, procured a big display and advertised the status of our CI/CD pipeline to everyone on the same floor with our team.

Module dependencies instead of repository coordinates

There were a handful of common modules for every application we developed. While our team leads were responsible for maintaining those common modules we didn’t hide source code of the common modules from other team members.

We didn’t hide common module artifacts behind repository coordinates either. Every application module added them as module dependencies. By doing so we made sure that every single change was instantly available to every developer.

Calendar Versioning

Keeping track of version numbers for 150 artifacts is a cumbersome job. I hated maintaining our legacy versioning scheme based on SemVer. Our decision for switching to CalVer was well received by test and DevOps teams as well. Everyone was instantly happy and no one ever missed SemVer.

Bonus material: Monorepos

We put every independently deployed module into its own repository. As a result, there were 150 repositories that we maintained. If I were to take over those three applications today I would without hesitation combine all those repositories into three monorepos. For many scenarios pros of using monorepo far outweighs cons of it.

Project Coin

Project Coin kapsamında JDK çekirdek sınıflarında ilk güncelleme yapıldı. Bu güncelleme ile JDK çekirdek sınıfları Diamond operatörünü kullanır hale geldiler.

--- a/src/share/classes/java/lang/String.java   Wed Jun 30 16:11:32 2010 -0700
+++ b/src/share/classes/java/lang/String.java   Mon Dec 20 13:47:04 2010 -0800
@@ -2330,7 +2330,7 @@ public final class String
int off = 0;
int next = 0;
boolean limited = limit > 0;
-            ArrayList<String> list = new ArrayList<String>();
+            ArrayList<String> list = new ArrayList<>();
while ((next = indexOf(ch, off)) != -1) {
if (!limited || list.size() < limit - 1) {
list.add(substring(off, next));

Cloud hosting nedir?

Geleneksel hosting işinde hosting firması müşterisine bir sunucu kiralar. Bu sunucuda koşacak olan işletim sistemi, uygulama sunucusu ve veritabanı sunucusu müşteri tarafından kurulur. Bütün güvenlik prosedürlerinin uygulanması müşterinin sorumluluğundadır. Ziyaretçi sayısı arttığında clustering yapmak müşterinin sorumluluğundadır. İşletim sistemini, uygulama sunucusunu ve veritabanı sunucusunu güncellemek müşterinin sorumluluğundadır.

Cloud hosting işinde ise müşterinin tek sorumluluğu kendi uygulamasını kodlamaktır. Bunun dışında müşteriye başka bir sorumluluk bırakılmaz. Uygulamasının hangi sunucu üzerinde çalışacağını, hangi SQL veritabanını kullanacağını, işletim sisteminin ne olacağını müşteri bilmez. Müşteri hosting firmasına yalnızca war (ROOT.war) dosyasını emanet eder. Güncelleme ve cluster işlemleri tamamen otomatize edilmiştir.

Cloud servislerinde varsayılan Java kütüphaneleri değiştirilmiş ve bazı özelliklere erişim kısıtlanmıştır. Örneğin dosya sistemi ve socket işlemlerine izin verilmez veya kısıtlı erişim sağlanır (yalnızca kendi uygulamasının bulunduğu dizine erişim gibi). Yazılımcı klasik Java Logging API‘sini kullanır fakat arka planda loglar dosya sistemi yerine merkezi log sunucularına iletilir. Müşterinin kendi loglarına web üzerinden erişimi sağlanır. Cron benzeri job queue API’si sağlanır. Resim ve video gibi SQL veritabanına yazmanın uygun olmayacağı veriler (blob) için özel servisler sağlanır. SQL veritabanına alternatif olarak NoSQL ve key/value store servisleri sağlanır.

Ben Java web uygulamaları için özelleştirilmiş cloud servisinin resmini çıkardım. Bu cloud servislerinin Java’ya veya web uygulamalarına has olduğu anlamına gelmez. C ile geliştirilmiş uygulama çalıştırmak için özelleştirilmiş cloud servisi de olabilir. Nasıl olacağını okuyucunun hayal gücüne bırakıyorum.

Notlar

Her zaman bazı istisnai durumlar olabilir. Örneğin aşırı titiz bir müşteri için dedike servis sağlanabilir. Böyle bir müşteriye uygulamasının diğer müşterilerden ayrı bir ortamda çalışacağı garanti edilirken, diğer müşterilerin kullanamadığı servisler sağlanmaz.

Cloud hosting sağlayıcıları

http://en.wikipedia.org/wiki/Category:Cloud_platforms

Yazılım sürecinde test etme ve kullanılabilirlik

Bir fırsatı ürüne çevirmek için :
  1. Hayal edin,
  2. Basit düşünün (KISS : Keep it simple stupid),
  3. Hayal edin,
  4. Basit düşünün,
  5. Çizin,
  6. Tartışın,
  7. Basit düşünün,
  8. Çizin
  9. Tartışın
  10. Çizin
  11. Yazın,
  12. Test edin,
  13. Yazın,
  14. Test edin,
  15. Yazın,
  16. Test edin,
  17. Yazın,
  18. Test ettirin,
  19. Yazın,
  20. Test edin,
  21. Test ettirin,
  22. Yayınlayın,
  23. Test edin,
  24. İzleyin (dönüşleri takip edin).
  25. goto 1: (yeni özellik geliştirme için)

https://erkyazilim.com.tr/blog/2009/11/yazilim-surecinde-test-etme-ve-kullanilabilirlik

Reported by Mustafa ULU

Mart 2008’de rapor ettiğim bu güvenlik açığı Ekim 2009’da giderildi.

SA-CONTRIB-2009-081 – Abuse – Cross Site Scripting

The Abuse module enables users to flag nodes and comments as offensive, bringing them to the attention of the site maintainer for review. The module suffers from a Cross Site Scripting (Cross Site Scripting) vulnerability. Such an attack may lead to a malicious user gaining full administrative access.

O zaman gönderdiğim e-posta

Abuse module displays flagged nodes in a moderation queue without applying filters (without calling node_view) on them.

Module version: abuse 5.x-1.x-dev at (http://drupal.org/node/123349)

Steps to reproduce:

  • Install abuse.module.
  • Enable flagging of any content type at “admin/settings/abuse” page.
  • Flag a node by using “Flag as offensive” link on “node/#nid” page.
  • Go to “admin/content/abuse” page. Under any tab one can see unfiltered node contents.

Keyifli bir okuma: Yazılım Geliştirme Süreçleri – 1

Çarklar

Amerikada yakın zamanda Jr. Software Architect olarak işe başlayan birisinin ilk izlenimini anlattığı yazısını paylaşıyorum.

Yazarın Hakkımda sayfasında yazdığı şu cümlelere kısmen katılıyorum:

“Eskiden programlama dilleri benim amacımdı. Özellikle C ve C++ dili konusunda uzmanlaşmak istiyordum. Şu an biliyorum ki, tüm programlama dillerinin canı cehenneme. Diller sadece bir araç. Önemli olan programladığımız alet her ne ise onun inceliklerini anlamak, o makineyi analiz etmek, ve çalışması için gerekli olan koşulları yerine getirmektir.”

https://www.hasanozgan.com/2009/08/yazilim-gelistirme-surecleri-1