Posts

Observability of the Java Virtual Machine

Image
The JVM is one of the most observable runtimes. It provides us lots of tools for troubleshooting a JVM application in production. 1. Thread observability Threads are how the JVM actually does work. When something is wrong in production, the symptom is almost always a thread: stopped, blocked, leaking etc. Thread dumps work on any JVM with no  instrumentation, no agents, no restarts. <Example project link with /threaddump endpoint>         // (1) Deadlock — two threads grab the same pair of locks in opposite order.         new Thread(() -> grab(LOCK_A, LOCK_B), "deadlock-A-then-B").start();         new Thread(() -> grab(LOCK_B, LOCK_A), "deadlock-B-then-A").start(); http://localhost:8080/actuator/threaddump To list the JVMS, we can use the command below. PS C:\observe-jvm> jps -lv 25296 jdk.jcmd/sun.tools.jps.Jps -Dapplication.home=C:\Program Files\Microsoft\jdk-21.0.3.9-hotspot -Xms8m -Djdk.module.main=...

Saga Nedir?

"Saga", Domain Driven Design ve CQRS sözkonusu olduğunda sıklıkla duyduğumuz bir kavram. Saga, birden fazla Aggregate ile ilişkili bir "long-running business transaction" konusunda bize yardımcı olan bir yapı. Saga'lar Aggregate üzerinde doğrudan bir state değişikliği yapmıyor fakat oluşturduğu Command mesajları ile dolaylı olarak state değişikliğine sebep oluyor. Sagalar aynı zamanda Command nesnelerini ele alabilir ve Event'lere abone olabilir. Kısacası Saga, CQRS implementasyonlarında sıklıkla karşımıza çıkan ve DDD terminolojisinde ApplicationService adı verilen kavramla ilgili bir yapı. Bir sonraki yazıda örnek bir Saga implementasyonunu paylaşıyor olalım. Bahadır Konu bah(dot)konu(at)gmail(dot)com

Axon Framework ve tanımı değişen Event sınıfları

Axon Framework kullanarak geliştirdiğim CQRS uygulamasında karşılaştığım bir sorundan ve çözüm yollarından bahsedeceğim. Uygulamada "event sourcing" yöntemini kullanıyorum ve Event nesneleri SQL veritabanına serialize edildikten sonra kaydediliyor. Serialize edilen veri içerisinde Event sınıfının tam ismi (paket ismi ile birlikte) geçtiği için, bu isimde yapılan bir değişiklik (örneğin paket yapısındaki bir refactoring) benim mevcut event verilerim ile uyumsuz hale geliyor. Böyle durumlarda serialize edilmiş event verilerinin migrate edilmesi için 2 yöntemden bahsediliyor: 1) Genellikle bu durumda bir "Upcaster" yardımıyla eski tip eventler deserialize edilir. Yani uygulamamız deserialize sürecinde eski eventleri ele alabilmek için ayarlanmış olmalıdır. Axon framework'te EventUpcaster sınıfı incelenebilir. 2) Paket yapısında bir değişiklik olduğunda ve XStram kullanılıyorsa, eski paketten yeni pakete bir "alias" tanımlanabilir. // makes sure old packag...

Loglama işleminin "spy appender" yoluyla test edilmesi

Loglama işlemi yapan bir sınıf, Logger nesnesini şu şekilde elde ediyor olsun: Logger log = Logger.getLogger(FinalExceptionHandlerImpl.class.getName()); Burada loglama işleminin yapılıp yapılmadığını test edebilmek için, Logger sınıfına bir "casus" appender enjekte ediyoruz. Sonuçta test sınıfımız aşağıdaki şekilde oluyor: @RunWith(MockitoJUnitRunner.class) public class FinalExceptionHandlerImplTest { private SpyAppender spyAppender = new SpyAppender(); FinalExceptionHandlerImpl handler; @Mock private MessagesUIConnector messagesUIConnector; @Before public void setUp() throws Exception { handler = new FinalExceptionHandlerImpl(); Logger.getLogger(FinalExceptionHandlerImpl.class.getName()) .addAppender(spyAppender); } @Test public void shouldLogErrorForException() throws Exception { Exception exception = new IndexOutOfBoundsException("message"); handler.handleException(exception, mess...

Mockist testler ve custom matcher yazımı

Çalıştığım projede Mockito testlerini yoğun olarak kullanıyoruz ve birçok durumda custom matcher yazmamız sözkonusu oluyor. Aşağıdaki mock test örneğine bakalım: @Test public void saveSkillAssignmentApprovalShouldCreateNew() throws ServiceException { Skill skill = new SkillBuilder().buildSample(); SkillAssignmentDao dao = mock(SkillAssingmentDao.class); //... // manager kendi icerisinde dao.save(..) metodunu cagiriyor. SkillAssignment result = skillAssignmentManager.saveSkillAssignmentApproval(approver, skill, skillLevel); // burada assertion icin result'i kullanamayiz cunku mock dao tarafindan set //ediliyor. assertThat(result.getSkill(),equalTo(skill)); // ?? } Burada test ettiğimiz skillAssignmentManager nesnesinin geri gönüş değeri yoluyla sınama yapamayacağımız açık. O nedenle mock olarak kullandığımız dao metoduna geçilen parametreyi sınamamız gerekiyor: @Test public void saveSkillAssignmentApprovalShouldCreateNew() throws S...

"Open Session In View" kalıbı

Bu kalıp Hibernate ile Java ağ uygulamaları geliştirirken ortaya çıkan bir probleme istinâden belirmiştir. Bir HTTP isteği web sunucusuna gelsin ve sunucumuzda yüklü olan kontrölcü servlet isteği ele alsın. Örneğin: protected ModelAndView handleRequestInternal(HttpServletRequest request, HttpServletResponse response) throws Exception { String expenseId = request.getParameter("expenseId"); Expense expense = expenseService.loadWithId(expenseId); return new ModelAndView("edit_expense", "expense", expense); } Burada expense nesnesi tembel bir şekilde elde edilmiş olabilir (lazily loaded). Bu durumda henüz ihtiyaç olmadığı için veritabanı tarafında bir SELECT sorgusu çalıştırılmış değildir. Fakat gösterim sayfasına (view) gönderdiğimiz nesnenin içindeki değerler, program akışı view kodlarına geldiğinde okunmak istenecektir. İşte burada bir sorun ortaya çıkıyor ki o da şu: Bizim servis metodumuz yükleme (load) işlemini yaptıktan sonra Sessio...

Kaynak Kod Versiyonlama Sistemleri ve Subversion

Üzerinde çalıştığımız projenin kaynak kodlarını ve kodda yapılan her türlü değişiklikleri depolayan yazılım sistemlerine "kaynak kod versiyonlama sistemleri" diyoruz. Bu alandaki ürünlere baktığımızda açık kaynak kodlu projelerden CVS ve Subversion, ticari ürünlerden ise Clearcase ve Visual SourceSafe sayılabilir. Versiyonlama sistemi kullanımı özellikle birden fazla geliştiricinin çalıştığı projelerde elzemdir. Maalesef ülkemizde halen versiyonlama sistemi kullanmayan firmalar olduğuna şahit olmaktayız. Fakat genellikle yaygın olarak kullanılmaktalar. Hatta bazı firmalar ilanlarında, bir geliştiricilerde aradıkları özelliklere şunu ekliyorlar: - Düzenli check-out / check-in yapabilecek... Visual Studio ile tümleşik çalışan Visual SourceSafe, kullanımı çok kolay bir yazılım. Biz, Java tarafındaki Subversion sistemine bir göz atalım: Eğer Eclipse geliştirme ortamını kullanıyorsak, Subversion için bir eklenti mevcut. "Subclipse" adındaki bu eklentiyi Eclipse'in...

Servis sınıfları ile "Transaction" yönetimi

Kurumsal uygulamalarda en önemli konulardan birisi de birbirinden ayrılamaz veritabanı işlemlerinin bir "transaction" içerisinde yapılmasının sağlanmasıdır. Çok katmanlı (layer) uygulamamızda bu işin yapılmasından hangi katman sorumlu olmalıdır? Diğer katmanların durumu nedir? Yaygın olarak kullanılan "veri erişim nesnesi" (DAO) kalıbını kullandığımızı düşünelim. Bunların yer aldığı veri erişimi katmanı, transaction yönetiminden sorumlu olabilir. Fakat en çok kabul görmüş yöntemlerden birisi, transaction kontrolünün "service layer" denilen bir katmanda yapılmasıdır. Böyle bir yapıda gerçekleşen olaylar şöyle özetlenebilir: 1- Kullanıcı arayüzü katmanına ilişkin "controller" kodu, bir servis metodunu çağırır. Örnek: class StudentController... { //... studentService.addRegistration(...); } Görüldüğü gibi burada kullanıcı arayüzü kodu, sadece tek bir servis metodunu çağırmakta ve gerisine karışmamaktadır. Transaction kontrolünden sorumlu ...

Popular posts from this blog

The WeakReference class, monitoring memory leak and garbage collection in a Java application

Simplescalar Simulator - Part 2: sim-outorder.c

Kotlin Language Features Related to Null Handling