顯示具有 java 標籤的文章。 顯示所有文章
顯示具有 java 標籤的文章。 顯示所有文章

2011年10月24日 星期一

JDK7 on non-RPM based Linux

JDK 7出來已經有一段時日了,官方網頁也貼心的提供了rpm的套件可以直接安裝,只可惜沒有deb可以下載。雖然如此,我們還是可以省略掉一些手法來同時使用系統提供的jdk6以及網路下載的jdk7--利用update-alternatives工具來達成。但是為了方便作說明,還是先安裝系統套件庫所提供的jdk6吧:

aptitude install sun-java6-jdk

下載適合自己的版本 x86或是x86_64之後,查看自己的java版本以及安裝在何處:

ls -l `which java`
發現原來是連結到/etc/alternatives裡:
lrwxrwxrwx 1 root root 22 2011-10-24 21:39 /usr/bin/java -> /etc/alternatives/java
利用update-alternatives來幫助我們作版本控制,使我們不用手動設定變數等複雜設定,也統一了管理介面。
ls -l /etc/alternatives/java
lrwxrwxrwx 1 root root 36 2011-10-24 21:39 /etc/alternatives/java -> /usr/lib/jvm/java-6-sun/jre/bin/java
所以結果揭曉:/usr/bin/java是來自於/etc/alternatives的一個軟連結,而這個軟連結源自於真正的java位置。所以我們看看他的狀態:
update-alternatives --display java
輸出結果可能會是:
java - auto mode
  link currently points to /usr/lib/jvm/java-6-sun/jre/bin/java
/usr/lib/jvm/java-6-sun/jre/bin/java - priority 63
  slave java.1.gz: /usr/lib/jvm/java-6-sun/jre/man/man1/java.1.gz
Current 'best' version is '/usr/lib/jvm/java-6-sun/jre/bin/java'.

所以我們也可以如法泡製,把下載來的jdk7放在/usr/lib/jvm底下。 請至oracle網站下載最新版本的jdk,假設是jdk-7u25-linux-x64.tar.gz

sudo tar zxvf jdk-7u25-linux-x64.tar.gz -C /usr/lib/jvm/
但此時update-alternatives的cache裡並不會自己發現有jdk的存在,這是安裝一個deb檔的postinst程序才會執行的部份。我們自己試著新增一個,語法如下:
update-alternatives --install <link> <name> <path> <priority>

通常priority大於1000比較有可能是首選。假設您下載了多個jdk7的版本且想要安裝到最新,可以利用下列script來達成:

所以到此為止雖然我們都沒有透過dpkg或是aptitude來安裝jdk7,但是一樣可以作到版本控制,非常方便。

啟動Java plugins:
你可以點我有Java嗎?來測試Java plugin是否有安裝上去。在我的LinuxMint 11 amd64的版本裡,我即使安裝了sun-java6-plugin,無論是我的firefox 或是chrome都無法顯示成功啟動java plugin。
試試看這樣行不行得通:

cd /usr/lib/mozilla/plugins
ln -s /usr/lib/jvm/jdk1.7.0_25/jre/lib/amd64/libnpjp2.so .
如果是rpm-based linux,可以這麼做:
cd /usr/lib/mozilla/plugins
ln -s /usr/java/default/jre/lib/amd64/libnpjp2.so .

參考文章:
man update-alternatives

Share

2010年3月7日 星期日

Java方塊字

許多Java應用程式在輸入中文時會出現方塊字,其實這個時候只要把字型設定給Java即可。以我的Ubuntu為例,我安裝的是sun-java6-jre,此時只要幾個步驟:

cd /usr/lib/jvm/java-6-sun/jre/lib/fonts
mkdir fallback
ln -s /usr/share/fonts/truetype/LiHei_ProPC.ttf .

其中LiHei_ProPC.ttf是我要指定讓Java應用程式使用的字體,因此千萬確定你所使用的字體支援中文,否則就失去意義了。
把你的Java應用程式重新啟動,應該就可以看到正常的中文字體了。

2009年4月9日 星期四

Java Decompiler for Linux

JAD(Java Decompiler)是java類別檔的反組譯器,能夠反組譯.class觀察原始碼的型態。 http://java.decompiler.free.fr/?q=jdgui 最近筆者爬了網路上關於JAD/JODE的文章,都沒辦法順利下載for linux的版本;感謝郭朝益老師熱心提供的連結,讓我們學習java省去不少摸索的時間!

2009年2月2日 星期一

在OpenSuSE上安裝JDK以及netbeans

我真是跟不上時代進步,我竟然不知道JDK已經可以直接從網路安裝了@_@

本文介紹兩種jdk安裝方式,一種是使用網路安裝openjdk,一種是手動安裝jdk。

1.透過網路自動安裝openjdk:
首先,先移除原本的java:

zypper remove java-1_6_0-sun Java-1_6_0-plugin

接著,再安裝openjdk:
zypper in java-1_6_0-openjdk java-1_6_0-openjdk-devel java-1_6_0-openjdk-plugin

其中,java-1_6_0-openjdk是jre,java-1_6_0-openjdk-devel是jdk,java-1_6_0-openjdk-plugin是給瀏覽器的plugin。如果你只要jre的環境,請只安裝java-1_6_0-openjdk就好;如果你需要可以開發的環境,請安裝java-1_6_0-openjdk-devel。

假如你所看到的openjdk的版本是1.5或是看不到openjdk,請加入下列repo:

JAVA.repo
-----------------------
[JAVA]
name=JAVA
enabled=1
autorefresh=1
baseurl=http://download.opensuse.org/repositories/Java:/packages/openSUSE_11.1/
path=/
type=rpm-md
keeppackages=0
-----------------------
此時,請到java的網站驗證是否裝了瀏覽器的plugin: 沒錯,我們的jdk版本實在是太舊了(目前最新的版本為1.6.0 update 11,安裝的版本為最早期的1.6.0)。其實java se 6的差異實在不大,如果你沒有追求最新版的慾望,事實上已經建置好java的開發環境了;但是假設你就是想要用最新版的jdk,請參考第二部份的手動安裝。

2.手動安裝JDK
請到sun官網下載JDK 6 Update 11或是JDK 6 Update 11 with NetBeans 6.5(bundle)。安裝bundle比較簡單,這裡介紹分開安裝的方式。安裝以前建議先把openjdk移除,除非你有需要兩個版本的jvm。

zypper rm java-1_6_0-openjdk java-1_6_0-openjdk-devel java-1_6_0-openjdk-plugin
然後先安裝jdk 6 update 11(不建議安裝rpm的那個):
mv jdk-6u11-linux-i586.bin /opt/sun/
sh /opt/sun/jdk-6u11-linux-i586.bin
此時你還需要手動設定jdk的PATH。你需要新增兩行到.profile下:
JAVAHOME=/opt/sun/jdk1.6.0_11/
JDK=/opt/sun/jdk1.6.0_11/bin
export PATH=$PATH:$JDK
接著安裝netbeans:
mv netbeans-6.5-ml-javase-linux-tw.sh /opt/sun/
sh /opt/sun/netbeans-6.5-ml-javase-linux-tw.sh
結果卻出現:
Configuring the installer...
Searching for JVM on the system...
sed: -e expression #1, char 52: Invalid range end
sed: -e expression #1, char 52: Invalid range end
sed: -e expression #1, char 52: Invalid range end
sed: -e expression #1, char 52: Invalid range end
sed: -e expression #1, char 52: Invalid range end
sed: -e expression #1, char 52: Invalid range end
sed: -e expression #1, char 52: Invalid range end
Java SE Development Kit (JDK) was not found on this computer
JDK 6 or JDK 5 is required for installing the NetBeans IDE. Make sure that the JDK is properly installed and run installer again.
You can specify valid JDK location using --javahome installer argument.

To download the JDK, visit http://java.sun.com/javase/downloads
暫時設定java的PATH給root吧:
JAVAHOME=/opt/sun/jdk1.6.0_11/
export PATH=$PATH:$JAVAHOME
或是使用參數的方式安裝:
sh /opt/sun/netbeans-6.5-ml-javase-linux-tw.sh --javahome /opt/sun/jdk1.6.0_11
就可以成功啟動安裝程式了。為了方便管理,我一樣把netbeans安裝在/opt/sun底下: 便可以成功啟動netbeans。

3.手動安裝支援java的plugin給瀏覽器
如果不是suse系列的linux,安裝的方式請參照sun的官方教學。如果是java的話,使用官方的教學是沒有用的。suse無論使用任何瀏覽器都會去讀取同一個動態函式庫,因此:

ln -s /opt/sun/jdk1.6.0_11/jre/plugin/i386/ns7/libjavaplugin_oji.so /var/lib/rpm/alternatives/libjavaplugin.so
更多資訊請參考: 簡易佈署java程式 Java on Linux 簡易設定

2008年11月22日 星期六

簡易佈署java程式

如果各位有安裝Java Runtime Environment(JRE)的話,一定會發現有一個東西叫做Java Web Start。這是一個很powerful的java程式佈署工具,包含在JRE裡;如果需要java的應用程式,可以直接利用他來呼叫。被Java Web Start呼叫的程式通常被包成 .jar,這是一個壓縮程度類似tar.gz的壓縮格式。本文主要針對製作jar作簡單筆記。

1. 包成類別庫:

假設當前的工作目錄為~/java-workspace/NewJob,其下有一個主類別TestNewjob.java,兩個套件(folder)跟類別分別是:

work1/Job1.java
work2/Job2.java
包覆成jar類別庫時,當然要先編譯出class檔出來;編譯主類別前,需要注意javac能否找到非預設套件下的兩個類別:
javac -sourcepath . -d classes TestNewjob.java
將sourcepath指定到當前目錄,javac會自動找尋當前目錄下的所有資料夾當成搜尋套件的PATH。注意上面的-sourcepath不能簡寫成-sp。編譯成功後會在~/java-workspace/NewJob裡面多出:
classes/TestNewjob.class
classes/work1/Job1.class
classes/work2/Job2.class
這時請切換工作目錄到classes裡面來。包覆java類別庫的指令為jar(詳情請man jar):
cd classes
jar -cvf TestNewjobLib.jar work1/ work2/
熟悉linux tar指令的人一定很愛這種命令,感覺好像本來就會了一樣!
包完之後的java類別庫並沒有可以啟動程式的主類別(所以才叫做類別庫^^),因此要執行必須指定主類別名稱:
java TestNewjobLib.jar TestNewjob
我們會發現執行失敗。雖然我們現在的環境變數已經在這個路徑了,不過還是會要求說找不到main方法的入口,這時我們利用-classpath來指定:
java -classpath TestNewjob.jar:. TestNewjob
便可以成功執行。利用":."來指定多個路徑,也就是在當前目錄下同時存在類別庫跟主類別時的執行方法。

請注意在殘障作業系統(Windows)內,指派多個路徑的方式則是利用分號(;)

java -classpath TestNewjob.jar;. TestNewjob

2. 包覆成可執行程式:
雖然說是可執行程式,但具體而言她還是一個jar的壓縮檔;不同的是主類別也包覆進去,因此無須費力的指定classpath。
之前的環境是相同的,之後作法才開始不同。
在~/java-workspace/NewJob/classes裡,須新增一個檔案,假設為manifest.mf,裡面新增一行:

Main-Class: TestNewjob
(如果是windows平台,則需要再多一行空白行,原因是因為windows跟unix-like系統的換行定義不同。unix-like是\n換行,windows則需\n\r)
上列指令意思是宣告main的主要入口是由這個類別進入的。如果需要接一個classpath,可以這樣定義:
Class-Path: ThirdPartyLibs.jar
接下來必須把這個主類別也包進去:
jar -cvmf manifest.mf TestNewjob.jar TestNewjob.class work1/ work2/
需注意引數的順序。倘若是mf,則表示要先宣告manifest.mf(名稱其實不重要),再宣告jar檔。當然你也可以相反過來,檔案名稱互換一下就可以了。並且包覆的主類別其.class也要補進去。
這樣就包成一個可以執行的jar檔了!如何執行呢?
java -jar TestNewjob.jar
就可以快樂執行了!

3. 實際佈署java應用程式
java可以接受直接使用第三方的類別庫,不過必須要放在特定的位置才能直接使用。存放類別庫的位置依據客戶端是使用private JRE還是public JRE而定。判定的方法很簡單:

java -server
如果有出現
Usage: gij [OPTION] ... CLASS [ARGS] ...
    to invoke CLASS.main, or
    gij -jar [OPTION] ... JARFILE [ARGS] ...
    to execute a jar file
Try `gij --help' for more information.
以上的訊息,表示你的java是使用private JRE;假設顯示的是錯誤訊息,表示客戶端使用的是public JRE,也就是只有安裝JRE而非JDK。
假設我們所使用的是private JRE,表示此JRE是由JDK所帶來的,因此應該放在$JDK/jre/lib/ext裡。
如果使用的是public JRE,表示使用的是JRE,因此應該放在$JRE/lib/ext裡。

不過第三方的類別庫可別放太多,否則編譯時間會大大的增加!

2008年11月2日 星期日

JUDE on linux

JUDE是一套強大且based on jdk的java UML editor。所謂的UML就是Unified Modeling Language的簡稱,也就是統一塑模語言。不過我也不是如此的了解UML的全部意涵,我想這篇文章是解釋UML的一篇不錯的文章。

為了設計java UML,老師介紹大家用這套JUDE community。JUDE還有professional版本,需要付費但是功能強大,連Mind Map也包進裡面了。不過我想我們只需要單純的功能,所以免費的community版本就足夠我們練習的了。

不過,JUDE的官方網站似乎沒有for linux的JUDE提供下載。但是用google查到JUDE在linux上的使用可是沸沸揚揚的,怎麼會這樣呢?仔細看了一下,有兩派人馬,一派是很幸運的可以用wine來安裝、啟動JUDE;另一派則完全沒有提到wine,似乎是可以直接拿來使用。

後來我才知道JUDE在linux/MacOS/Solaris上都是不用安裝的。首先,必須先註冊一個JUDE帳號,接著下載community的版本。請下載.zip的那個檔案,這才是給linux用的。例如檔名是類似jude-community-5_4.zip的壓縮檔。解開後裡面有一個jude的檔案,他是一個script,內容大致如下:

#!/bin/sh

#Remove "#" from following two lines, if you'd like to use j2sdk.
#JAVA_HOME=/usr/lib/j2sdk1.4/;export JAVA_HOME
#PATH=$JAVA_HOME/bin:$PATH; export PATH

JUDE_HOME=/opt/jude_community
#JUDE_HOME=`dirname $0`
JUDE_JAR=jude-community.jar

CLASSPATH=$JUDE_HOME/$JUDE_JAR

JAVA_OPTS="-Xms16m -Xmx512m -Xss2m"

java $JAVA_OPTS -jar $JUDE_HOME/$JUDE_JAR $1 $2 $3
我在此只需要修改!JUDE_HOME即可。原因是因為JAVA_HOME根本無須設定,因為我的PATH裡已經有了。需注意JUDE需要JDK才跑得起來!!假設我把jude_community放在/opt下面,環境變數也設定成功了,則:
ln -s /opt/jude_community/jude /usr/bin/jude
就算是大功告成了! 不過話說回來,那些用wine來跑JUDE的人,會不會太大費周章了點^^

關鍵字:jude, linux

2008年10月30日 星期四

Java on Linux 簡易設定

01. 安裝環境
J2SE Development Kit 5.0 Update 16 with NetBeans IDE 6.1 Bundle
我所選擇的環境是Java SE 5.0 與Netbeans IDE 6.1的整合套件。JDK是一個開發的元件,內含java語言的編譯器、JVM,以及JRE(內有標準的類別函式庫)。也就是說一般的使用者只是想運行java程式,只要有JRE就好;如果想要開發java程式,則必須安裝JDK;如果想要一個圖形整合介面,那麼可以考慮昇陽官方的Netbeans。不過必須有一個觀念,Netbeans只是一個空殼,如果沒有JDK,Netbeans也只是一個圖形介面,什麼碗糕也跑不出來。因此如果不安裝bundle組合套件,那麼可以自己下載最新的JDK以及Netbeans IDE。

另一個應該注意的是,雖然安裝的JDK包含了JRE,不過當你在使用瀏覽器遇到使用java程式的時候,還是會出現警告找不到JRE的視窗。這是因為JDK會使用自帶的JRE,而這個JRE並不會給編譯java以外的事情使用,這是為了編譯時候的過程是順利、且可以確保版本號,因此JRE需要額外安裝。不過這樣所帶來的好處是,開發人員可以安裝多個JRE來測試不同環境所編譯出來的程式是否有任何異常問題,而系統預設以最高版本的JRE來運行。

02. 環境變數設定
首先,系統的shell並沒有辦法知道JDK在哪裡,你必須告知系統JRE的PATH,例如我放在/usr/local/jdk1.6.0_07/bin, 則應該在定義PATH的設定檔內修改成:

JAVA_HOME=/usr/local/jdk1.6.0_07
export PATH=$PATH:$JAVA_HOME/bin
除此之外,路徑對於JVM來說只是一個package。例如在unix上一個再普通不過的binary,你可以透過路徑的方式告知該做什麼動作:
gcc ../abc/test.c -o bin/test
不過java可不能這麼用。在當前目錄下假設有一個abc.java檔案(假設public類別名稱也為abc),詳細訊息可以這樣印出來:
javac -verbose abc.java
這個動作會產生abc.class的byte code:
java abc
來執行這隻程式。執行程式時,java會認為JVM才是真正的作業系統,以下是簡單的執行流程:
--class loader:指派記憶體位置。
--byte code verifier:進行雜湊校驗,比對是否真的由javac所原生。
--hotspot excution:就是JVM啦,有可能是client,也有可能是server。
--talk to hardware:由JVM產生native code與硬體溝通。

03. classpath與sourcepath的設定:
通常java會把編譯後的bytecode跟原始碼放在一起(而不是當前目錄)。不過,在執行一個大的project時,會撰寫成許多不同的類別,這時候為了除錯方便以及also compile方便,我們需要把source code與byte code分開。假設source codes放在src,而byte code放在classes,則我們在有abc.java的工作目錄時,編譯java需要這樣作:

javac -d classes -classpath PATH_OF_CLASS abc.java
-d:         告知java compiler編譯完成把byte code放在./classes裡。
-classpath  告知有哪些既有的class可用的路徑。效果等於-cp,但是-cp無法用於環境變數。
如果classes裡缺少某類別的byte code可以使用,則需要回頭編出一個class來使用。預設會在當前目錄找,但是如果找不到,則無法also compile--造成編譯失敗。解決的方法是指定sourcepath給java:
javac -d classes -sourcepath PATH_OF_SOURCE abc.java
-sourcepath 告知哪裡有.java原始檔。
假設在src下有多個套件,仍然只需要指定src即可,javac會自動往下找其他套件。
這樣java就知道去哪裡找cource code去編譯該類別出來。但是不建議sourcepath與classpath混用,因為混用的結果只有sourcepath有效(除非還有用到其他類別)。
javac -d classes -sourcepath PATH_OF_SOURCE -classpath PATH_OF_CLASS abc.java
理由是,當java compiler編譯時缺少某一類別,他會在sourcepath裡尋找是否有對應的.java。如果有,他也不會去找classpath,會直接再編譯一個byte code出來;因此在指定sourcepath以及classpath時,通常是不會同時使用的。javac會先抓取sourcepath引數,再抓取classpath引數。無論你是否先指定classpath,抓引數的順序仍然是先sourcepath再classpath。簡而言之:

利用-sourcepath達成also compile;
利用-classpath告知既存的類別檔位置。

當然,使用unix都是懶惰的人,總是希望事情可以簡化又依照我們的要求,我們可以把他寫進環境變數裡:
export CLASSPATH=~/java-workspace/classes
同樣的,如果要設定sourcepath,也寫成:
export SOURCEPATH=~/java-workspace/src
不過我實在很懶。如果每次編譯都要打這串javac -d classes,我實在覺得很煩。不過 -d存放class檔無法使用環境變數固定住,因此我目前想出來的方法是用alias。
alias javac='javac -d ~/java-workspace/classes'
問題就解決啦!如果是呆呆windows可能就沒這麼方便了。 為什麼要這麼麻煩去特別指定sourcepath以及classpath呢?假設今天有一個大專案,需要很多次修改某幾個類別,你一定不希望每個.java都被編譯一次,這時候可以「只」指定classpath,不指定sourcepath(在當前目錄),則系統就會去找既有的class來使用,降低了大量重複also compile的無謂cpu時間消耗。

04. 執行java
到此為止,編譯方面的環境設定就結束了;那麼執行呢?
傳統的程式編譯出來的binary,只要設定好PATH,則我們可以這樣作:

Testjava ../abcdef.txt
但是我已經設定好classpath了,因此我可以在任何一個地方下指令:
java Testjava
都可以順利執行。如果想要把Testjava變成外部命令,可以寫在alias:
alias Testjava='java Testjava'

關鍵字:java, java se, netbeans, classpath, sourcepath