Salı, Ekim 27, 2009

Java ResultSet'te neden satır sayısı bilgisi yok?

Merhabalar,

Bir çok yerde de tartışma konusu olduğu üzere java.sql.ResultSet sınıfı bünyesinde doğrudan satır sayısına ulaşabileceğimiz bir method barındırmıyor sebebi ise ;

100bin kayıt içeren bir tablo düşünün. Bu tabloya hiç bir kriteri olmayan bir sorgu gönderdiğinizde dönecek 100bin kayıtı RAM'de tutmak çokta akıl karı bir iş olmasa gerek ayrıca network'te yük oluşturduğunuzuda unutmayın. Bu yüzden bu kayıtlar belli gruplar halinde getirilirler (fetch) yani ResultSet objemizin kayıtların sayısı hakkında bir fikri yoktur. Veritabanı editörlerinde de bunu fark etmişsinizdir. Tablolardaki veriler siz tabloyu scroll ettikçe fetch edilirler. Tüm veriyi aynı anda getirmek performans darboğazları yaratabileceği gibi çoğu zamanda (%99) gereksizdir.

Satır sayısı bilgisinin gerekliliğine gelince. Bugüne kadar yazdığım hiçbir programda bu bilgiye ihtiyacım olmadı desem yalan söylemiş sayılmam ama bu bilgi benim için elzem diyorsanız gezilebilir (Scrollable) ResultSet kullanarak bu bilgiyi elde edebilirsiniz. Scrollable olmayan durumlarda ise Cursor tek yönlü olacağından ResultSet'te gezinmeye başladığınızda [myRS.next()] bir önceki kayıta dönmeniz mümkün olmayacaktır. ResultSet'ten satır sayısını bulabileceğimiz bir örnekle konuyu kapatalım,


Statement stmt = conn.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE,ResultSet.CONCUR _READ_ONLY);

ResultSet rs = stmt.executeQuery(query);

int probablyUselessRecordCount = 0;
if (rs != null) {
rs.last(); // cursor'u sona ilerlet
probablyUselessRecordCount = rs.getRow(); //satır sayısını al
rs.beforeFirst();// ResultSet'te gezinmek için cursor'u başa al

}

Çarşamba, Ağustos 05, 2009

Could not find files...

Bir önceki yazımdakine benzer bir kodu PROD. ortamında kullanılırken şöyle bir hatayla karşılaştım.

Could not files in sftp://SFTP_SERVER_PATH

İlgili sunucuda dosya bulunmasına rağmen ve daha yarım saat önce bu sunucudan download işlemi yapabilirken bir anda bu hata mesajı ile karşılaştım. Konuyu biraz araştırdığımda, sorunun beklenmedik bir biçimde sonlanan SFTP sunucularına tekrar bağlantı sağlanmaya çalışıldığında oluştuğunu gördüm.

commons-vfs geliştiricilerine bug olarak iletilen bu sorunun geçici çözümü ise

public static DefaultFileSystemManager fsManager = null;

satırını aşağıdaki gibi değiştirmek,

public StandartFileSystemManager fsManager = new StandartFileSystemManager();

try {
fsManager.init();
} finally {
fsManager.close;
fsManager = null; //mark for garbage collection
}



İyi çalışmalar...

Salı, Haziran 16, 2009

SFTP sunucudan dosya indirme

Merhabalar,

Kullandığımız sistemlerin dış sistemlerle iletişimi elbette çok büyük önem taşıyor. Tabiki iletişim sistemler arası iletişim stored procedure'lardan web servislere farklı teknolojileri kapsıyor. Ben bugün farklı bir sistemden SFTP protokolünü kullanarak dosya indirme işlemini nasıl gerçekleştireceğimiz konusunda bir örnek vermek istiyorum.

Örneğimizde kullanacağımız kütüphane commons-vfs-1.0. Commons VFS (Virtual File System), adında anlaşılacağı gibi bir dosya sistemi yöneticisi FTP,SFTP, HTTP,HTTPS, RAM, MIME gibi çok farklı dosya sistemlerini desteklemekte. Fakat birazdan örneklendireceğimiz SFTP protokolü için jsch-0.1.41 kütüphanesine ihtiyaç duyuyor.
Ayrıca aşağıdaki örnekte bağlantı cümlesindeki SFTP kelimesini FTP ile değiştirmeniz FTP sunucudan dosya almanız için yeterli.

Commons VFS kütüphanesi kullanırken dikkat edilmesi gereken en kritik nokta DefaultFileSystemManager'ın tekrar kullanılmayacağından emin olunmadığı sürece kapatılmaması. Çünkü DefaultFileSystemManager'ın kapatılması durumunda JVM yada uygulama sunucu tekrar başlatılana kadar kullanılamaz hale geliyor. Ayrıca bir JVM sadece bir DefaultFileSystemManager içerebileceğinden static olarak kullanmakta fayda var.





import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileOutputStream;

import org.apache.commons.io.FileUtils; //from commons-io
import org.apache.commons.net.ftp.FTPClient;
import org.apache.commons.vfs.CacheStrategy;
import org.apache.commons.vfs.FileObject;
import org.apache.commons.vfs.FileSystemOptions;
import org.apache.commons.vfs.Selectors;
import org.apache.commons.vfs.VFS;
import org.apache.commons.vfs.impl.DefaultFileSystemManager;
import org.apache.commons.vfs.provider.sftp.SftpFileSystemConfigBuilder;


public class FileDownloader {

//Should be static and should not be forced to close.
public static DefaultFileSystemManager fsManager = null;

static {
try {

fsManager = (DefaultFileSystemManager) VFS.getManager();
//Refer to API for further info
fsManager.setCacheStrategy(CacheStrategy.ON_RESOLVE);
} catch(Exception ex) {
System.out.println(ex.getMessage());
}
}

public static void downloadUsingSFTP() throws Exception {

String destinationFolder = "YOUR_DESTINATION_FOLDER";
String userName = "USER_NAME";
String pass = "PASSWORD";
String serverIP = "SERVER_IP";
String serverPath = "DEST_FOLDER"; //Relative to user root directory
try {

FileSystemOptions fsOptions = new FileSystemOptions();
//we wont check any keys SftpFileSystemConfigBuilder.getInstance().setStrictHostKeyChecking(fsOptions, "no");

//Set user dir as root SftpFileSystemConfigBuilder.getInstance().setUserDirIsRoot(fsOptions, true);
StringBuffer uri = new StringBuffer();
uri.append("sftp://" + userName + ":" + pass + "@" + serverIP + "/" + serverPath);

System.out.println("Connection string : " + uri.toString());
FileObject fo = fsManager.resolveFile(uri.toString(), fsOptions);
FileObject[] foArray = fo.findFiles(Selectors.SELECT_FILES); //Just list files under destFolder. check api for other options

if(foArray == null || foArray.length == 0) {
throw new Exception("No files to download.");
}

logger.info("Number of files listed : " + foArray.length);
String[] files = new String[foArray.length];

for( int i = 0; i < foArray.length; i++ ) {
files[i] = FilenameUtils.getName(foArray[i].getName().getPath());
}

File folder = new File(destinationFolder);
logger.info("Create directory... - > " + destinationFolder);
FileUtils.forceMkdir(folder);
for( int i=0; i {
try {
String dataFileName = destinationFolder + "/" + files[i];
File file = new File(dataFileName);
file.createNewFile();
logger.info("Retrieving file -> " + files[i]);
FileOutputStream fos = new FileOutputStream( file );
BufferedInputStream is = new BufferedInputStream(foArray[i].getContent().getInputStream());
int content;
// do copying
while ((content = is.read()) != -1) {
fos.write(content);
}

is.close();
fos.close();
}
}catch (Exception ex) {
throw new Exception(ex.getMessage());
}


}
try {
fsManager.freeUnusedResources();
} catch (Exception ex) {
//Your logic goes here
}
}catch( Throwable e ) {
e.printStackTrace();
throw new Exception(e.getMessage());
}
}

public static void main(String args[]) {
downloadUsingSFTP();
}

}



Pazar, Mart 22, 2009

Java 5 özelliklerini Java 1.4'te kullanabilseydik keşke?



Java 5'le hayatımıza giren yenilikler (ki benim favorim @Annotations) çığır açan yeniliklerdi şüphesiz. Çok yaygın olarak kullanılan Java 1.4'ten Java 5'e geçiş tabiki kolay olmuyor ve Java 1.4 büyük ölçekli projelerde hala en çok tercih edilen SDK olma ünvanını koruyor.

Peki benim gibi Java 1.4 ortamında proje geliştirmek zorunda kalanlar Annotations, Autoboxing/unboxing, gelişmiş Generic'ler ve gelişmiş "for" döngüleri gibi nimetlerden faydalanamayacak mı? Elbette faydalanacak nasıl mı buyurun buradan devam edin
Retrotranslator





Çarşamba, Mart 04, 2009

JBoss Seam?

Merhabalar,,,,

Java dünyasında olupta JBoss adını duymayan yoktur sanırım. (Onlarda şimdi duydular).
Bu yazımda Enterprise Java dünyasında her zaman büyük boşlukları dolduran JBoss grubunun Seam isimli yeni framework'ünden bahsetmek istiyorum.

Java platformunda yazılım geliştiren insanların en çok entegre bir platform bulamamasından yakındığına şahit oldum bu zamana kadar.(ki bende onlardan biriyim) Seam işte bu noktada devreye giriyor ve başarılı bir entegrasyon platformu olarak karşımıza çıkıyor.

Seam aslında Spring, Hibernate, JSF, EJB, AJAX gibi tanıdık teknolojilerinin artı yönlerinin toplanarak oluşturulan bir platform. Örneğin persistance konusunda Hibernate model olarak alınmışki, Seam'i geliştiren ekibin fikir babasının Hibernate ekibininde beyini olduğunuda dikkate alırsak Seam persistance konusunda başarılı olacak gibi görünüyor.

Ayrıca JBoss tools ile Eclipse gerçekten entegre bir geliştirme ortamına dönüşüyor ve Seam ile uğraşmak zevkli bir hale dönüşüyor. Özellikle Seam'in CRUD generator aracını kullanarak dakikalar içinde CRUD (Create,Read,Update,Delete) işlevlerine sahip temel bir web uygulamasına sahip olabilirsiniz.

Seam ile Spring'le kabus haline dönüşen XML konfigürasyonlarını minimum seviyeye indirebilir ve annotation dünyasına ufak adımlar atmaya başlayabilirsiniz.

Seam'de göze çarpan başka neler var :

Drools : Rol tabanlı otorizasyon (authorization yani :))
Built-in Captcha : Web uygulamanıza girişte ek güvenliği kolayca sağlayabilmek için
ICEfaces, iText, JFreechart vs.vs.vs. gibi Java dünyasının popüler oyuncularıyla entegrasyon... (O kadar şey yazdım merak edip araştırırsınız heralde :))


Tabiki bu kadar farklı teknolojiyi bünyesinde barındırması hazım zorluğunuda beraberinde getiriyor. Yani yukarda bahsettiğim teknoloji konularına hakim değilseniz Seam'i kullanabilmek için 40 fırın ekmek yemeniz gerekecek...


Seam her ne kadar gelecek vaad etsede yüksek öğrenme eğrisiyle popüler olması oldukça zaman alacak gibi görünüyor.

Son bir not : Seam tabiki sadece JBOSS AS ile değil WebSphere, WebLogic gibi uygulama sunucularındada sorunsuz çalıştığını iddia ediyor ben denemedim ama :)
ha birde JDK 1.6 ile test edilmemiş sonuç ne olur bilemem...

Pazar, Şubat 22, 2009

Robot Programmer's Bonanza!

Tekrar Merhabalar,

Bu yazımda ilginç,basit ve bir o kadarda yetenekli bir robot programlama ortamından bahsetmek isiyorum.

RobotBASIC robotunuzun çalışma algoritmalarını yazabileceğiniz ve algoritmanızın sonucunu ekranınızda simule edebilen bir programlama dili. RobotBASIC sadece bir robotu simule etmekten ileri gidiyor ve yazılan programının hiç bir değişiklik yapılmadan yada çok küçük değişikliklerle gerçek robotlarda kullanılmasına olanak sağlıyor.

RobotBASIC ile yazılan programlar birçok küçük ve ucuz robotlar la uyumlu olduğu gibi LegoMindstorms gibi kompleks ve yetenekli robot serileri ilede çalışabiliyor.


Örneğin;

rLocate 100,100
rTurn 90
rForward 300
rTurn 45
rForward 50
rTurn −90
rForward −200
End

yukardaki kod bloğu ile robotunuzu hareket ettirebilir ve simulasyon ekranından sonuçları takip edebilirsiniz yalnız simulasyon ekranı diyince çokta fazla birşey beklemeyin çünkü oldukça ilkel.



bu ekran görüntüsünde ortadaki daire robotumuzu temsil ediyor mesela :)

Pekala Microsoft Robotics gibi müthiş bir simulasyon ortamı dururken neden bunu kullanalım diye bir soru gelebilir aklınıza? Cevabı ise basit benim o ortamı kaldırabilecek bir bilgisayarım yok :)))

Microsoft Robotics'i tam verimle kullanabilmeniz için Physics desteğine sahip güncel bir ekran kartına ve en az çift çekirdekli bir işlemciye ihtiyacınız olacak yoksa robotunuzun bir adım attığını bile görebilmek dakikalar alabilir.


RobotBASIC ile ilgili daha fazla bilgi için http://www.robotbasic.org/ adresini kontrol etmeden geçmeyin.

Görüşmek üzere

Cumartesi, Şubat 14, 2009

Toad ve MySQL başarısı

Merhabalar,

Kuşkusuz MySQL en popüler açık kaynak kodlu veri tabanı yazılımlarının başında geliyor. Sun Microsystems'ın desteğiyle sürekli ve yüksek bir ivmeyle geliştirilmeye devam eden bu veritabanını yeni kullanmaya başlayacaklar için en korkutucu durum tabiki yönetim kısmı.
Hele birde Microsoft yazılım geliştirme araçlarının süslü dünyasında MySQL dünyasına adım atıyorsanız kullanım bir çok açık kaynak kodlu yazılımda olduğu gibi MySQL içinde kabus halini alabilir.

MySQL'i beraberinde gelen komut satırı istemcisiyle kullanmaktan sıkıldığınızda karşınıza bir çok ücretsiz alternatif yazılım çıkacaktır ama bu işi en iyi başaran firmalardan biri olan Quest, Oracle ve SQL Server için hazırladığı Toad veritabanı yönetim aracınının ücretsiz bir versiyonu olan Toad for MySQL 'le MySQL veritabanı yönetimini çocuk oyuncağı haline getirmiş durumda.

Yazılım ER-diagram, Query-builder, Knowledge Expert, kod tamamlama ve formatlama özelliğine sahip editörü ile paralı araçlara ihtiyacımız olmadığını tekrar gözler önüne sermiş durumda.