แสดงบทความที่มีป้ายกำกับ java แสดงบทความทั้งหมด
แสดงบทความที่มีป้ายกำกับ java แสดงบทความทั้งหมด

วันเสาร์ที่ 25 ธันวาคม พ.ศ. 2553

ค้นหา Open Source ซอฟแวร์ในภาษาจาวา

โน๊ตไว้สั้นๆ กันลืมกับเว็บดีๆอย่าง java-source.net ไว้ค้นหา Open Source ซอฟแวร์ในภาษาจาวา มีการจัดหมดหมู่ไว้หาง่ายดี

วันจันทร์ที่ 19 เมษายน พ.ศ. 2553

EJB 3.0 @Stateless @EJB @Resource and JNDI clarity

EJB 3.0 @Stateless @EJB @Resource and JNDI clarity
การกำหนดชื่อของ Service
  • property name เทียบกับ ejb-jar.xml คือ ejb-name

  • property mappedName ใช้กำหนด global JNDI name
ตัวอย่าง
@Stateless // name() defaults to "A2"
public class A1 implements A { ... }

@Stateless(name="A2", mappedName="A2Global") // force product-specific JNDI name to "A1Global"
public class A2 implements A { ... }

การเรียกใช้
  • property name เทียบกับ ejb-jar.xml คือ ejb-ref-name ไว้สำหรับใช้เรียกผ่าน java:comp/env

  • property beanName เทียบกับ ejb-jar.xml คือ ejb-link

  • property mappedName เทียบกับ ejb-jar.xml คือ mapped-name ไว้เรียก global JNDI name
ตัวอย่าง
ภายใต้ application เดียวกัน(อยู่ภายใต้ ear เดียวกัน)
@EJB
private A a;

@EJB(beanName="A2")
private A a;

ต่าง application กัน
@EJB(mappedName="A1/local") // for JBoss
private A a;

@EJB(mappedName="A2Global")
private A a;

หมายเหตุ mappedName เป็น product-specific JNDI name ฉะนั้นระวังด้วยหาก application ต้องการความสามารถ portability ซึ่งใน EJB 3.1 ที่มีการกำหนดเรื่อง portable JNDI name ไว้ แนะนำให้ใช้ property lookup แทน

อ้างอิง
forums.sun.com
What is the relationship between @EJB and ejb-ref/ejb-local-ref?
Partial Deployment Descriptors

วันพุธที่ 16 กันยายน พ.ศ. 2552

Java Decompiler

ตั้งแต่ย้ายมาทำงานบน Ubuntu เพิ่งจะได้มีโอกาศต้อง decompile โค้ดชาวบ้านเค้า ปกติจะใช้งาน Open source ซะส่วนใหญ่เลยสบายไป
หาๆเจอ JD-GUI, JD-Eclipse ที่นี่เลย Java Decompiler project ใช้ได้เลย

How to add a TrueType font to Java

To add a TrueType font to Java, just put the .TTF file in the /usr/java/jre/lib/fonts directory.

Note: you may need to restart the JVM to see it

Thank http://www.fileformat.info/tip/java/ttf.htm

วันอังคารที่ 28 กรกฎาคม พ.ศ. 2552

Transaction annotation-driven แล้ว Spring สร้างอะไรให้บ้าง

การใช้งาน @Transactional จะต้องกำหนดใน Spring Context ดังนี้

<tx:annotation-driven transaction-manager="transactionManager" />

มาดูกันว่า มันสร้างอะไรให้บ้าง

<aop:aspectj-autoproxy />
<bean id="transactionAttributeSource" class="org.springframework.transaction.annotation.AnnotationTransactionAttributeSource" />
<bean id="transactionInterceptor" class="org.springframework.transaction.interceptor.TransactionInterceptor">
<property name="transactionManager" ref="transactionManager" />
<property name="transactionAttributeSource" ref="transactionAttributeSource" />
</bean>
<bean id="org.springframework.transaction.config.internalTransactionAdvisor" class="org.springframework.transaction.interceptor.BeanFactoryTransactionAttributeSourceAdvisor">
<property name="transactionAttributeSource" ref="transactionAttributeSource" />
<property name="adviceBeanName" value="transactionInterceptor" />
</bean>

บรรทัดแรกสั่งให้ Spring ทำ auto proxy จาก Advisor ที่มีการคอนฟิกใน Spring Context
ที่ เหลือเป็นการคอนฟิก Advisor, Interceptor(เป็น Advice) และ TransactionAttributeSource ที่ทำหน้าที่ บอกว่า method ของ class ที่ถูกเรียกนี้มี TransactionAttribute ยังไง
ตัวที่บอกรายละเอียด Transaction พวก propagation, isolation, timeout ฯลฯ อยู่ที่ TransactionAttribute นี่แหละ

อันนี้เฉพาะโหมด proxy ของ annotation-driven ยังไม่ไล่โหมด aspectj แต่มันก็คือๆกันแหละแค่เปลี่ยนการทำ proxy จากใช้ Proxy ของ JDK เป็น cglib แทน

วันเสาร์ที่ 25 กรกฎาคม พ.ศ. 2552

ดูการสร้าง Bean ของ Spring JavaConfig

เริ่มแรกดูการคอนฟิก Spring Context ก่อนจากเดิมใช้ XML เป็น Java + Annotation

@Configuration
class MyConfig {
public @Bean MyBean myBean() {
new MyBean();
}
}


เพื่อให้ง่ายต่อความเข้าใจจะใช้ XML ร่วมกับ ConfigurationPostProcessor เพื่อทำ Bootstrapping JavaConfig

<beans>
<!-- first, define your individual @Configuration classes as beans -->
<bean class="myapp.MyConfig"/>

<!-- be sure to include the JavaConfig bean post-processor -->
<bean class="org.springframework.config.java.process.ConfigurationPostProcessor"/>
</beans>

จะเห็นได้ว่ามีการกำหนด MyConfig เป็น Spring Bean ร่วมกับใช้ ConfigurationPostProcessor ซึ่งเป็น BeanFactoryPostProcessor ชนิดหนึ่ง

การสร้าง Spring Bean แบบปกติตัวที่ทำหน้าที่สร้าง Instance Bean คือ InstantiationStrategy

Spring JavaConfig ก็ใช้หลักการเดียวกัน แต่จะใช้การสร้าง bean ผ่าน Factory Method นั่นคือ MyConfig.myBean() จะทำหน้าที่เป็น Factory Method นั่นเอง หากแปลงเป็น XML จะได้ประมาณนี้

<bean id="myconfig" class="myapp.MyConfig" />
<bean id="myBean" factory-bean="myconfig" factory-method="myBean" />


ส่วนเหตุที่มานั่งไล่ Spring JavaConfig เพราะกำลังเขียน BeanDefinitionParser อยากให้ Instance ที่สร้างใน BeanDefinitionParser ด้วยการ new Object ธรรมดานี่แหละขึ้นมาเป็น Spring Bean เลยมาดูสักหน่อยว่า Spring JavaConfig ใช้วิธีไหน

วันพุธที่ 15 กรกฎาคม พ.ศ. 2552

Distribution Spring, maven repository, and SpringIDE

You can find those on "Amazon S3 Web Frontend".
Distribution Spring at dist.springframework.org, in addition, you can find SpringIDE updatesite here too.
Spring Maven repository at maven.springframework.org.
Enjoy your spring anytime.

วันพฤหัสบดีที่ 16 เมษายน พ.ศ. 2552

JBoss5 JNDI

เพิ่งจะได้ลอง JBoss 5.0.1 หลังจากที่ลอง JBoss 5.0 ตั้งแต่วันแรกที่ออก(อุตส่าห์รอคอย)
ใน JBoss 5.0 พบว่าเขียน Test client (java class with main method to call ejb service) เปลี่ยน namming ให้ตายก็ lookup ไม่เจอสักทีเสียเวลาเป็นวัน เลิกเลย

หลังจากเห็น JBoss 5.0.1 ออกมาเกือบสองเดือนก็ยังไม่ได้เทส วันนี้ว่างๆเลยขอลองซะหน่อย
ปรากฏว่าเต่นเต๋นเต้น ตอน deploy เสร็จเห็นเลยว่ามี JNDI อะไรบ้างที่ binding เข้ากับ Global JNDI เลย
23:30:20,632 INFO [JndiSessionRegistrarBase] Binding the following Entries in Global JNDI:

MyPrint/remote - EJB3.x Default Remote Business Interface
MyPrint/remote-test.PrintRemote - EJB3.x Remote Business Interface


เข้าไปดูใน JMX Console ก็เห็นเหมือนเวอร์ชั่น 4.2 ด้วย(ดีใจไม่ต้องเสียเวลางม)
+- MyPrint (class: org.jnp.interfaces.NamingContext)
| +- remote-test.PrintRemote (class: Proxy for: test.PrintRemote)
| +- remote (class: Proxy for: test.PrintRemote)


ตัว Test client ก็ง่ายๆเหมือนเวอร์ชั่น 4.2 เลย

public class PrintClient {
public static void main(String[] args) {
try {
Properties prop = new Properties();
prop.setProperty("java.naming.factory.initial","org.jnp.interfaces.NamingContextFactory");
prop.setProperty("java.naming.provider.url","jnp://localhost:1099");
prop.setProperty("java.naming.factory.url.pkgs","org.jboss.naming:org.jnp.interfaces");

InitialContext ctx = new InitialContext(prop);
PrintRemote print = (PrintRemote)ctx.lookup("MyPrint/remote");
print.display();
} catch (Exception e) {
e.printStackTrace();
}
}
}

จบเรื่องคาใจไปอีกเรื่อง งมใน mail ก็เห็นคนบ่นกัน ว่าแล้วว่ามันต้องแก้

วันจันทร์ที่ 6 เมษายน พ.ศ. 2552

Bug in GORMSessionFactoryDefinitionParser

In GORM of Grails 1.1, I found this bug.
if you define context.xml like this.

<bean id="txManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory" />
</bean>
<gorm:sessionFactory base-package="org.grails.samples"
data-source-ref="dataSource" message-source-ref="messageSource" transaction-manager-ref="txManager">
<property name="configLocations" value="classpath:hibernate.cfg.xml" />
<property name="hibernateProperties">
<util:map>
<entry key="hibernate.hbm2ddl.auto" value="update" />
</util:map>
</property>
</gorm:sessionFactory>

An attribute transaction-manager-ref is not necessary, for Grails will create transactionManager (org.springframework.orm.hibernate3.HibernateTransactionManager), but whether you provide your transaction manager, you will see this exception.
Exception in thread "main" org.springframework.beans.factory.NoSuchBeanDefinitionException: No bean named 'transactionManager' is defined
at org.springframework.beans.factory.support.DefaultListableBeanFactory.getBeanDefinition(DefaultListableBeanFactory.java:387)
at org.springframework.beans.factory.support.AbstractBeanFactory.getMergedLocalBeanDefinition(AbstractBeanFactory.java:971)
at org.springframework.beans.factory.support.AbstractBeanFactory.isFactoryBean(AbstractBeanFactory.java:758)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:422)
at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:728)
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:380)
at org.springframework.context.support.ClassPathXmlApplicationContext.(ClassPathXmlApplicationContext.java:139)
at org.springframework.context.support.ClassPathXmlApplicationContext.(ClassPathXmlApplicationContext.java:83)
at com.gable.grails.test.interoperation.App.main(App.java:15)

In found in GORMSessionFactoryDefinitionParser on line 213.

targetRegistry.registerAlias("transactionManager", transactionManagerRef);

I thought this line intend to give transactionManager being an alias of transactionManagerRef.
It should be

targetRegistry.registerAlias(transactionManagerRef, "transactionManager");

วันศุกร์ที่ 20 มีนาคม พ.ศ. 2552

The ways to deal with non-transactional resources

There are serveral ways to deal with them.
1. Interaction without regard to transactionality. This approach is appropriate when there is no need for transaction management.
2. Development of transactional interfaces. This approach is the most comprehensive, but also the most time consuming because it needs to implement JTA interfaces (implementation of javax.transaction.xa.XAResource).
3. Implement the interactions in a “pseudo-transaction” that explicitly checks for and manages error conditions and rollback. I thought this approach like transaction in the web service which have to implement method for rollback by yourself.
In the detail, you can read at TheServerSide.

วันพฤหัสบดีที่ 19 มีนาคม พ.ศ. 2552

Problem from using JPA in grails with maven

I got this problem when i called $mvn grails:run-app.
[groovyc] Compiling 9 source files to /media/src/source/Eclipse/TestFrameWork/workspace/groovy/my-app/target/classes
[groovyc] org.codehaus.groovy.control.MultipleCompilationErrorsException: startup failed, Compile error during compilation with javac.
[groovyc] /media/src/source/Eclipse/TestFrameWork/workspace/groovy/my-app/src/java/org/grails/samples/Person.java:3: package javax.persistence does not exist
[groovyc] import javax.persistence.Entity;
[groovyc] ^
[groovyc] /media/src/source/Eclipse/TestFrameWork/workspace/groovy/my-app/src/java/org/grails/samples/Person.java:4: package javax.persistence does not exist
[groovyc] import javax.persistence.GeneratedValue;
[groovyc] ^
[groovyc] /media/src/source/Eclipse/TestFrameWork/workspace/groovy/my-app/src/java/org/grails/samples/Person.java:5: package javax.persistence does not exist
[groovyc] import javax.persistence.GenerationType;
[groovyc] ^
[groovyc] /media/src/source/Eclipse/TestFrameWork/workspace/groovy/my-app/src/java/org/grails/samples/Person.java:6: package javax.persistence does not exist
[groovyc] import javax.persistence.Id;
[groovyc] ^
[groovyc] /media/src/source/Eclipse/TestFrameWork/workspace/groovy/my-app/src/java/org/grails/samples/Person.java:7: package javax.persistence does not exist
[groovyc] import javax.persistence.Version;
[groovyc] ^
[groovyc] /media/src/source/Eclipse/TestFrameWork/workspace/groovy/my-app/src/java/org/grails/samples/Person.java:26: cannot find symbol
[groovyc] symbol: class Entity
[groovyc] @Entity
[groovyc] ^
[groovyc] /media/src/source/Eclipse/TestFrameWork/workspace/groovy/my-app/src/java/org/grails/samples/Person.java:28: cannot find symbol
[groovyc] symbol : class Id
[groovyc] location: class org.grails.samples.Person
[groovyc] @Id
[groovyc] ^
[groovyc] /media/src/source/Eclipse/TestFrameWork/workspace/groovy/my-app/src/java/org/grails/samples/Person.java:29: cannot find symbol
[groovyc] symbol : class GeneratedValue
[groovyc] location: class org.grails.samples.Person
[groovyc] @GeneratedValue(strategy=GenerationType.AUTO)
[groovyc] ^
[groovyc] /media/src/source/Eclipse/TestFrameWork/workspace/groovy/my-app/src/java/org/grails/samples/Person.java:31: cannot find symbol
[groovyc] symbol : class Version
[groovyc] location: class org.grails.samples.Person
[groovyc] @Version
[groovyc] ^
[groovyc] 9 errors
[groovyc]
[groovyc]
[groovyc] 1 error
Compilation error: Compilation Failed

It seems javax.persistence does not exist in maven dependencies of grails-maven-archetype 1.0.
To fix this problem, I added ejb3-persistence in pom.xml.

<dependency>
<groupId>org.hibernate</groupId>
<artifactId>ejb3-persistence</artifactId>
<version>1.0.2.GA</version>
</dependency>

วันเสาร์ที่ 3 มกราคม พ.ศ. 2552

Other ways to run Maven on Eclipe.

M2eclipse is excellent Maven tool for Eclipse.
I always use hotkey Shift + Alt + X M to run the last maven goals of Maven Build projects.
example First time you run "compile goal" of MyProject. Next time you want to run with other goals. If you use this hotkey, It will run "compile goal" again. You must move a mouse, right click on project, then select Run as Maven builds ... and key the new goal that you want. It is inconvenient.

Today I read Eclipse integration with Grails. In the step Adding domain classes etc, It shows the way to use External Tools to run grails command. It can adapt to run maven goals.
1 Run -> External tools -> External tools configuration ... .
2 Select Program and new launch configuration.
3 Enter a name of "Maven".
4 Browse file system for the location of mvn command that you have installed.
5 Set the working directory to "${project_loc}".
6 Set the arguments as "${string_prompt}".
7 Under the "Refresh" tab, set to refresh the "project containing the selected resource" upon completion.
8 Under the "Common" tab, tick "Display in favorites menu".
9 I set hotkey Shift + Alt + X S to Runs the last launched external Tool.

Every time you use thes hotkey, Eclipe will always ask you what is the goals you need to run.
You can type any maven goals.