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 : ).

Jenkins ve Mercurial’da otomatik derleme şeysi

Merhaba arkadaşlar,

Gene kendime daha sonra bilgi olsun diye yazdığım bir not ile karşınızdayım.

Son günlerde Jenkins’teki iş sayısının çokluğu, polling(yoklama) mekanizması ile çalışmamızı imkansız noktaya getirmişti. 150’den fazla iş aynı anda Mercurial’dan sorgu çekmeye çalışınca sistemi oldukça yoran bir noktaya getiriyordu.

Bunun için Mercurial’dan push komutunu çalıştırdıkça Jenkins üzerinde derleme işlemi başlatmak gerekiyor. Bunun için Mercurial’daki hook mantığını kullanıyoruz. Daha fazla bilgi.

Neyse

Aynı mantıkla, hook üstünde çalıştırdığımız komutun da bir şekilde Jenkins’te iş çalıştırması lazım. Bunun için de Jenkins’in Build Token Root eklentisini kullanıyoruz. Eklentiyi kurduktan sonra tek yapmanız gereken jenkinste projenizi uzaktan tetiklemeye(remote triggering) açmanız ve bir token üretmeniz. Bu sayede kullanıcı adı ve şifre vermeden çalışabiliyoruz.

Örnek bir hook (projenin .hg/hgrc dosyasında tanımlanan):

 

[hooks]
changegroup = curl “http://jenkins.adresi.com/buildByToken/build?job=proje_adi&token=urettiginiz_token”

Bu sayede şakır şakır uzaktan derleme yapabilirsiniz.

Play Framework Sinir Stresleri – 1

Herkese merhaba,

Uzun aradan sonra play framework kullanarak birşeyler yapmam gerekti ki, yeni bir versiyonu çıkmış ve arkadaşlar  base versiyonu güncellemişler. Bunun sonucu olarak hepinizin eninde sonunda alacağı bir hata olan aşağıdaki güzellikle karşılaştım:

[error] (*:update) sbt.ResolveException: download failed: org.slf4j#slf4j-api;1.6.6!slf4j-api.jar
[info] Updating {file:/path/to/your/workspace/}asante...
[warn]  [NOT FOUND  ] org.slf4j#slf4j-api;1.6.6!slf4j-api.jar (0ms)
[warn] ==== local: tried
[warn]   /path/to/your/play/home/play-2.1.1/repository/local/org.slf4j/slf4j-api/1.6.6/jars/slf4j-api.jar
[warn]  ::::::::::::::::::::::::::::::::::::::::::::::
[warn]  ::              FAILED DOWNLOADS            ::
[warn]  :: ^ see resolution messages for details  ^ ::
[warn]  ::::::::::::::::::::::::::::::::::::::::::::::
[warn]  :: org.slf4j#slf4j-api;1.6.6!slf4j-api.jar
[warn]  ::::::::::::::::::::::::::::::::::::::::::::::
 İnternette aradığımda karşıma saçma sapan blog yazıları çıktı. Bu sebeple bu yazıyı yazma ihtiyacı duydum. Arkadaşlar bu hatanın sebebi, makinanıza kurulu olan Play versiyonu ile projenin Play versiyonunun farklı olmasıdır!!!! Bunu plugins.sbt den düzelttiğinizde sorun ortadan kalkacak.
Satir atlama
Örneğin sizde 2.1.1 vardı ve uygulama 2.1.3 kullanıyorsa bu hatayla karşılaşacaksınız demektir. Versiyonunuzu güncelleyin ve ilerlemeye devam edin.
Satir atlama : )
Web’de de karşınıza çıkan yok efendim 2.0.7 yap geçer, 2.1.5 te bu sorun yok gibi izansız ifadelere de önem vermeyin.
Satir atlama
İyi kodlamalar!

Mercurialda repoları web üzerinden paylaşıma açmak

Merhabalar,

Bu yazımda Linux üzerindeki bir Apache sunucusu üzerinden mercurial repolarının paylaşımını açıklamaya çalışacağım. Basit bir sırası var, aşağıdaki maddeleri takip edin lütfen.

  • İlk olarak gerekli klasörleri oluşturun, bunlar sırayla : /var/hg/repositories ve /var/hg.
  • Daha sonra /var/hg altında hgweb.config isimli bir dosya oluşturun. Dosyanın içine şunları yazın:

[web]
style = gitweb

[collections]
/var/hg/repositories = /var/hg/repositories

  • Ayar dosyasını oluşturduktan sonra Apache sunucusunun hgweb i çalıştırabilmesi için hgwebdir.cgi dosyasını oluşturun. Bu dosyanın içeriğine aşağıdakileri yazdırın.

#!/usr/bin/env python
from mercurial import demandimport; demandimport.enable()

import cgitb
cgitb.enable()

import os
os.environ["HGENCODING"] = "UTF-8"

from mercurial.hgweb.hgwebdir_mod import hgwebdir
import mercurial.hgweb.wsgicgi as wsgicgi

application = hgwebdir('hgweb.config')
wsgicgi.launch(application)

  • CGI betiğini hazırladıktan sonra apachenin kendi klasörüne dönüyoruz. Ubuntu da bu klasör /etc/apache2 şeklinde oluyor. Burada bir mercurial klasörü oluşturuyoruz. mkdir mercurial
  • Bu klasörün içine girip, mercurial.conf dosyasını oluşturuyoruz. Bu dosyanın içine şunları yazıyoruz:

ScriptAliasMatch ^/mercurial(.*) /var/hg/hgwebdir.cgi$1
<Directory "/var/hg/">
Options Indexes FollowSymlinks MultiViews ExecCGI
AllowOverride All
Order allow,deny
Allow from all
AuthType Basic
AuthName "Mercurial Repositories"
AuthUserFile /var/hg/hgusers
Require valid-user
</Directory>

Bu sayede demin oluşturduğumuz klasörün apache üzerinden servis edilmesini sağlıyoruz.

  • Mercurial’ın dışarı açılması için gerekli bir adım daha: apachenin içindeki sites-available klasöründe, az önce oluşturduğumuz ayar dosyasının sunulmasını sağlamak. Bunun için sites-available klasörüne girip, örneğin default dosyasına şu satır eklenmelidir: Include /etc/apache2/mercurial/mercurial.conf
  • Herşeyin normal olduğunu kontrol etmek için su komutu çalıştırın: sudo apache2ctl configtest
  • Daha sonra apacheyi tekrar başlatalım; eğer bir sorun olmazsa siteniz/mercurial adresine girdiğinizde güzei bir görüntü olmalı 🙂 :
$ sudo apache2ctl stop
$ sudo apache2ctl start

Unit Testing

Selamlar,

Bu aya da bir yazı yetiştirdim. Sayılır : )

Çalıştığım şirket için bir Unit Testing eğitimi hazırlamam gerekti. Bunun için kurguladığım sunumun dosyasını SlideShare üzerinden paylaşıyorum. Umarım başlangıç yapmak isteyen arkadaşlara bir yol açmış olurum.

İyi çalışmalar.

Link: Slide Share sunumu

Web sayfasından iPhone uygulaması açmak

Selam arkadaşlar,

Ne zamandır yazamıyorum, malum ülkenin gündemi aşırı yoğun. Haliyle insanların dikkati de başka yönlere çekiliyor ister istemez. Bu sebeple iki yazı arasına bayağı bir süre geçti kusura bakmayın.

Bir web sayfasından nasıl iPhone uygulamasının açıldığını gösteren örnek bir kod paylaşmak istiyorum bu yazıda sizlerle.


<script language="javascript">

$(document).ready(function () {

var time = (new Date()).getTime();

var url = "your_app://functionality?someparam";
 window.location = url;

setTimeout(function () {

now = (new Date()).getTime()

console.log( "opened time:" + time);
 console.log( "now: " + now);

if ( now - time < 2500 ){
 //if the interval is bigger than 2500 ms, user probably opened the app
 window.location = "download_link";
 }
 }, 2000); //will wait for 2seconds before going to itunes
 });

</script>

Burada çok basit bir şekilde url scheme belirtmiş bir uygulamanın web siteden açılma denemesini görüyorsunuz. Burada önemli bir nokta, uygulama açılmazsa download_link adresine yapılan yönlendirme. Bu yönlendirmede zamanın önemi var çünkü her hangi bir kontrol yapmadığınız takdirde, uygulamanız açılsa bile indirme adresine yönlendirme oluyor. Bu yüzden zaman kontrolüne dikkat etmekte fayda var.

Mobil tarayıcıdan uygulamasının açılmasını isteyen arkadaşların işine yaraması dileğiyle,

Herkese iyi çalışmalar

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!

QCON 2013

Herkese merhaba,

Bu sene çalıştığım şirket tarafından QCON 2013’ü izlemek üzere Londra’ya gönderildim, dönüşte izlenimlerimizi bir blog yazısı olarak aktarmamız istendi, bu amaçla aşağıdaki yazıyı kaleme aldım, umarım beğenirsiniz.

What happened at QCON 2013 London?

This year I was one of the two engineers that my company sent to attend to QCON London. We tried to split as we encounter interesting presentations that seem useful to us and our company’s main line of work. Below you will find the main summary and the trending topics of the event.

One of the main line of topics was Best Practices in Web Development, we have seen so many things that we feel in our guts when we are developing but yet did not find its way into our practice somehow. Most prominent examples were anti-patterns like sessions and cookies, usage of javascript and css, semantic html and web sockets. Session usage being an anti-pattern was the most important aspect of those talks. Now I am really convinced that sessions must only be used in development mode, then must be switched to something else, like databases or memory cache structures in the software life cycle.

 

Another interesting aspect of the conference was the real world scenarios. Those were the cases where big companies or big projects encounter problems that can take companies/projects down. It was a very useful series, we have seen NOSQL products in action. Also we have seen a trend where people are migrating to JVM and started to use functional languages like Scala and Clojure.

 

Agile Practices was another interesting topic in the series. Everyone knows that they must be followed, but none follows them well in Turkey. Especially Pair Programming, Retrospection and Iterative Development models are practices which every development team that calls itself agile must follow. Companies that calls themselves agile and customer-driven must also follow these, at least as guidelines.

Key Notes were very successful in my opinion. Barbara Liskov’s entry to conference was really refreshing about where the software came from and where it must go. Damian Conway was a real presentation expert and inspired a lot of people. His main theme was also a very important one that programming languages determine the way you think, therefore more powerful and abstract languages make your thinking more powerful. By the way I must add that he wrote a Latin interpreter just for the sake of the presentation!! There was also a key note called 8 Lines of Code that changed my view of Spring frameworks. It was very inspiring and challenging.

REST was also a very important topic at the conference. Because everyone talks about how they do their API’s in REST, but no one actually does it right. I know that because I was not doing it right. We get the chance to learn the powers of REST and after this conference, will try to use it at every opportunity. I also inspected that the simplicity of REST does not mean it is easy.

Last but maybe the most important topic of the conference was NOSQL technologies. A lot of NOSQL companies were sponsors of the conference so it is logical to see so many presentations. But the numbers and the use cases shows us that this technology is here to stay. And it is powerful. And it is useful. And the beauty is, everyone can break their own motherships to use new technologies piece by piece. The challenge and the beauty lies in this situation.

As for the summary, QCON really showed us great trends and useful presentations. Many of the presentations were also a lot of fun so we did not dose of sleep in any of the presentations : ). Every competing software company needs to follow this conference every year if it wants to stay competitive and succeed.