java etiketine sahip kayıtlar gösteriliyor. Tüm kayıtları göster
java etiketine sahip kayıtlar gösteriliyor. Tüm kayıtları göster

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.

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.

01 Nisan 2007

Java 6'da Print API Hatası

Java Print API bir uygulamadaki yazılı çizili ne varsa bunları yazdırmanızı sağlayan bir kütüphanedir. Bu kütüphane yardımı ile bir Graphics nesnesinde çizdirdiğiniz her şeyi bir yazıcıya gönderip yazdırabilirsiniz. Ayrıca bu API sistemdeki tanımlı yazıcıları kullandığı için sizin kodda yazıcı bulmak için çok fazla uğraşmanıza gerek yoktur. Örneğin; Windows'ta tanıttığınız yazıcıları Java Print API kullanabilir.
İşte bende geçenlerde iş yerimde yazdığımız bir uygulamada Graphics nesnesine çizdirdiğim şeyleri bir kart yazıcısında yazdırmak için bu API'yi kullandım. İlk başta Java 5 ile uygulamayı geliştiriyordum ve gayet güzel çalışıyordu. Yazdığımız uygulama da demo amaçlı bir uygulama idi ve bir gün sonra demo yapacaktık. Herşey gayet düzgün gidiyordu, ta ki Java 6'ya geçene kadar. Son gün Java 6'ya geçtiğimde biraz daha kod yazmaya deva ettim ve uygulamayı bir kez daha denedim. Bir de ne göreyim bir gün düzgün çıktı verdirten kod şimdi düzgün çıktı verdirmiyordu. Sonra birkaç kez daha denedim ama sonuç nafile. Tabi o sırada sorunun Java 6'dan kaynaklandığı hiç aklımın ucundan bile geçmiyordu. 7 saat uğraştıktan sonra arkadaşların yardımı ile Java 6 aklımın ucuna geldi. Daha sonra Java 5'e geçince sorun bitti ama bende bittim.
Diyeceğim Java 6 kullanırken böyle hatalar ile karşılaşabilirsiniz. Muhtemelen geliştiricileri bu API'yi Java 6 için test etmediler. Çünkü bu API bayadır var. Bunu bir bug olarak SUN'ın sitesine girmek lazım...

17 Mart 2007

Dosyalarınızı Nasıl Sıkıştırırsınız?

Merhabalar,
Java'da dosyalarınızı ve klasörlerinizi hiç sıkıştırmayı denediniz mi? Denemediyseniz buyrun böyle alalım:) . Java'yı kullanarak dosya ve klasörlerinizi arşivleyen bir program yazabilirsiniz. Bunun için "java.util.zip" paketini kullanabilirsiniz. Bu iş için bu paketteki ZipFile, ZipEntry ve ZipOutputStream sınıflarını kullanabilirsiniz.
ZipEntry sınıfı zip dosyasında saklanacak her bir elemanı temsil eder. Bu elemanlar dosyalar ve klasörlerdir. ZipFile sınıfı bir zip dosyasını temsil eder. ZipOutputStream ise bir zip dosyasına için gerekli olan I/O sınıfıdır.
İsterseniz örneklere bakarak inceleyelim:

1. Bir dosyayı sıkıştırmak için:

byte[] readBuffer = new byte[2156];
int bytesIn = 0;

FileInputStream fis = null;
ZipOutputStream zos = null;
try {
zos = new ZipOutputStream(new FileOutputStream(""));
fis = new FileInputStream(<"Sıkıştırılacak dosyanın yolu">);
// dosya bir zip elemanı haline dönüştürülüyor
ZipEntry anEntry = new ZipEntry(fileToZip.getPath());
// Zip elemanı yazılmak üzere ZipOutputStream nesnesine veriliyor.
zos.putNextEntry(anEntry);
// Son olarak dosyanın içeriği stream'e yazılıyor.
while((bytesIn = fis.read(readBuffer)) != -1)
{
zos.write(readBuffer, 0, bytesIn);
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
// yazma işlemi bittikten sonra streamler kapatılıyor.
try {
fis.close();
zos.close();
} catch (IOException ex) {}
}

2. Bir klasörü sıkıştırmak için:
Klasör ve klasörün her bir elemanı ayrı bir entry olduğu için ayrı ayrı sıkıştırılır.

File dirTozip = new File(<"Sıkıştırılacak klasörün yolu">);
ZipOutputStream zos = null;
try
{
zos = new ZipOutputStream(new FileOutputStream(""));
// gerçekten klasör mü?
if ( !dirTozip.isDirectory() ) {
throw new IllegalArgumentException(dirTozip+" bir klasör olmalı!");
}
// klasörün içeriği alınıyor
String[] dirList = dirTozip.list();
// klasörün içindeki her bir eleman ayrı ayrı sıkıştırılıyor.
for(int i=0; i
{
File f = new File(dirTozip, dirList[i]);
if(f.isDirectory())
{
// eğer bu File nesnesi bir klasörse içindekileri sıkıştırmak için
// bu fonksiyon yeniden çağrılır (recursive)
// yeni bir klasörü elemanı oluşturuluyor.
ZipEntry anEntry = new ZipEntry(f.getPath()+"/");
zos.putNextEntry(anEntry);
zipDir(f, zos);

continue;
}
// Buraya ulaştıysak bir dosya sıkıştırabiliriz demektir.
zipFile(f, zos);
}
} catch(Exception e) {
e.printStackTrace();
} finally {
// yazma işlemi bittikten sonra streamler kapatılıyor.
try {
fis.close();
zos.close();
} catch (IOException ex) {}
}

3. Bir zip dosyasını açmak için:

Enumeration entries;
ZipFile zipFile;

try {
zipFile = new ZipFile(<"Açılacak zip'in yolu">);
entries = zipFile.entries();

byte[] buffer = new byte[1024];
int len;

while(entries.hasMoreElements()) {
ZipEntry entry = (ZipEntry)entries.nextElement();

// eğer entry bir klasör ise klasör oluşturulmalı
if(entry.isDirectory()) {
(new File(entry.getName())).mkdir();
continue;
}

// Entry açılıyor....
InputStream in = zipFile.getInputStream(entry);
BufferedOutputStream out = new BufferedOutputStream(new FileOutputStream(entry.getName()));

while((len = in.read(buffer)) >= 0)
out.write(buffer, 0, len);

in.close();
out.close();

}

zipFile.close();
} catch (IOException ioe) {
ioe.printStackTrace();
return;
}

Bu 3 işlemle basit bir arşivleme programı yazabilirsiniz. Kolay gelsin...