【本文已迁移到“程序员文摘” http://programmerdigest.cn/category/lajp】
Linux下的socket模式hello world
安装之前:
系统要求: Linux,安装好Apache、PHP环境
Java JDK:1.5以上。
gcc编译环境。
安装配置:
下载lajp_9.09.tar.gz ,解压:
lajp_9.09 //消息队列版
|
|--java
| |
| |--hello //Hello World示例程序
| | |
| | |--HelloClass.class
| | +--HelloClass.java
| |
| |--lajp_9.09.jar //Java服务端主程序
| +--run.sh //运行脚本
|
|--jni //JNI源代码
| |
| |--lajp_MsgQ.c
| |--lajp_MsgQ.h
| +--make.sh
|
+--php
|
+--php_java.php //PHP脚本
需要编译JNI:
1. 进入java/jni目录
2. chmod +x make.sh //设置make.sh有执行权限
3. vi make.sh //编辑make.sh,按注释修改脚本:
001 #!/bin/sh
002
003 # -----------------------------------------------------------
004 # LAJP-JNI 编译脚本 (2009-09 http://code.google.com/p/lajp/)
005 #
006 # 编译环境: Unix/Linux
007 #
008 # 源文件: lajp_MsgQ.c lajp_MsgQ.h
009 # 目标文件: liblajpmsgq.so
010 # 编译参数:
011 # --share : 编译为动态库
012 # -I : 搜索编译JNI需要的.h文件, 注意"/usr/lib/jvm/java-6-sun/"
013 # : 要换成编译环境中的JAVA_HOME路径
014 #
015 # liblajpmsgq.so发布 : 复制到<java.library.path>中,可通过java程序:
016 # : System.out.println(System.getProperties().getProperty("java.library.path"));
017 # : 获得本机的<java.library.path>
018 # -----------------------------------------------------------
019
020 gcc lajp_MsgQ.c --share -I. -I/usr/lib/jvm/java-6-sun/include -I/usr/lib/jvm/java-6-sun/include/linux -o liblajpmsgq.so
修改020行的两处"/usr/lib/jvm/java-6-sun/",替换为本机的JAVA_HOME路径。
4. ./make.sh //编译
5. 将编译出的动态库文件liblajpmsgq.so复制到/usr/lib目录。
JNI动态库.so需要复制到java.library.path路径中,此路径可通过Java程序System.out.println(System.getProperties().getProperty("java.library.path"))得到。
编译JNI的详细步骤请看LAJP帮助文档
编写PHP文件:
001 <?php header("Content-Type:text/html;charset=utf-8"); ?>
002
003 <?PHP
004 require_once("php_java.php"); //引用下载的php_java.php文件
005
006 $name = "Ali";
007
008 try
009 {
010 //调用Java的hello.HelloClass类中的hello方法
011 $ret = lajp_call("hello.HelloClass::hello", $name);
012 echo "{$ret}<br>";
013 }
014 catch (Exception $e)
015 {
016 echo "Err:{$ret}<br>";
017 }
018 ?>
运行:
1. 运行脚本程序run.sh,显示:
-------------------------------------------
- Start LAJP-JAVA...
- time:Tue Sep 29 20:27:32 CST 2009
-------------------------------------------
init [IPC] Message Queue OK...
init [IPC] Shared Memory OK...
init [IPC] Semaphore OK...
set charser: UTF-8
Start LAJP-JAVA OK...
以上信息表示Java服务已经运行。
2. 打开浏览器,访问刚创建的php程序地址,页面显示:"Hello World! Ali"。
OK,Hello World程序演示结束。
解释:
在下载的zip文件的Java程序中,带有一个LAJP服务,服务类是HelloClass.class,我们看它的源代码HelloClass.java:
001 package hello;
002
003 public class HelloClass
004 {
005 public static final String hello(String userName)
006 {
007 return "Hello World! " + userName;
008 }
009 }
当php程序执行到 $ret = lajp_call("hello.HelloClass::hello", $name)语句时,发生如下事情:
1. lajp_call函数参数"hello.HelloClass::hello"告诉LAJP,我要访问hello.HelloClass类中的hello方法,并且传给它一个参数$name。
2. 在lajp_call函数内部将请求包装为消息包,写入系统消息队列
3. Java端的LAJP程序从消息队列中读取消息报,解析调用含义,找到HelloClass类和hello方法,执行方法调用,再将方法返回值包装为消息包,写入系统消息队列
4. PHP端lajp_call函数从消息队列中读取并解析返回消息包,得到其中的字符串"Hello World! Ali"