<?xml version="1.0" encoding="UTF-8" ?>
<rss version="2.0">
<channel>
<title><![CDATA[Ratstar的小木屋]]></title> 
<link>http://www.ratstar.cn/blog/index.php</link> 
<description><![CDATA[小S和小M的窝 - 眼睛为他（她）下着雨，心却为他（她）撑着伞...]]></description> 
<language>zh-cn</language> 
<copyright><![CDATA[Ratstar的小木屋]]></copyright>
<item>
<link>http://www.ratstar.cn/blog/read.php?83</link>
<title><![CDATA[在Solaris系统上实现用Java JNI实现对Tuxedo服务的调用]]></title> 
<author>ratstar &lt;ratstar.cn@gmail.com&gt;</author>
<category><![CDATA[成长足迹]]></category>
<pubDate>Tue, 15 Dec 2009 05:39:26 +0000</pubDate> 
<guid>http://www.ratstar.cn/blog/read.php?83</guid> 
<description>
<![CDATA[ 
	　　在Solaris上实现了JNI之后，我就开始将目光放在更深的地方。我决定在Solaris系统上实现用JNI调用Tuxedo服务。<br/>　　一般Java调用Tuxedo服务常用的方法有两种，一种是通过Jolt调用，一种是通过Weblogic的WTC调用。但是由于要模拟C++/C的调用，我不想用这两种方法。而是要用JNI的方式去调用Tuxedo服务。<br/>　　由于这种“不走寻常路”这个过程中遇到了一些问题。<br/>　　我在网上搜索了一下，没有找到太多有价值的东西，经过自己的研究，将我的一些经验记录下来。<br/>　　在实现了JNI服务之后，我按JNI的方式进行Coding。这个过程没有什么特别的。我先是写了一个代理类，这个类有一个native方法，这个方法就是要用C/C++编写的程序。之后用javah生成.h文件，写一个c程序。<br/>　　这个过程之后，问题出现了。在一般的Tuxedo客户端，是用buildclient进行编译的。但是现在由于要生成的是共享库文件，而不是可执行文件，所以就没有办法用buildclient命令。经过查找资料，我发现buildclient并没有编译能力它只是调用了系统原有的编译器进行编译，只不过加入了一些参数。这样，我就想了一个办法。我故意在执行buildclient的时候，写错源文件。这样，buildclient就会报出什么什么指令不能执行。比如：我执行如下指令<br/><div class="code">buildclient -o tpcallagent -f tpcall.c</div><br/>　　其中tpcall.c是一个不存在的数据。这样它会给出如下的错误：<br/><div class="code">command line: fatal: cannot open&nbsp;&nbsp;tpcall.c: No such file or directory<br/>cc: acomp failed for tpcall.c<br/>CMDTUX_CAT:512: ERROR: Cannot execute C compiler cc&nbsp;&nbsp;-mt&nbsp;&nbsp;-I$TUXDIR/include -o tpcallagent&nbsp;&nbsp; -L$&#123;TUXDIR&#125;/lib tpcall.c&nbsp;&nbsp;-ltux -lbuft&nbsp;&nbsp;-lfml -lfml32 -lengine&nbsp;&nbsp;-R/usr/lib/lwp -lpthread -lposix4 -lsocket -lnsl -lm&nbsp;&nbsp;-lnsl -lsocket</div><br/>　　这样，就看到了实现执行的指令了，也就是<br/><div class="code">cc&nbsp;&nbsp;-mt&nbsp;&nbsp;-I$TUXDIR/include -o tpcallagent&nbsp;&nbsp; -L$&#123;TUXDIR&#125;/lib tpcall.c&nbsp;&nbsp;-ltux -lbuft&nbsp;&nbsp;-lfml -lfml32 -lengine&nbsp;&nbsp;-R/usr/lib/lwp -lpthread -lposix4 -lsocket -lnsl -lm&nbsp;&nbsp;-lnsl -lsocket</div><br/>　　这样，将这个编译指令进行修改，就得到了所要的执行了。要执行的指令如下：<br/><div class="code">cc -G -mt -I/usr/java/include -I/usr/java/include/solaris -I$TUXDIR/include -o libtpcallagent.so&nbsp;&nbsp; -L$&#123;TUXDIR&#125;/lib tpcallagent.c&nbsp;&nbsp;-ltux -lbuft&nbsp;&nbsp;-lfml -lfml32 -lengine&nbsp;&nbsp;-R/usr/lib/lwp -lpthread -lposix4 -lsocket -lnsl -lm&nbsp;&nbsp;-lnsl -lsocket</div><br/>　　其中修改了参数-o，使其指向要生成文件，以及修改了原代码文件。增加了-G参数用来编译成库文件，增加了JNI要用的include文件。这样，我们就可以用编译tuxedo客户端功能的jni库文件了。<br/>　　之后的工作就很轻松。编译，写一个调用代理类的新类。执行，OK。
]]>
</description>
</item><item>
<link>http://www.ratstar.cn/blog/read.php?82</link>
<title><![CDATA[第一次在Solaris上成功使用JNI]]></title> 
<author>ratstar &lt;ratstar.cn@gmail.com&gt;</author>
<category><![CDATA[成长足迹]]></category>
<pubDate>Fri, 11 Dec 2009 09:30:57 +0000</pubDate> 
<guid>http://www.ratstar.cn/blog/read.php?82</guid> 
<description>
<![CDATA[ 
	　　平时在使用Java的时候，有时候会用到JNI。但是使用JNI往往都只是在Windows上进行，很少有在其它系统上进行的。公司开发环境是Solaris，而且有Java环境。于是我就想在Solaris系统上使用JNI。<br/>　　查了很多资料，发现Windows上的JNI和Unix系统上的JNI很多都一样。无非是写Java程序，编译Java，再用Javah得到一个.h文件，之后可以根据得到的.h文件编写c或c++程序了。这些步骤之后，不同系统的差别就体现出来了。虽然编译动态库的工作原理是一样的，但是每一个系统实实在在有着不小的差别。<br/>　　在Windows上只要用vc编译出一个dll文件就可以了，之后就是将这个dll文件放在java执行目录下就可以调用。但是Unix系统的规则和Windows不同，它不会搜索当前目录。它会在</span>LD_LIBRARY_PATH中设置的路径中找，而一般的系统中不会让LD_LIBRARY_PATH有当前的目录。这样就要修改配置文件，由于这个环境是很多人用的，不想改变配置，这样就需要每一次运行时用export设置一次LD_LIBRARY_PATH。这样很麻烦。于是我没有用常用的System.loadLibrary方法，而是用System.load方法，这个方法只要给出库文件的绝对路径就可以加载。<br/>　　我遇到的另外一个问题是文件名的问题。在Solaris下，库文件之前要加"lib"比如"System.loadLibrary("Sample");"，对应的库文件名就是libSample.so。这个问题也是困扰了半天的问题。<br/>　　别外贴一个我编译so用到的指令以供后面学习参考。<br/><div class="code">gcc -fpic -c -I/usr/java/include -I/usr/java/include/solaris Sample1.c<br/>gcc -G -o libSample1.so Sample1.o</div><br/>
]]>
</description>
</item>
</channel>
</rss>