Friday, July 5, 2013

Create a keystore (Certificate) and then sign jar (applet)

To sign a jar
  1. Need to create a keystore (like Certificate)
    1. Go to your java jdk directory (e.g. C:\Program Files\Java\jdk1.6.0_25\bin)
    2. Type keytool -genkey -keystore icepdfapplet.keystore -alias icepdfapplet -keyalg RSA where icepdfapplet.keystore will be created
    3. You will be asked for Name, Unit... and password (Please remember the password)
    4. The keystore will be successfully created
  2. Now assign the certificate to the jar
    1. Type jarsigner -keystore icepdfapplet.keystore -storepass 123456789 icepdf-applet.jar icepdfapplet where 123456789 is the password I entered in the previous and icepdf-applet.jar is the jar file being assigned with the certificate
>keytool -genkey -keystore icepdfapplet.keystore -alias icepdfapplet -keyalg RSA
>jarsigner -keystore icepdfapplet.keystore -storepass 123456789 icepdf-applet.jar
icepdfapple

Thursday, July 4, 2013

"ant" is not recognized as an internal or external command

If you find that you run ant command in command prompt, there is an error that "ant" is not recognized as an internal or external command,

Please do the following steps.
  1. Download the apache-ant binary distributions zip file and unzip it under C:\bin directory
  2. Edit the computer environment variable (Right click My Computer and select properties > Advance > Environment Variable)
  3. Add C:\bin\apache-ant\bin in Path Variable
When open a command console, and type echo PATH. You will see the newly added path C:\bin\apache-ant\bin

Monday, April 22, 2013

SQL Exception 17009 - Closed Statement

花了一段時間去 investigate 個 SqlException with Error code '17009'.

我主要用 dbcp 作 datasource, spring 3.1 既 aop 做 declarative transaction management 同 mybatis 既 SqlSessionDaoSupport, 用SqlSessionDaoSupport是因為我有機會在 DAO Implementation 做一些 java coding.

我個development condition:
1) Spring 3.1.0
2) Spring Security 3.2.0
3) Vaadin 6.8.2
4) Spring-Mybatis 1.1.1
5) MyBatis 3.2.0
6) Java 5+
7) Oralce 10g

我是沒有用 annotation. 主要原因是方便和清楚知道每個 manager 的關係.

在 spring 的 config. file 裡,加上以下的codes.

<!-- Configure your datasource -->
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource">
        <property name="driverClassName" value="${db.driverClassName}" />
        <property name="url" value="${db.url}" />
        <property name="username" value="${db.username}" />
        <property name="password" value="${db.password}" />
        <property name="defaultAutoCommit" value="false" />
        <property name="poolPreparedStatements" value="true" />
 <property name="maxOpenPreparedStatements" value="50" />
 <property name="validationQuery" value="select 1 from dual"/>
</bean>

<!-- Configure a SQL session for SQL execution in DAO layer -->
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
 <property name="dataSource" ref="dataSource" />  
 <property name="configLocation" value="classpath:mybatis-config.xml"/>  
</bean>

<!-- Use AOP to set the transaction management -->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">  
  <property name="dataSource" ref="dataSource" />  
</bean>
<aop:config>
    <aop:pointcut id="transactionService" expression="execution(* com.gpch.cams.service.*Manager.*(..))"/>
    <aop:advisor advice-ref="txAdvice" pointcut-ref="transactionService" order="1"/>
</aop:config>
<tx:advice id="txAdvice" transaction-manager="transactionManager">
        <tx:attributes>         
            <tx:method name="get*" read-only="true"/>
            <tx:method name="*" propagation="REQUIRED"/>                        
        </tx:attributes>
</tx:advice>

<!-- set sqlSessionFactory for your DAO -->
<bean id="employeeDao" class="com.gpch.cams.dao.impl.EmployeeDaoImpl">
 <property name="sqlSessionFactory" ref="sqlSessionFactory"/>
</bean>

<!-- In your java class (e.g. EmployeeDaoImpl) -->
<!-- must extend SqlSessionDaoSupport -->
<!-- use getSqlSession() to call and execute your MyBatis Sql -->
public class EmployeeDaoImpl extends SqlSessionDaoSupport implements EmployeeDao{

    public Employee getEmployee(Long empId){
          return (Employee) getSqlSession().selectOne("getEmployeeRecordById", empId);
    }
}



一開波run 個program 都冇事, 做insert 都係冇事, 但run run 下就出現以下的exception. 找了一段時間, 仲要係間歇性出現. 最後發現用錯了jars. 應該用 common-dbcp-1.2.2.jar and common-pool-1.4.jar

2013-04-22 10:44:42,665 DEBUG [org.springframework.beans.factory.support.DefaultListableBeanFactory] - Finished creating instance of bean 'Sybase'
2013-04-22 10:44:42,665 INFO [org.springframework.jdbc.support.SQLErrorCodesFactory] - SQLErrorCodes loaded: [DB2, Derby, H2, HSQL, Informix, MS-SQL, MySQL, Oracle, PostgreSQL, Sybase]
2013-04-22 10:44:42,665 DEBUG [org.springframework.jdbc.support.SQLErrorCodesFactory] - Looking up default SQLErrorCodes for DataSource [org.apache.commons.dbcp.BasicDataSource@2596c1]
2013-04-22 10:44:42,665 DEBUG [org.springframework.jdbc.support.SQLErrorCodesFactory] - Database product name cached for DataSource [org.apache.commons.dbcp.BasicDataSource@2596c1]: name is 'Oracle'
2013-04-22 10:44:42,665 DEBUG [org.springframework.jdbc.support.SQLErrorCodesFactory] - SQL error codes for 'Oracle' found
2013-04-22 10:44:42,665 DEBUG [org.springframework.jdbc.support.SQLErrorCodeSQLExceptionTranslator] - Unable to translate SQLException with Error code '17009', will now try the fallback translator
2013-04-22 10:44:42,665 DEBUG [org.mybatis.spring.SqlSessionUtils] - Releasing transactional SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@40d241]
2013-04-22 10:44:42,665 DEBUG [org.springframework.jdbc.datasource.DataSourceTransactionManager] - Initiating transaction rollback
2013-04-22 10:44:42,665 DEBUG [org.springframework.jdbc.datasource.DataSourceTransactionManager] - Rolling back JDBC transaction on Connection [jdbc:oracle:thin:@localhost:8081:oral, UserName=test, Oracle JDBC driver]
2013-04-22 10:44:42,744 DEBUG [org.mybatis.spring.SqlSessionUtils] - Transaction synchronization rolling back SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@40d241]
2013-04-22 10:44:42,744 DEBUG [org.mybatis.spring.SqlSessionUtils] - Transaction synchronization closing SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@40d241]
2013-04-22 10:44:42,744 DEBUG [org.springframework.jdbc.datasource.DataSourceTransactionManager] - Releasing JDBC Connection [jdbc:oracle:thin:@localhost:8081:oral, UserName=test, Oracle JDBC driver] after transaction
2013-04-22 10:44:42,744 DEBUG [org.springframework.jdbc.datasource.DataSourceUtils] - Returning JDBC Connection to DataSource
Other Threads:
https://forums.oracle.com/forums/thread.jspa?messageID=10509456
https://issues.apache.org/jira/browse/DBCP-28

Tuesday, March 26, 2013

iReport 4.0.1 - Connect DB with iReport

 To create a new DB connection into iReport

  • 選擇 "Window" and select "Services" 去開著 "Services" 視窗
  • 選擇 "Databases" in "Services" , 然後 right click and select "New Connection"
  • 選擇 "New Driver" for "Name"
  • 加 ojdbc14.jar 
  • 輸入 User Name, Password 和 JDBC URL

 To Add data source from existing DB connection

  • 選擇 Report datasources
  • Click "New"
  • Select Database JDBC connection
  • And then input the correct information.


Friday, March 1, 2013

Linux Concepts

讀大學的時候,主要學習寫程式的概念,對於伺服器那方面東西不太清楚.出來工作後,很多時要configure servers (e.g linux)

要趁早學多一點,免得用起上來來個措手不及.

以下這個綱頁做得幾好,因許多時的 Tutorial 都是教寫 command 而忽略了背後的意義,原因和運作.但這個綱頁主要講述 concept 的東西!

http://www.linux-tutorial.info/modules.php?name=MContent&pageid=224

對我來說,寫唔難,Configure 唔難,最難是採用那一個方法是最好,或者的怎樣解決!寫同configure都係 syntax 野,每個 programmer 只要 google 一下就會找到答案,但 methods 就唔同,是 concept 野,因為你要識這樣東西才能在某指定的情況下提出最合適的解決方法.

希望在這年裡有多一點時間去不斷增值自己!加油!

Monday, February 18, 2013

Java VisualVM to monitor memory

Condition: You want to monitor the java heap size in your local PCs or remote servers. You could use Java VisualVM tool if your device (local PCs or remote servers) must have jdk1.5+ for program execution. For Unix and Linux, they must install X-windows first.

Step to run the Java VisualVM.
  1. echo "%JAVA_HOME%"
    (To show your installed JDK path. e.g. C:\Program Files\Java\jdk1.6.0_25\bin)
  2. cd "%JAVA_HOME
    (Go to your JDK bin)
  3. jvisualvm.exe
    (Run Java VisualVM tool)
According to the following picture, you will see that 3 Java Applications are running on my PC. They are
  1. Unknow Application (pid 3164)
  2. JDeveloper 11g (pid 248)
  3. Tomcat (pid 3560)

Double the java application you want to monitor. I chose Tomcat as an example. You can select Monitor, Threads, Sampler and Profiler tabs to view the statistic.

To monitor remote server (JBOSS), you could
  1. Right click "Remote" and select "Add Remote Host..."
  2. Input your Host Name such as 192.168.254.111
  3. Click "Advanced Settings" and input Post 2020 (jstsd port - RMI Broadcasting - Listener) and set the Refresh Interval
  4. Then you will see 192.168.254.111 under remote
  5. Right click 192.168.254.111 and select "Add JMX Connection"
  6. Input Port "1090" (JMX port setting in Jboss - Check your server setting)
  7. Input Username and password
My Personal Jboss Testing Server Setting
  • JMX port in JBoss server : 1090
  • jstatd port in JBoss server : 2020
  • jstatd port in local (PC) Tomcat server (your IP) should be as default

Monday, February 4, 2013

Vaadin 6.8 with EmbedPDF

Introduction: 

Environment:
Vaadin 6.8 + AppletIntegration 1.2.9 (Add-on)
Spring-Security 3.1.2
Spring 3.1.0
EmbedPDF.jar (Version: 0.18)

Condition: 

Due to business requirement, it only allows users to print PDF. No save function will be provided at all. (That means: No PDF file will be created at the Local directory)

I tired to find the solution on the internet but no suitable methods for me. Therefore, I used the EmbedPDF Applet instead of Adobe Reader to view PDF.

There are several steps that will be gone through in details:
  1. Add Vaadin addon AppletIntegration (not describe in details)
  2. Add the EmbedPDF Applet into your Vaadin Web Application
  3. Configure your Spring-Security file

Add the EmbedPDF Applet into your Vaadin Web Application

  1. Create a directory named "applet" under your WebContent/VAADIN/  It is because files under /WEB-INF directory are protected. It is not allowed to be directly accessed by users.
  2. Place your EmbedPDF.jar and a PDF file into "applet" directory 
  3. In your source code, please pay attention to 
    • AppletClass - it always be "EmbedPDF.class"
    • Codebase - it is the directory your EmbedPDF.jar placed into
    • AppletParams - they are the parameters being passed into the EmbedPDF applet
      • Please kindly refer to the EmbedPDF Specification Readme file. There are some parameters must be set.
     
    VerticalLayout x = new VerticalLayout();
    AppletIntegration applet2 = new AppletIntegration(){  
         private static final long serialVersionUID = 7124868233557401171L;  
         @Override  
         public void attach(){  
             setAppletArchives(Arrays.asList(new String[]{"EmbedPDF.jar"}));  
             setCodebase("/ProjectName/VAADIN/applet/");     
             setAppletClass("EmbedPDF.class");  
             setAppletParams("id", "embedId");  
             setAppletParams("pdf", "/ProjectName/VAADIN/applet/example.pdf");  
             setAppletParams("enableOpenWindow", "false");  
             setWidth("500px");  
             setHeight("500px");  
         }  
     };  
     x.addComponent(applet2);  
     getApplication().getMainWindow().addWindow(x);  
    
The file structure

Configure your Spring-Security file

  1. It is required to make the /VAADIN/applet/ directory to be Anonymously. It is because a new session will be created when the EmbedPDF applet is called. So, the spring security go through the authentication. It is required to pass the username and password to the spring security for the authentication process. There is an exception thrown in the app. server since spring security cannot get the username and password. So, it will block the EmbedPDF.jar and EmbedPDF.class to run. 
  2. There lists some exceptions will be found if the spring security setting is not correct
    • java.lang.ClassFormatError: Truncated class file
    • java.lang.ClassFormatError: Incompatible magic value 537528892 in class file
 <http auto-config="false" entry-point-ref="authenticationEntryPoint"   
     access-denied-page="/jsp/login_error" use-expressions="true">  
     <intercept-url pattern="/jsp/login*" access="permitAll" />  
     <intercept-url pattern="/jsp/login_error*" access="permitAll" />  
     <intercept-url pattern="/VAADIN/applet/**" access="permitAll" />  
     <intercept-url pattern="/**" access="hasRole('ROLE_USER')" />  
     <logout invalidate-session="true"/>  
     <custom-filter ref="authenticationFilter" position="FORM_LOGIN_FILTER"/>  
 </http>  

Addition Information: Delete the dynamic generated PDF file

  1. The following code describe how to get the absolute path in java for server
  2. It is better to use a helper to create a PDF file and return a new AppletIntegration
  3. When user removes the Applet from the layout, the remove will be deleted (see the "detach" function)

//TODO: create your own file

VerticalLayout x = new VerticalLayout();
final String filename = "example.pdf";
final String absReportzPath = String absProjPath = ((WebApplicationContext)ProjectApplication.getInstance().getContext())
 .getHttpSession().getServletContext().getRealPath("/VAADIN/reportz/reportz/");

AppletIntegration applet2 = new AppletIntegration(){  
     private static final long serialVersionUID = 7124868233557401171L;  
     @Override  
     public void attach(){  
         setAppletArchives(Arrays.asList(new String[]{"EmbedPDF.jar"}));  
         setCodebase("/ProjectName/VAADIN/applet/");     
         setAppletClass("EmbedPDF.class");  
         setAppletParams("id", "embedId");  
         setAppletParams("pdf", "/ProjectName/VAADIN/applet/reportz/"+filename);  
         setAppletParams("enableOpenWindow", "false");  
         setWidth("500px");  
         setHeight("500px");  
     }  

     @Override
     public void detach(){ //To delete file if the applet is removed.
         String absPath = getAbsoluteReportzDirectory();
         File delFile = new File(absReportzPath+"/"+fileName);
         if(delFile.exists()){
             delFile.delete();
         }
     }
 };  
 x.addComponent(applet2);  
 getApplication().getMainWindow().addWindow(x);  

Friday, February 1, 2013

Enable HTTPS (SSL) in Tomcat7

Introduction:

To make the redirection from HTTP to HTTPS in Tomcat. There are two required steps that must be done.
  1. Generate a self-sign key (Certificate)
  2. Configure the Tomcat Server Setting
The detail steps of each part are listed below. Hope it could be useful and helpful.

Generate a self-sign key (Certificate) with the following command.

  • Open a command console and type [cmd]
  • Type [set] in order to check your java jdk directory (e.g. C:\Program Files\Java\jdk1.6.0_25\bin)
  • Type [cd ${java_directory}] (e.g. cd C:\Program Files\Java\jdk1.6.0_25\bin)
  • Type [keytool -genkey -keystore chap8.keystore -storepass rmi+ssl -keypass rmi+ssl -keyalg RSA -alias chapter8  -validity 3650 -dname "cn=chapter8 example,ou=admin book,dc=jboss,dc=org"]
    • Words/Fonts with bold style can be modified
    • chap8.keystore - Sign file name and will be generated/created in your java jdk bin directory (e.g. C:\Program Files\Java\jdk1.6.0_25\bin)
    • rmi+ssl - Password
    • chapter8 - Alias name
    • validity - How long your self-issued certificate is valid
    • inside the quote sign "chapter8, adminbook, jboss, org" are not important. It is just the information of your certificate for people to view.
  • There is a chap8.keystore file (certificate)  is created in your java jdk bin directory (e.g. C:\Program Files\Java\jdk1.6.0_25\bin)
  • Copy the generated certificate "chap8.keystore" to the folder ${cataline.home}/conf/ (e.g. C:\bin\apache-tomcat-7.0.27\conf\)

Configure the Tomcat server setting

  •  Edit ${cataline.home}/conf/server.xml and modify the following
  •  <Connector port="8080" protocol="HTTP/1.1" enableLookups="false" redirectPort="8443" /> 
  • <Connector protocol="org.apache.coyote.http11.Http11NioProtocol"
                port="8443" SSLEnabled="true" maxThreads="200"
                scheme="https" secure="true"
                keystoreFile="/conf/chap8.keystore"
                keystorePass="rmi+ssl" clientAuth="false"
                sslProtocol="TLS"/>
     
    • chap8.keystore - certificate file name you type in the previous steps
    • rmi+ssl - keystore password you type in the previous steps

Wednesday, January 9, 2013

Errro Log - Unknown Source

Spent three hours to solve the problem.

"How to make the log file to show exact line number the exception thrown instead of Unknown source?"

The exact line number the exception thrown (It is what I want)
Caused by: java.lang.NullPointerException
at com.vaadin.ui.collection.Testing.isValidFormSubmit(Testing.java:315)....

It informs you there is an exception, please guess where the exception is. (Kill me)
Caused by: java.lang.NullPointerException
at com.vaadin.ui.collection.Testing.isValidFormSubmit(Unknown Source)....

It is only add debug="true" in your javac tag of your build.xml file if you are using ant script to compile your project.

Friday, December 28, 2012

Vaadin 6.8.2 - Table Scroll Issue

Vaadin - Table Scroll

Condition:

By Clicking "Find Next" button, the record in the table containing the input name will be highlighted.

It should be called table.setValue(itemId) to set which record should be highlighted and setCurrentPageFirstItemId(itemId) to scroll to the highlighted record as the first row in the table.

However, I found that function setCurrentPageFirstItemId could work properly. It cannot locate the right position for the highlighted record. I tried to find the reasons/causes related to that on the internet. Someone has the same issue but no solution provided.

Problem:
The problem is the modified CSS. I set all the cell content be "pre-wrap" like
.v-table-cell-wrapper{ font-size: 9px; white-space: pre-wrap !important; }

Solution:
The white-space: pre-wrap !important should be removed because Vaadin could not encounter the dynamic row height I guess.

Tuesday, November 27, 2012

iReport 4.7.1 - New Font Installation

If you want to use Traditional Chinese Font (such as 細明體) in the jasper report, you should install a new font in your iReport and create a jar file for your project classpath.

The installation of a new font is going to be demonstrated in the following.
Enjoy and Relax! Hope this will help the beginners. Actually, I am also a newbie. =]


  • Go to C drive >> Window >> Fonts >> Copy the font (i.e. .ttf file under C:\WINDOWS\Fonts) you want to iReport Installed Path (\iReport-4.7.1\ireport\fonts)
  • Open iReport Designer >> Select Tools >> Option
  •  Select "Fonts" tab and click "Install Font" button

  • Click "Browse" button and select the corresponding .ttf file. Click "Next" button
  • Select PDF Encoding 

Note:  If there is an exception thrown (e.g. "Unsupported Encoding Exception: UniCNS-UCS2-H", "Identity-H" (UTF8) should be used for PDF Encoding. It is because Java doesn't know UniCNS-UCS2-H encoding but UTF8 Encodeing.
  • After installation, you can check the irfonts.xml file under (\iReport-4.7.1\ireport\fonts). You can find that the Font Family inserted.

  • Export the newly installed font as jar file and place the jar in both your project classpath and server lib folder.