19 Eylül 2019

2017 yılında iş değişikliğinden dolayı gelen vergi tebligatları hakkında

Selamlar,

2017 yılında bir iş değişikliği yapmıştım. Geçen haftalarda adresime vergi dairesinden tebligat geldi. 2017 yılına ait tüm bordrolarınızla vergi dairesine gelmemi söylüyordu. Vergi dairesine gittim, bordrolarımı incelediler. Şu ortaya çıktı: iş değişikliğinde yeni iş yerim "yıllık kümülatif gelir matrahı" (YKGM) kısmını sıfırdan başlatmış. Bu durumda ödediğiniz gelir vergisi en düşük vergi diliminden hesaplanıyor. Normalde olması gereken yeni iş yerinin YKGM'yi kaldığı yerden, yani eski iş yerinden aldığınız son bordroda yazan rakamdan başlatması gerekiyormuş.

Kanunda yazan bunu çalışanın bilmesi gerektiğiymiş. İş verenin bir yükümlülüğü yokmuş. Tabi, bir çalışan olarak ben kanunları okumuyorum ve bilmiyorum. Sanırım, neredeyse tüm çalışanlar da benimle aynı durumdadır. İş verenin kanunları daha iyi bilmesi gerektiğini düşünüyorum. Çünkü mali denetleme vs. gibi devlet kanalları ile daha çok ilişki içerisindeler. Yanlış bir şey yapmamaya dikkat ederler.

Velhasıl, öyle yada böyle ödemem gereken gelir vergisini hesaplamam gerekiyordu. Dikkat edin, kendimin hesaplaması gerekiyor. Bunu vergi dairesi yapmıyor maalesef. Dolayısıyla bu konuda tecrübesiz olduğum için yanlış yapma ihtimalinden dolayı serbest mali müşavirden danışmanlık aldım. Tavsiyem başınıza böyle bir şey gelirse danışmanlık almak. Yazının sonunda danışmanlık aldığım mali müşavirin iletişim mail adresini paylaştım. Mali müşavir ödemem gereken vergiyi hesapladı ve bunu Gelir İdaresi Başkanlığı'nın online sunduğu hazır beyan sisteminden girdik.

Şöyle bir durum var, sistem bir de size pişmanlık zammı diye bir kalem çıkarıyor. Çok garip ama çıkarıyor. Bilmediğim bir şey için pişman olmak da enterasan bir durum doğrusu. Bilginiz olsun.


Danışmanlık alınabilecek serbest muhasebeci mali müşavir mail adresi:

yildirim.danismanlik.smmm@gmail.com

09 Nisan 2019

How to Call A Number Programmatically Using Amazon Connect Service API?

Let’s think a scenario like this:
You have a CI tool and there exists a serious pipeline in it. This pipeline makes some tests for your production system. Failing any of the tests means that there is an urgent issue about production. Immediately someone has to be notified. So, you want your CI pipeline to call your support guy automatically when there is a failure in your pipeline. How? 

Please read my latest article on Medium.

16 Mart 2013

Google Hesap Makinesi

4 senelik bir aradan sonra akademik hayata geri dönünce matematiğe de geri dönmek zorunda kaldım :) Yazılımın içinde olunca matematik olarak 4 işlem bir de mod alma olmak üzere toplam 5 işlem yapıyorsunuz :) Bu nedenle bazı şeyleri unuttuk tabi. Örneğin 0! = 1 miydi, değil miydi emin olamadım?
Google'a sorunca 0! nedir diye sonuçlar aşağıdaki gibi oldu:


Çok basit ve güzel bir fikir bence. Sonra 3*4 yazdım, sonuç yine aynı şekilde hesap makinesi görünümünde belirdi. Google'ın bu tarz basit ve kullanışlı fikirleri popüler olmasında bir etken bence. Bu özellik eski olabilir, fakat ben yeni karşılaştım, eline sağlık Google...

08 Eylül 2011

JBOSS 6'da "Adding multiple last resources is disallowed" hatası

EJB'nizde bir transaction içerisinde birden fazla JPA entity manager kullanarak işlemlerinizi gerçekleştirmek istediniz. JBOSS 6 kullanıyorum. Hiç bir ayar yapmadan bunu denediğinizde aşağıdaki gibi bir hata alabilirsiniz:

ARJUNA-12140 Adding multiple last resources is disallowed.
...
Could not enlist in transaction on entering meta-aware object!; - nested throwable: (javax.transaction.SystemException: java.lang.Throwable: Unabled to enlist resource, see the previous warnings. tx=TransactionImple < ac, BasicAction: 0:ffff0acc0a36:12ce:4e6754eb:142 status: ActionStatus.ABORT_ONLY >); - nested throwable: (org.jboss.resource.JBossResourceException: Could not enlist in transaction on entering meta-aware object!; - nested throwable: (javax.transaction.SystemException: java.lang.Throwable: Unabled to enlist resource, see the previous warnings. tx=TransactionImple < ac, BasicAction: 0:ffff0acc0a36:12ce:4e6754eb:142 status: ActionStatus.ABORT_ONLY >))



JBOSS 6'da varsayılan ayarlar olarak bir transaction'da tek datasource kullanabiliyorsunuz. Bu nedenle two phase commit gereken işlemleri yapamıyorsunuz. Bunu yapabilmek için deploy dizini altındaki transaction-jboss-beans.xml dosyasını açınız ve aşağıdaki değişikliği yapınız.


<bean name="CoreEnvironmentBean" class="com.arjuna.ats.arjuna.common.CoreEnvironmentBean">
  ...
     <property name="allowMultipleLastResources">true</property>  
  ...
</bean>

Bunu yapınca uygulamanızı çalıştırdığınızda konsolde aşağıdaki bir warning alabilirsiniz:


WARN  [com.arjuna.ats.arjuna] ARJUNA-12141 Multiple last resources have been added to the current transaction. This is transactionally unsafe and should not be relied upon. Current resource is com.arjuna.ats.internal.arjuna.abstractrecords.LastResourceRecord@63a188

Bunun nedeni jboss datasource xml'inizde kullandığınız datasource tipi local datasource olmasıdır. Bunun yerine two phase commit imkanı sağlayan xa datasource kullanınız.

06 Ekim 2010

Gönüllerin Feryadı "Ney"

Ney sazı ile maceram devam ediyor. Saz üzerindeki çalışmalarım yaklaşık 3 seneyi buldu. İnsan sevdiği şeyler üzerine emek harcıyor gerçekten. Ney benim için rastgele bir uğraş olmadı, devamı geldi, Ney ile ilgili ney yapım ustalarının ve hocalarımın yardımları ile farklı bilgiler edindim. Sanki benden bir parça haline geldi diyebilirim. Sıkıldığımda, neşelendiğimde, bunaldığımda yada hüzünlendiğimde destekçim olan yegane unsurlardan birisi oldu. Abartmıyorum eğer evde olursam:) elimden bırakamıyorum diyebilirim.
Geçenlerde iş arkadaşlarımdan Asım'ın teklifi üzerine kurumumuzun dergisinde neyzen arkadaşım Elif ile birlikte bir yazı hazırladık. Çeşitli kaynaklardan bilgileri derleyerek ve kendi tecrübelerimizi de katarak bu yazıyı oluşturduk. Aşağıda bağlantısı mevcut. Yazı derginin son sayfalarında yer almaktadır:

02 Şubat 2010

Süper Netbeans Woodstock Hatası!!!

Bildiğiniz gibi Netbeans görsel web uygulamaları geliştirmek için ICE Faces mimari çatısını tercih etti. Woodstock'ı geride bıraktı. Çok yerinde, çok mantıklı bir karar. Projemizde bir web uygulamasında Netbeans 6.0 kullandım. Doğal olarak Woodstock ile uygulamayı geliştirdim. Netbeans'in yavaşlıkları zaten deli ediyordu, woodstock'ın da o diktatör, esnek olmayan yapısı iyice deli etti kodun bakımını yaparken. Neyse bugün uygulamayı bir gözden geçireyim dedim. Bir sayfada "Calendar" bileşenini kullanmıştım. Daha düne kadar yani Ocak ayında çok güzel çalışıyordu bu bileşen. Fakat Şubat ayına geçince bileşen sapıttı. Bileşene tıklayınca o her zamanki date picker açılır penceresini göreceğimi ümit ederken hiç bir tepki alamamam ilk önce bir afallamama sebep oldu. Sonra bir kaç kez daha tıkladım, sanki bir şey olacakmış gibi, ve yine bir şey olmadı. Sonra bir baktım ki javascript hatası vermiş bileşenimiz. "this.lastRow has no properties" yada "this.lastRow is null" şeklinde. Sonra düşündüm bu geçen hafta, yani Ocak'ın son haftası, düzgün çalışıyordu. Ne oldu birdenbire. Sonra sistem tarihini Ocak ayına çektim. Bir de ne göreyim, çalıştı. Tarihi Mart ayına çektim, yine çalıştı. Ama tarihi Şubat'a çekince, sapıttı. Muhtemelen geliştiriciler Şubat ayının hususiyetini unutmuş, Şubat 28 çeker hemşerim. Neyse sonra google amcama bir sorayım dedim bu durumu. O da bana şu linki verdi:


Birisi daha karşılaşmış olacak ki hemen nasıl çözeriz diye soru sormuş, hem de geçen sene şubat ayında sormuş bu soruyu. Neyse ben hiç çözümünü sormayacağım, zaten adamlar Woodstock'ın pabucunu dama atmışlar. Sağlık olsun, ne diyelim...

30 Haziran 2009

JPA'da Bir Problem mi Var?

Çalıştığım projede EJB 3.0 ve JPA'yı kullanmaktayız. Uygulama sunucusu olarak JBoss 4.2.3 GA kullanıyoruz. Bu sabah bir native query yüzünden 1 saat oyalandım durdum. Query native yazıldı çünkü karmaşık bir query idi. JPA API'sindeki createNativeQuery metodu kullanıldı. Sorun şu: query'de çekilen kolonlara isim vermeyince otomatik olarak kolon ismi atanıyor. Bunu da çekilen alanın ismine göre yapıyor. Örneğin; "... d.id, p.id ..." şeklinde kolonlar varsa sonuç listesinde "ID, ID " şeklinde bir görüntü oluşuyor. Bu durumda da normalde d.id değeri 120, p.id değeri 130 ise ikisi de 120 geliyor. Daha sonra query'i "... d.id AS ID1, p.id AS ID2 ..." şeklinde değiştirince sorun gözükmüyor. JPA kolon isimlerinden dolayı bir karmaşaya düşüyor galiba. Çözüm bulmak sevindirici fakat böyle bir saçmalıktan dolayı 1 saat boşa uğraşmak üzücü...

25 Mart 2009

Tomcat 6.x Windows Servis'ine VM Argümanı Nasıl Verilir?

Apache Tomcat 6.x windows servis olarak çalıştırılabilmektedir. Tomcat'i bilgisayarınıza kurduğunuzda "bin" klasörü altında service.bat, tomcat6.exe ve tomcat6w.exe dosyaları bulunmaktadır. VM argumanı verirken bu dosyaları kullanacağız. Bu dosyalardan asıl işimizi gören "service.bat" dosyasıdır. Bu dosya ile tomcat windows servis olarak kurulabilir veya var olan bir servis kaldırılabilir. Bu dosyayı direk çalıştırdığınızda şu satır çıkar konsolda:

Usage: service.bat install/remove [service_name]

Buna göre "service.bat install" dediğinizde tomcat servis olarak yüklenecek veya "service.bat remove" dediğinizde var olan tomcat servisi sistemden kaldırılacaktır. Tomcat'i servis olarak yükledikten sonra "bin" klasörü içindeki tomcat6w.exe dosyasını çalıştırarak tomcat'in servis olarak çalışırken nasıl ayarlar ile çalışacağını kontrol edebilirsiniz, tabi ki bir kısım ayarlar. Bu ayarlardan bir tanesi VM argumanlarının verileceği kısımdır. Bu argümanlar açılan pencerede 4. tab olan Java tab'ındaki "Java Options" kısmında verilir. Ben bu kısma PermGen Space ayarı ile ilgili vm parametreleri girdim. Ondan sonra servisi başlattım fakat hata verdi, argümanları algılayamadı. Daha sonra service.bat dosyasını düzenlemek için açtım. Dosyada:

rem Set extra parameters
"%EXECUTABLE%" ...


şeklinde devam eden bir satır var. Bu satıra VM argümanları ";" işareti ile ayrılarak yazılmış. Ben de -XX:PermSize=512m, -XX:MaxPermSize=512 argümanlarını şu şekilde ekledim:

"%EXECUTABLE%" //US//%SERVICE_NAME% ++JvmOptions "-Djava.io.tmpdir=%CATALINA_BASE%\temp;-Djava.util.logging.manager=org.apache.juli.ClassLoaderLogManager;-Djava.util.logging.config.file=%CATALINA_BASE%\conf\logging.properties;-XX:PermSize=512m;-XX:MaxPermSize=512m" --JvmMs 256 --JvmMx 512

Daha sonra servisi "service.bat remove" ile kaldırıp "service.bat install" ile tekrar kurdum. Bu işlemden sonra servis düzgün olarak çalıştı.
Bu arada tomcat servis olarak değil de normal olarak yani startup.bat dosyası ile çalıştırılacaksa ve VM argümanı verilmek isteniyorsa catalina.bat dosyası içindeki "JAVA_OPTS" değişkenine istenilen argümanlar eklenmelidir. Ekleme aşağıdaki şekilde olabilir:

set JAVA_OPTS = %JAVA_OPTS% -XX:PermSize=512m -XX:MaxPermSize=512

Zaten dosya içinde JAVA_OPTS şeklinde aratırsanız örneğini görebilirsiniz.

11 Şubat 2009

JSF Tomcat ve Eclipse konfigürasyonu

Eclipse Ganymede versiyonunda JSF projesi nasıl yapılır, Tomcat üzerinde nasıl çalıştırılır? gibi soruların cevaplarının bulunabileceği güzel bir makale "JSF tutorial with Eclipse and Tomcat".

02 Kasım 2008

Türksel Çeker :)

Geçen hafta yaptığımız Bolu Yedigöller gezisinde karşılaştığım ve bizim milletimizin kıvrak zekasını tekrar müşahede ettiğim tebessüm ettirici bir anıyı paylaşmak istedim. Maalesef Yedigöller'e giderken telefon hattınız çekmeyebilir. Bazı noktalarda çekiyor. Aşağıdaki resimde de bu noktalardan bir tanesi gösterilmiş:) Yalnız sadece Türksel :) çekiyor, Aveya veya Vodafon :) çekmiyor. Bu noktada insanlar sevdikleri ile konuşabiliyor.

Yansımalar - Ağıt Nota

Yansımalar grubunun çok güzel parçalarından bir tanesi Ağıt. Beste Birol YAYLA'ya ait. Notası aşağıdadır:

17 Ekim 2008

Yansımalar Yakamoz Nota

Merhabalar,
Sevgili Birol YAYLA'nın çok sevdiğim eserlerinden biri Yakamoz. Son yıllarda tanıdığım en önemli bestekârlardan birisi Birol YAYLA. A.Şenol FİLİZ ile muhteşem bir ikili oluyorlar. Grupları Yansımalar kendi tarzında yoluna devam eden yegane gruplardan bir tanesi. Son albümleri olan Gölgesiz Aydınlık'ın piyasaya çıkacağı günü sabırsızlıkla bekliyorum.

18 Eylül 2008

JAR içinden animated gif nasıl okunur?

Şu yazımda bir jar dosyası içinden bir resim dosyasının nasıl okunacağını yazmıştım. Fakat bu yöntemi bir jar içinden animated gif dosyasını okumak için uygularsanız resim animated olmaz statik olur. Animated GIF dosyaları bir kaç tane resmin ard arda sıralanıp tek bir dosya haline getirilmesinden oluştur. Biz bu resimlere frame dersek JAR içinden bu resmi okuduğunuzda ilk frame size getirilir ve siz hareketsiz bir resim görürsünüz. Bunun çözümü ise tabiki tüm frameleri okumaktır. Bu nasıl yapılır:
// İlk önce class loader nesnesi alınır
ClassLoader cl = this.getClass().getClassLoader();
// okunacak animated gif resource olarak okunur
InputStream is = cl.getResourceAsStream("images/animatedpic.gif");
// resim byte olarak okunacağı için bir ByteArrayOutputStream nesnesi oluşturulur
ByteArrayOutputStream baos = new ByteArrayOutputStream();
// -1 okuyana kadar resource'dan byte byte okunur ve output stream'e yazılır.
int r = 0;
while ((r = is.read()) != -1)
baos.write(r);
// Son olarak output stream byte dizisine dönüştürülür ve Image nesnesi oluşturulur.
Image image = Toolkit.getDefaultToolkit().createImage(baos.toByteArray());
// Bu image nesnesini de istediğiniz yerde kullanabilirsiniz.
JLabel label = new JLabel();
label.setIcon(new ImageIcon(image));

08 Eylül 2008

İpek Yolu

Selamlar,
"İpek Yolu" parçasını duymayanınız yoktur. Eğer duymadıysanız buyrun. Bu parça aslında Kitaro grubuna ait bir parçadır. Detaylı bilgi için buyrun. İşin garip yanı ben bu parçayı Kitaro'dan dinlemedim, Kervansaray grubunun 1. albümünde yer alıyordu ve NEY ile icra edilmişti, çok hoşuma gitmişti ilk dinlediğimde. Ben burada bu parçanın hocam Serpil CEYLAN tarafından tashih edilen notasını koymak istiyorum. İnternetteki arayışlarıma rağmen pek net bir sonuca ulaşamadım bu konuda. Umarım benim gibi bu parçanın notalarını arayanlara yardımcı olur:

29 Ağustos 2008

NEY ve Yansımalar Sonbahar Nota

Yazı yazmayalı baya bir zaman oldu. İş, güç, okul derken bu köşemizi unuttuk. Gerçi yazacak çok şey çıktı ama ya vakit bulamadım ya da üşendim. Bu yazıdan sonra burada sadece JAVA ile ilgili yazılar olmayacak. Bundan sonra farklı konularda da hayatımda gördüklerimi, duyduklarımı ve yaşadıklarımı paylaşacağım. Paylaşmanın bir alanda olması diğer alanlarda bilgi kısırlığına neden olacak endişesiyle bu kanıya vardım. Bu yazıyı yazdığım sırada yaklaşık 1 senedir NEY kursuna devam ediyor olacağım. NEY benim için yıllardan beri içimde kalmış bir uhde idi. Bu görevi de ancak ve ancak çalışma hayatına atıldıktan 3 yıl sonra yerine getirebildim. Kurs olarak Cevizli Maltepe İSMEK kursuna devam ettim. Buradan hocamız Serpil CEYLAN'a teşekkür ediyorum. Saolsun sabrederek tüm öğrenciler ile teker teker ilgilendi. NEY enstrümanı gerçekten sabır isteyen ve insana sabrı öğreten bir enstrüman. NEY için enstrüman demek biraz basit kalıyor sanki. NEY çok değişik bir varlık diyebilirim. NEY'in sesi gerçekten insan sesine en yakın ses. NEY üflemek ve dinlemek insanın inlemelerini dışa vuruyor. NEY ile inlemelerinizi dillendiriyorsunuz. NEY bir kamış, basit bir tahta parçası diyenler vardır. Ama insanda bıraktığı etki büyük. Diğer enstrümanların önemi büyük tabi ama NEY aralarında en mütevazi olanı. Bir kamış, hafif, taşınması kolay ve sesi dinleyen herkesi etkileyebiliyor. Nasıl mütevazi insanı herkes sever, gururlu olma insanlar tarafından hoş karşılanmaz. NEY'de ben bu mütevaziliği gördüm. Bir kamış dedik, ama size boynunuzu eğdiriyor. Gururunuzu ayaklarınızın altına almanızı sağlıyor. NEY inler, insan inler, diğer sesler duyulmaz olur. Günlük yaşamın hızlılığı insanı sakin olmaktan alıkoyuyor, her işte bir panik, heyecan, stres oluşuyor. Bu tarz dertlerden muzdaripseniz NEY üflemenizi tavsiye ederim. En azından bir enstrüman ile uğraşmak gerektiği kanaatindeyim. Neyse yazının başlığından baya bir uzaklaştım. Sevgili Serpil CEYLAN hocamızın tahsis ettiği Yansımalar grubunun Sonbahar parçasının notasını sizinle paylaşmak istedim. Bu parçanın o güzel melodisi sayın Birol YAYLA'ya aittir. Yansımalar grubu hayranı ilerde bu grup ile ilgili düşüncelerimi de paylaşmak isterim.

02 Haziran 2008

Aynı Makinede İki Tane JBOSS Çalıştırılması

Not: Burada anlatılanlar JBOSS 4.2.1 versiyonunda uygulanmıştır.

Aynı makinede iki adet JBOSS aynı anda çalıştırılabilir. Bunun için JBOSS’ta yeni bir konfigurasyon tanımlanması gerekmektedir. Bilindiği gibi JBOSS ilk kurulup çalıştırıldığında çalışan konfigürasyon “default” konfigürasyonudur. Konfigürasyonlar /server/ dizini altında bulunur. Örnek bir gösterim aşağıdaki gibidir:

JBOSS ilk kurulduğunda gelen konfigürasyonlar “all”, “default” ve “minimal” konfigürasyonlarıdır. Burada biz kendimiz yeni bir konfigürasyon oluşturup aynı anda “default” ve bizim oluşturduğumuz konfigürasyonu deneyeceğiz.

Öncelikle “default” klasörü farklı bir isimde server dizinin altına kopyalanır, örn: “myconfig”. Daha sonra myconfig/conf dizini altındaki jboss-service.xml dosyası bir editörde açılır. Bu dosyada Service Binding kısmı bulunur. Burada amaç “myconfig” konfigürasyonunun çalışacağı portları belirlemektir. Aksi takdirde “default” konfigürasyonu ile çakışır. “default” konfigürasyonu kopyaladığımız için burası comment edilmiştir. Buradaki comment kaldırılır ve aşağıdaki gibi görüntü oluşur:

Bu parçada StoreURL alanı ile gösterilen dosyada hazır port konfigürasyonları vardır. Bu dosyayı açtığınızda “ports-default”, “ports-01”, “ports-02” ... gibi konfigürasyonlar vardır. Kendi konfigürasyonunu da oluşturabilirsiniz. ServerName alanı ile de bu dosyadaki konfigürasyonlardan birisini seçersiniz. Bu parçada “ports-02” konfigürasyonu seçilmiş. “default” konfigürasyonda yukarıdaki xml parçası commentli olduğu için “ports-default” konfigürasyonu kullanılmaktadır. Böylece kendi konfigürasyonumuzu oluşturduk.

Şimdi sıra geldi çalıştırmaya. Çalıştırmak için /bin/run.bat veya run.sh (linux için) dosyasını çalıştıracağız. İlk önce default konfigürasyonu çalıştıralım. Komut satırında “run.bat –c default” yazılır ve çalıştırılır. Daha sonra “myconfig” konfigürasyonu için “run.bat –c myconfig” yazılır ve çalıştırılır. Böylelikle iki konfigürasyon da aynı makinede çalıştırılmış olunur. Eğer çakışan port olursa, bu port numarası “myconfig” konfigürasyonundaki dosyalar arasında aranır. Bulunan sonuçlar kullanılmayan portlardan birisi ile değiştirilir.

10 Şubat 2008

JBoss için Login Module Tanımlanması ve Rol Bazlı EJB Güvenliği

Java Authentication and Authorization Service (JAAS) ve EJB Güvenliği adlı yazımda JAAS'dan kısaca bahsetmiştim. JAAS'ın kullandığı bir yapı olan Login Module kavramının ne olduğuna da kısaca değinmiştim. Login Module login işleminin gerçekleştiği birimlerdir. Her sistem farklı tipte login gerçekleştirebilir. Kimisi basit kullanıcı adı ve şifre bilgileri ile bu işlemi yaparken kimisi sertifika bazlı işlem yapabilir. JBoss'da kendi içinde JAAS'ı kullanmaktadır. Bu nedenle JBoss üzerinde çalıştırdığınız EJB'lere rol bazlı erişim sağlamak istiyorsanız JBoss'un kendi sunduğu bir login modül kullanabilirsiniz yada kendiniz oluşturabilirsiniz. Burada kendimiz nasıl oluştururuz ona bakalım.

Yazacağınız login module JBoss'un sunduğu AbstractServerLoginModule abstract sınıfını extend etmelidir. Bu linkte kaynak kodunu görebilirsiniz (Ayrıca bu sınıfı kullanan JBoss login modülleri olan UsernanePasswordLoginModule ve DatabaseServerLoginModule sınıflarının kodları da incelenmesi gerekmektedir). Bu nedenle yazacağınız kod getRoleSets() ve getIdentity() metodlarını override etmelidir. Tabi bunlarla kalmamak lazım. Bir de login işlemini gerçekleştiren login() metodu var. Bu metod bu sınıfta implemente edilmiş ama biz kendimize uygun bir login modül oluşturacağımız için bu metodu da override etmemiz gerekir. Ayrıca login module ilklendirilirken kullandığınız seçenekler var ise initialize() metodunu da override etmek gerekir. Genel olarak sınıf aşağıdaki gibi olacaktır:

package com.ornek;

public class MyLoginModule extends AbstractServerLoginModule {

...

/*

burada options parametresi login modül'e verilen optionları barındırır, callbackHandler giriş bilgilerini barındırır, subject de rol bilgilerini tutar.

*/

public void initialize(Subject subject, CallbackHandler callbackHandler, Map sharedState, Map options) {

...

}

/*

login işlemi burada gerçekleştirilir. işlem başarılı ise mutlaka süper sınıfta tanımlanmış loginOk değişkeni true değerine atanmalıdır. Aksi takdirde süper sınıftaki commit metodu çalışmaz.
*/

public boolean login() throws LoginException {

}

...

super.loginOk = true;

...

}

/*

Login olan kullanıcının role gruplarını oluşturan bir metoddur ve override edilmesi gerekir. Bu metod override edildiğinde kullanıcının role bilgilerini barındıran en azından “Roles” adında bir Group oluşturulmalıdır.

*/

protected Group[] getRoleSets() throws LoginException {

...

}

/*

Kullanıcının birincil giriş bilgisini içeren Principal nesnesini döndürür.

Bu metod genelde login metodu içinde oluşturulan Principal nesnesini döndürür.

*/

protected Principal getIdentity() {

...

}

Kendi modülünüzü yazdıktan sonra bunun Jboss’a tanıtılması gerekmektedir. Bunun için login module sınıfınızı jar haline getirin ve Jboss deploy kütüphanelerini (/server/default/lib) arasına oluşturduğunuz jar’ı kopyalayın. Daha sonra deploy konfigürasyonlarının olduğu dizin (/server/default/conf) altındaki login-config.xml dosyasını açın. Bu dosyaya kendi login modulünüzü ekleyeceksiniz. Zaten dosyanın başında nasıl yapcağınız anlatılıyor. Örneğin yukarıdaki sınıfı şu şekilde eklenebilir:





Görüldüğü üzere kendi yazacağınız login module sınıfında yukarıdaki üç metodu override etmeniz yeterli olacaktır. login metodu düzgün olarak çalıştığında ve super.loginOk = true ise süper sınıf kendi içindeki commit metodunu çalıştıracak ve kullanıcının rol bilgilerini oluşturan getRoleSets metodunu çağıracak. Bütün işlemler bittiğinde kullanıcıya ait giriş ve rol bilgilerini barındıran bir Subject nesnesi oluşturulacak. Bu nesne ejb metodları çağırılırken çağıranın rol bilgilerinin kontrolü için kullanılacak. Örnek:

@Remote

public interface MyEJB {

public void myMethod();

}


@SecurityDomain(“MyLoginModule”)

@Stateless

public MyEJBImpl implements MyEJB {

@RolesAllowed(“MyRoleName”)

public void myMethod() {

...

}

}

Yukarıdaki örnekte EJB metodları çalıştırılmadan önce MyLoginModule ismindeki login modülün çalıştırılacağı ve kullanıcının girişinin gerçekleştirileceği SecurityDomain annotation’ı ile belirtilmiştir. SecurityDomain annotation’ı içine vereceğiniz login module ismi login-config.xml dosyasında tanımlı olmalıdır. Kullanıcı girişi gerçekleştirildiğinde istenilen ejb metodu çağırılır aksi takdirde hata verilir.

Bir EJB metodu olan myMethod’a sadece MyRoleName rolundeki kullanıcıların erişebileceği @RolesAllowed annotation’ı ile gösterilmiştir. Bu annotation içine birden fazla rol yazabilirsiniz @RolesAllowed(“Role1”, “Role2”, ...) şeklinde. İşte bu annotation içindeki rol bilgileri login module tarafında oluşturulan Subject nesnesinin içindeki rol bilgisiyle karşılaştırılır. Eğer Subject nesnesi bu rollerden birisini barındırıyorsa metod çalıştırılır. Aksi takdirde çalıştırılmaz.

07 Ocak 2008

Java Authentication and Authorization Service (JAAS) ve EJB Güvenliği

JAAS java uygulamaları için kimlik doğrulama ve yetkilendirme işlemlerini portatif bir şekilde yapılmasını sağlayan bir arayüzdür. JAAS'ı kullanarak kendiniz sisteme giriş yapmayı ve yetkilendirmeyi sağlayan mödüler API'ler yazabilirsiniz.
JAAS'ı herhangi bir güvenlik sisteminde kullanabilirsiniz. Örneğin; bir uygulama sunucusu kimlik doğrulamayı bir dosyadan okuyarak yapıyor olabilir yada bir veritabanından sorgulatarak ya da bir LDAP sunucusuna bağlanarak yapıyor olabilir. JAAS ile bu ortamlara ayak uydurmak hiç dert değil. Çünkü JAAS interface'lerden oluşur ve siz de bu interface'leri implemente edersiniz. Böylece kimse kimseye darılmaz.
JAAS EJB güvenliğinde sıklıkla kullanılır. Sun, JAAS'ı EJB güvenliğinde standard olarak kullanmaktadır.

Genelde JAAS modüllerinin kullanımı ile ilgili iki tip senaryo vardır:
  • Bir masaüstü uygulamanız vardır ve bu uygulamanız uzak bir uygulama sunucusuna bağlanıp sisteme giriş yapacaktır. Sisteme giriş sağlandıktan sonra da kullanıcının yetkileri oluşturulup bu yetkilerine göre sistemde hangi modüllere erişip hangi modüllere erişemeyeceği belirlenecektir. Bunun için masaüstü uygulamanız JAAS ile kullanıcının giriş bilgilerini uygulama sunucusuna iletir. Uygulama sunucusu da bu bilgileri kullanarak sisteme girişi gerçekleştirip kullanıcının rollerini oluşturur. Bundan sonraki EJB metodlarının çağırılmasında kullanıcının rol bilgilerine bakılır. Eğer yetkisi varsa izin verilir yoksa izin verilmez.
  • Bir web tarayıcı aracılığı ile sisteme giriş yapabilirsiniz. Burada da kullanıcının giriş bilgileri JSP/servlet'e aktarılır. JSP/Servlet'de bu bilgileri kullanarak sisteme girişi gerçekleştirir. Tarayıcı giriş bilgilerini aşağıdaki yöntemleri kullanarak aktarır:
    • Basic authentication
    • Form-based authentication
    • Digest authentication
    • Certificate authentication
Masaüstü uygulamaları gibi web uygulamasında da sisteme giriş gerçekleştiğinde, istemci EJB metodlarını kullancının yetkileri izin verdiği ölçüde çağırır.

JAAS'ın çalışma mantığına bakacak olursak aşağıdaki maddeler çıkabilir:
  1. İstemci yeni bir LoginContext nesnesi oluşturur. Bu sınıf JAAS tarafından sunulmuştur ve kimlik doğrulama (authentciation) sürecinden sorumludur.
  2. LoginContext nesnesi bir Configuration nesnesi alır. Bu nesnede kimlik doğrulama işleminin hangi LoginModule'ler ile yapılacağı bildirilir. Örneğin bir sistem sadece kullanıcı adı ve şifre doğrulaması istersen başka bir sistem hem kullanıcı adı-şifre hem de sertifika bazlı doğrulama isteyebilir.
  3. LoginContext Configuration nesnesine kimlik doğrulama mekanizmalarının neler olduğunu sorar.
  4. Configuration nesnesi kimlik doğrulama mekanizmalarından oluşan mekanizmalardan oluşan bir liste döndürür. Bu mekanizmaların her birine login module denmektedir. Login Module JAAS'ın sunduğu bir interface'dir. LoginModule kimlik doğrulama işleminin yapıldığı birimlerdir.
  5. LoginContext LoginModule sınıflarından birer nesne oluşturur.
  6. LoginContext oluşturulan LoginModule nesnelerini ilklendirir.
  7. İstemci kodu LoginContext nesnesi üzerinden login() metodunu çağırır.
  8. LoginContext login işlemlerini LoginModule nesnelerine devreder. Çünkü kimlik doğrulama işlemlerinin nasıl yapılacağını bu modüller bilmektedir.
  9. Sizin tarafınızdan yazılmış LoginModule nesneleri kimlik doğrulama işlemini gerçekleştirir.
  10. İşlem sonucu oluşturulan bilgiler Subject sınıfından oluşturulmuş bir nesnenin içinde saklanır. Bu nesneyi güvenli işlemler gerçekleştirmek için kullanırsınız.
  11. Bundan sonra istemci kodu EJB metodlarını çağırır ve sistem giriş bilgisi bu metod çağırımlarında otomatik olarak iletilir. Böylece uygulama sunucusu bu bilgileri kullanarak kimlik doğrulama ve yetkilendirme işlemlerini yapar.
Aşağıda yukarıdaki yapının resim olara çizilmiş halini görebilirsiniz:

Bu yazıda JAAS yüzeysel olarak incelenmiştir. Detaylı bilgi için lütfen bkz. JAAS Reference Guide

JAAS Java SE ile birlikte gelmektedir. Böylelikle ayrı bir jar indirmenize gerek yoktur.
Bir sonraki yazıda JAAS kullanarak bir JBOSS uygulama sunucusundaki EJB'lere güvenli erişmeyi sağlayan bir örnek anlatılacaktır.

Kaynak: Mastering Enterprise Java Beans 3.0

15 Ekim 2007

JBoss Binding IP Adress

Merhaba,
Bir Enterprise Java Projesi'nde çalışıyorum. Business kısmını EJB'ler üstlenmiş durumda. Uygulama sunucusu olarak JBoss 4.0.5 kullanıyorduk. Varsayılan konfigürasyonlarla bu JBoss versiyonuna aynı ağ üzerindeki herhangibir client makineden ulaşabiliyorduk. Yani business metodları çağırabiliyorduk. Fakat JSF 1.2 desteği olmadığından dolayı JBoss 4.2.1'e geçtik. Fakat bu seder EJB metodlarını çağıramaz olduk. Bu versiyonda uygulama sunucusu bir sadece bind ettiği bir IP, varsayılan 127.0.0.1, üzerinden hizmet veriyor. Bu nedenle 127.0.0.1 bind edildiğinden, yani localhost, dışarıdan erişemiyordum. Bu sorunu araştırdığımda eğer istenilen bir IP adresine bind edilmesi isteniyorsa JBoss'u "-b" seçeneği ile başlatın deniyordu. Örneğin; JBoss'un çalıştığı makinenin ağdaki IP'si 10.1.1.2 olsun. Komut satırında -b 10.1.1.2 şeklinde bir komut çalıştırırsanız JBoss 10.1.1.2 IP adresine yapılacak isteklere cevap verecektir.

18 Ağustos 2007

For each döngüsü ve Iterator

Bildiğiniz gibi Java 5 ile beraber for each döngüsü java'ya eklendi. Bu döngü ile bir collection'daki yada bir dizideki elemanlar üzerinde rahatça dolaşıp işlem yapabiliyorsunuz. Örneğin; elinizde String sınıfı tipinde nesneler barındıran "list" isminde bir List nesneniz olsun. Bu List üzerinde aşağıdaki gibi dolaşabilirsiniz:

for (String s : list) {
// s'i kullanan veya kullanmayan işlemler...
}
Bu örnekte type safety'de sağlanmış oluyor. Generics o biçim destekleniyor yani:). Bir diğer örnekte array'ler için. Örneğin elinizde A sınıfı tipinde "arr" isminde bir diziniz olsun, bu dizi üzerinde aşağıdaki şekilde dolaşabilirsiniz:

for (A item : arr) {
// item ile bir işlem yap...
}

Iterator java'da bildim bileli olan bir şey, Iterator ile Collection nesnesinin elemanları üzerinde dolaşabilir ve işlemler yapabilirsiniz ve o collection nesnesi de bu değişikliklerden etkilenir. Örneğin; içinde String nesneleri barındıran "mySet" isminde bir HashSet nesneniz bulunmaktadır. Bu set üzerinde aşağıdaki şekilde dolaşabilirsiniz.

Iterator iter = mySet.iterator();
while ( iter.hasNext() ) {
String s = iter.next();
// işlemlere devam et...
}

Gördüğünüz gibi "for each" yapısı Iterator'dan daha basit ve anlaşılır. Ancak Iterator'un pabucunun dama kaldırılmayacağını dün anladım.
İçinde oluşturduğum sınıf tipinde nesneler barındıran bir List üzerinde bir kaç işlem yapacaktım. Bu işlem de list elemanları üzerinde sırayla ilerleyip her elemanı bir koşuldan geçirip eğer koşul sağlanırsa o elemanı listeden kaldırmaktı. Bu işlemi for each ile aşağıdaki gibi yapmıştım:

List list = ...;
for (MyClass m : list ) {
if ( condition )
list.remove(m);
}

Bu kodu çalıştırdığımda java.util.ConcurrentModificationException aldım. Daha sonra aynı işlemi Iterator ile yaptım.

List list = ...;
Iterator iter = list.iterator();
while (iter.hasNext()) {
MyClass m = iter.next();
if ( condition )
iter.remove();
}

Bu kodda ise hata almadım. Nedeni kesin olarak bilmemekle beraber bildiğim kadarıyla Iterator bir Collection nesnesi içindeki elemanlar üzerinde pointer mantığıyla çalışıyor. For each'de ise böyle bir yapı yok, yani bir array gibi çalışıyor. Bu nedenle "for each" ile list üzerinde dolaşırken aynı anda bir nesneyi listeden kaldırmak istediğinizde nesnelerin indexleri değiştiğinden dolayı bu hatayı veriyor olabilir. Iterator ise kaldırılacak elemana point ettiğinden elemanı listeden kaldırıyor ve pointer'ını yeni nesne üzerinde konumlandırıyor, bir linked list mantığı. Siz ne dersiniz?