Java’da private metodlari test etmek

Arada sırada Java ünite testlerinde private metodları da test etmek gerekir. Hatta fonksiyonel bir bakış açısıyla, bir sınıftaki tüm private metodları teste dahil etmek de gerekir diyebiliriz. Gerçi bu fikre karşı çıkmak isteyenler, bir sınıfın API’ının o sınıftaki public metodlar olduğunu ve sadece onların test edilmesinin yeterli olacağını söyleyebilirler ama ben elimden geldiği kadar tüm metodlarımı kontrol etmek istiyorum.

Reflection API

Bu durumda JUnit gibi bir kütüphane ile çalışırken kullanılabilecek basit bir yöntem var. Tek yapmanız gereken, ilgili metodunuzu Reflection API yordamıyla bulmak, onun erişilebilirliği ile ilgili kısıtı kaldırmak ve sonra gene Reflection kullanarak çalıştırmanızdır. Sonrasında Assert nesnesi ile istediğiniz şekilde sonuç kontrolü yapabilirsiniz.

Basit bir örnek vermek gerekirse:

Örnek sınıf:

public class BaseballElimination {

 private final int numberOfTeams;

 private int[] wins;
 private int[] losses;
 private int[] remaining;
 private int[][] gamesAgaints;
 private String[] teams;

 private int findIndexOfTeam(String team) {
     for (int i = 0; i < numberOfTeams; i++) {
         if (teams[i].equals(team)) {
             return i;
         }
     }

     throw new IllegalArgumentException("team not valid");
 }
}

Örnek test:


@Test
public void testIndex() throws Exception {

    Method indexMethod = BaseballElimination.class.getDeclaredMethod("findIndexOfTeam", String.class);
    indexMethod.setAccessible(true);
    int index = (Integer) indexMethod.invoke(division, "Atlanta");

    Assert.assertEquals(0, index);
}

Gördüğünüz gibi, 3 satır kod yazmak yeterli, herkesi başarılı ünite testleri!

Ekleme, eger statik metodlari test etmek istiyorsaniz, tek yapmaniz gereken indexMethod.invoke() metoduna null gondermek.

JBoss – Loglama hakkında

Herkese merhaba,

Ne yazık ki geçen ay yazamadım, bu ay da şimdilik kendime hatırlatma olması amacıyla, basit bir yazı hazırladım.

JBoss’ta loglama Tomcat vs gibi uygulama sunucularından biraz farklı. Hatta 7.1’deki bir sorundan ötürü diğer ortamlarda çalışan log4j düzeninizin çalışmadığını farkedebilirsiniz. Neyse ki JBoss, sizin handle edilmeyen logger çağrılarınızı kendisi handle ediyor fakat siz belirtmediyseniz bir yere yazmıyor. Bunların yazılması için yapmanız gereken bir kaç işlem var:

1 – İlk olarak uygulamanız için loglama yapacak logger’ı tanımlamak. Bunun için standalone.xml ayar dosyasını açmanız gerekiyor. (dosya JBOSS_HOME/standalone/configuration/standalone.xml).

2 – Dosyanın içinde <subsystem xmlns=”urn:jboss:domain:logging:1.1″> noktasını bulun. Bu xml elementinin içine

<logger category=”proje.paketinin.ismi”>
<level name=”TRACE”/>
</logger>

şeklinde logger elemanını tanımlayın.

3 – Daha sonra yine aynı subsystem elemanının içine kendi handler’ınızı tanımlayın, ben örnekte periodic file handler tanımlıyorum.

<periodic-rotating-file-handler name=”APPLICATION”>
<level name=”DEBUG”/>
<formatter>
<pattern-formatter pattern=”%d{HH:mm:ss,SSS} %-5p [%c] (%t) %s%E%n”/>
</formatter>
<file path=”/home/username/log_jboss/app_name.log”/>
<suffix value=”.yyyy-MM-dd”/>
<append value=”true”/>
</periodic-rotating-file-handler>

4 – Son olarak da root logger’ının içinde demin tanımladığınız handlerı ekleyin.

<root-logger>
<level name=”INFO”/>
<handlers>
<handler name=”CONSOLE”/>
<handler name=”FILE”/>
<handler name=”APPLICATION”/>
</handlers>
</root-logger>

 

Tüm bu adımlardan sonra JBoss ve uygulamanızı tekrar başlatın. Ve yazılan logların keyfini çıkarın : )

JAX-WS Web Servisleri ve WSGEN

Herkese kısa bir yazıyla merhaba,

Yine daha sonra kendime not olması amacıyla yazdığım bir yazıyla karşınızdayım. 3. 4. kez bu hatayla karşılaşınca artık geri dönüp bir yerlere çözümü not etmek gerektiğine karar verdim.

Java’da web servislerinizi JAX-WS yordamıyla açmak diğer yöntemlere göre kısa ve kolay bir yol. Lakin bu şekilde çalışırken, SoapBinding özelliğini DOCUMENT olarak girerseniz yada boş bırakırsanız yapmanız gereken başka işlemler de var.

Bu durumda sadece derlemeyle oluşturduğunuz sınıflar yeterli olmuyor. JAX-WS için gerekli olan diğer sınıfları ve dosyaları(wsdl ve xsd) sizin üretmeniz gerekiyor. Aksi takdirde şu meşhur:

Wrapper class paket_ismi.jaxws.methodName is not found. Have you run APT to generate them?

Hatasını alıyorsunuz.

Bu dosyaları üretmek ise oldukça kolay. Tek yapmanız gereken wsgen aracıyla gerekli dosyaları oluşturmak ve projenizde gerekli paketin içine taşımak. Bundan sonra tek yapmanız gereken tekrar bir paket oluşturmak!

Gerekli wsgen komutu örneği:

wsgen -keep -cp . com.organizasyon.adi.ws.WebServiceEndpoint

PS: Bu arada hep benim düştüğüm hataya düşmeyin, bu işlemi .class dosyalarında çalıştırmanız gerekli, .java dosyalarında çalıştırırsanız ClassNotFound exceptionı alırsınız : ).

Scala’da case classes, pattern eşleştirme ve exception handling

Evet arkadaşlar selamlar,

Bu blogda arada sırada Scala yazmaya çalışıyorum. Bu ay da Scala’nın bazı özelliklerinden kısaca bahsedeyim istedim. Bu yazıda case classes, kısaca pattern matching ve exception mantığından bahsedeceğim sizlere.

Case classes, normal class mantığından bir kaç sentaktik şeker vererek ayrılan bir olgu. Case class kullandığınız zaman constructorda verdiğiniz parametreler için otomatik olarak içerde private alanlar oluşturuluyor ve bu alanlara yine constructorda verdiğiniz parametre isimlerinden erişebiliyorsunuz. Bu sayede basit POJO lar oluşturmak oldukça kolay hale geliyor. Basit bir örnek vermek gerekirse:

case class Person(firstName: String, lastName: String)

val me = Person("Erkan", "Ahmet")
val first = me.firstName
val last = me.lastName

if (me == Person(first, last)) {
  println("Found myself!")
  println(me)
}

Gördüğünüz gibi bütün sınıf tek bir satırdan oluşmakta. Gerçi bu kavramın adındaki Case nedir diye düşünenleriniz vardır, az bekleyin.

Gelelim pattern matching’e. Java da bu mantık switch case ler üzerinden yürüyor bildiğiniz gibi. Yalnız bu yapı sadece primitif tipleri kontrol edebiliyor. Bu da sizi eninde sonunda bir integer a yada bir enum değerine kadar indirebiliyor. O kadar karmaşık sınıflar yazıyor ama karşılaştıramıyoruz.

Bu soruna Scala’da amcalar neşter atmışlar. Temelde Java’dan ayrıldığı bir kaç noktayı aktaralım:

  1. Case statementları birbiri içine girmezler, yani gidip de hepsine break yazmak zorunda değilsiniz.
  2. Case statementları bir değer dönerler, bunu olduğu gibi kullanabilirsiniz, bu sayede daha az satır kod yazmış olursunuz.
  3. Case statementlar, patternleri eşleştirebilirler, bunun en güzel örneği ise case class kullanımında görülür.

object Scenario{
def apply(user: String, action: GameElement) = {
action match {
case workout: Workout => new WorkoutScenario( workout, user )
case like: Like => new SocialScenario( like, user )
}
}
 }

 

 
Örnekte gördüğünüz üzere, action nesnesi match blokuna sokuldu. Match blokunda, bu action sınıfından türemiş diğer sınıflarla karşılaştırıldı. Bunlar Workout ve Like. Bunlardan hangisi ile eşleştiyse de, buna uygun bir nesne üretildi ve geri dönüldü. İşte ben buna factory pattern derim. Hatta demem, çünkü ortada pattern denecek kadar bir kod parçası yok. : )

Peki gelelim exception handlinge. Scala bu işe de el atmış durumda. Normalde bir noktadan exception throw ederdiniz. Burada sorun yok. Fakat yakalayacağınız yerde, her bir exception tipi için ayrı ayrı blok açar ve ne yapacağınızı şaşırdınız. Scala ise exception handling’de de pattern matching kullanarak, işimizi bir adım daha kolaylaştırıyor.

Örnek vermek gerekirse

</pre>
<address>try{

workoutItems.foreach(item => {
...
if (repeat <= set.repeat_number.toInt) {</address><address>              ....
throw BadgeWon("pushup badge won!")
}

})
}
})

}
catch {
case e:BadgeWon => println("found the badge: " + e.message)
case e => {
println("general exception" + e.getMessage )
e.printStackTrace()
}
}</address><address>
Gördüğünüz gibi çok daha kısa bir kod parçası ile, exceptionlarınızı da yönetmeyi başardınız. Scala kullandıkça özelliklerini daha da çok seveceksiniz.
Önümüzdeki yazıda function literals konusuna değinmek istiyorum, herkese iyi günler!

Exception Handler ve rahatlığı

Arkadaşlar merhaba,

Sizlere bu yazıda kısaca Spring MVC frameworkteki Exception Handler annotationından bahsedeceğim. Bu konu özellikle REST arayüz yazan arkadaşların işine gelebilecek bir teknik.

spring

spring

Malum bir REST arayüz yazdığınız zaman esasen bir API yazmış oluyorsunuz. Haliyle API nizin bir çok metodu oluyor. Bu metodların hepsinde exception handle etmek de can sıkıcı bir durum. Bir süre sonra her metodda exception handle ederseniz ortaya ciddi miktarda tekrarlayan kod çıkacaktır.

Bunu önlemek için geliştirilen çözümlerden biri filtreleri kullanarak fırlatılan exceptionların filtre seviyesinde yakalanması ve işlenmesidir. Ama bu çözüm bütün web trafiğiniz üzerinde  çalışacağından, tüm kodunuzun buna uyumlu olmasına özen göstermeniz gerekiyor.

Diğer yandan yine Spring’in önerdiği bir çözüm ise, hata durumlarına karşı çözücüler yazarak kullanıcıyı istenilen hata sayfalarına yönlendirmek. Fakat bu da REST arayüz yazan  arkadaşların işine pek gelmez çünkü bizim dönmek istediğimiz değerler genellikle JSON nesneleri oluyor.

Bu durumda ortaya ExceptionHandler annotation ı çıkıyor. Bu annotation ı kullanmak için ilgili controllerin, yakalayacağı exception tipini vermeniz gerekli. Kullanacağı metodun içerisinden de istediğiniz loglamaları yaparak gerekli hata nesnesini dönebilirsiniz. Bu bir JSON nesnesi de olabilir, istediğiniz her hangi bir model ve view nesnesi de olabilir.

@ExceptionHandler(AddressNotFoundException.class)
   @ResponseStatus(value=HttpStatus.NOT_FOUND)
public ModelAndView handleAddressNotFoundException(AddressNotFoundException exception) {
ModelAndView modelAndView = new ModelAndView(“nocontact”);
modelAndView.addObject(“message”, exception.getMessage());
return modelAndView;
}

Bu örnekte ModelAndView sınıfı kullanılmış ama burada pek ala ResponseBody annotation ile birlikte bir POJO dönülebilirdi. Bu metodun güzelliği olayı inheritance ile birlikte kullanınca ortaya çıkıyor. Sadece tek bir exception handler metoduyla bütün bir REST apinin exception sorununu çözebilirsiniz. Tek yapmanız gereken Exception Handler metodunu, kullanacağınız base bir controllerın içine yerleştirmek ve işte sağlam yapınız artık hazır!!

Exception ve Throwable Ayrımı

Herkese merhaba,

4-5 saattir bir hatayla uğraşıyorum. wsimport marifetiyle bir web service clientı oluşturdum ve endpoint interface ini alarak çalışmaya başladım. Fakat kodu çalıştırdığımda, ne zaman endpoint interfaceini almaya kalksam kod sessiz bir şekilde hata veriyordu. Sadece bir controllerımdaki finally’e yakalanıyor, sonra da başarısız cevap dönüyordu.

Nasıl olur da hiç bir exceptiona yakalanmaz diye düşünürken, Java’da sadece Exception fırlatılmadığını, Throwable da fırlatıldığını hatırladık bir şekilde. Bu durumda Throwable aradık ve sonuca ulaştık, en azından yaşadığımız hatayı bulabildik. Aklıma iyice kazınsın diye de sizlerle paylaşıyorum arkadaşlar, dikkatli olun ;).

java throwable yapısı

java throwable yapısı

Spring Web Serviceleri ve Spring Namespace Handler not found hatasi

Gençler selam,

Uzun aradan sonra bir kaç cümle yazayım dedim, baktım ki evvelden iki madde not almışım bunlardan bahsedeyim diye. Yeri gelmişken sizlere de aktarayım.

Spring süper bir framework, kabulümüzdür. Fakat arada sırada kullanıcıya yardımı dokunmayan hata mesajları da verebiliyor, sonucunda da çokca vakit kaybedebiliyoruz. Ben geçenlerde benzer bir vakit kaybı yaşadım, sizlerle de paylaşayım da mümkün olduğu kadar siz aynı vakti kaybetmeyin.

Spring Namespace Handler not found diye bir hatası var, bu genelde aynı spring jarinin farklı versiyonlar üzerinden birden fazla şekilde uygulamaya katmaktan oluyor, keşke Spring kendisi bunu bize söyleyebilseydi. : )

Ayrica jax-ws spring eklentisini kullanmaya gerek yok, springin SimpleJaxWsServiceExporter sınıfı inanılmaz kullanışlı. Tek sıkıntısı, bu exporter web servisinizi ayri bir port üzerinden sunuyor. Bu durumda aynı uygulama içinden web servisi de sunmak imkansız hale geliyor, denediğinizde orada zaten bir uygulama olduğu hatasını alıyorsunuz.

Herkese iyi geliştirmeler.

Tomcat – Çıldırmaya devam

Çok enteresan bir sorunum var son günlerde. Tomcat ve Java’da enteresan olmayan gün zaten geçmiyor. Neyse soruna dönelim.

Büyük ihtimalle memory leak sahibi bir uygulama var elimde. Bunu sağlıklı bir uygulama ile birlikte kullanmam gerekiyor. Herşeyi anlarım da, neden tüm uygulamaları undeploy ettikten sonra, hatta webapps altından bile dizinlerini kaldırdıktan sonra tekrar bir uygulama deploy etmeye kalktığımda patlarsın Tomcat, işte onu anlamam. Yani ne ilgisi var?

E hani garbage collection hani üstün alman teknolojisi?

Tomcat – loglama ve çıldırtan ayarlar

Tomcat üzerinde apache commons ile loglama yapabilmek için

tomcathome/conf/logging-properties dosyasını güncellememiz gerekiyor. Bu dosyanın içine şu satırları yerleştirmek yeterli :

org.apache.catalina.realm.level = FINE
org.apache.catalina.realm.useParentHandlers = true

sonra örneğin console handler ınızın seviyesini de uygun şekilde ayarlayarak debug mesajlarını görebilirsiniz. Ama burada önemli bir nokta var ki, eğer console handler da FINE seviyesinde çalışırsa console üzerine sürekli mesaj yağdığını göreceksiniz. Bunun için paket mantığını kullanarak loglama seviyesini belirlemek daha mantıklı:

com.sirket.projex.core.Token.level = FINEST

Burada Token sınfının loglama seviyesini FINEST a alarak sadece o sınıftan aşırı loglama almayı garantiliyoruz.

tomcat

kedi güzel ama he

Daha sonra unutmamak için yazıyorum bunları : ). Sevgiler.

He bunu da hallederim diyosan, bir bakiver : http://wishjoin.com/post/1328