看了网上很多哥们对 OpenFire 的开发环境架设都有描述,我在架设的时候遇到了很多细节的问题,经过很步后实现了Eclipse下可编译可调试可修改的效果,特意记录下来给大家分享,希望对以后再走此路的人有帮助,跟着一步一步走一定可以走出迷雾。
说明:开发环境(IDE):Win7(64位) + Eclipse4.2 +JDK1.7+Openfire_src_3_7_1.zip
Openfire下载地址:http://www.igniterealtime.org/downloads/index.jsp#openfire
Eclipse 4.2 http://www.eclipse.org/downloads/packages/eclipse-classic-421/junosr1
JDK 1.6_32 自己找吧
1. 解压那openfire_src_3_7_1.zip 得到一个 openfire_src 目录,这就是项目的根目录
2. 在Eclipse 中新建一个openfire_src 的项目 , 下一步,然后按 Finish!
3. 当创建完 OpenFire项目后会发现有可恶的红交叉,原因是因为插件的包是没有的,解决的方法有两个,一个是下载插件然后加上,一个是直接把红交叉的文件直接删除,删除几个就ok了,不影响使用的,下面再讲讲如何补全其缺少的插件
所缺少的插件 包括了 几个 Oracle的包,其作用是实现群集的,我们先去下载
openfire的集群需要依赖Oracle的coherence.jar、coherence-work.jar、tangosol.jar包,你可以在网上找找这几个包
http://www.oracle.com/technetwork/cn/testcontent/coherence-085668-zhs.html
由于下载回来的 coherence是 3.71的缘故 ,所以在Openfire 的兼容性上出现了问题,我们需要修改 OpenFire的源代码去实现
修改如下(参考http://community.igniterealtime.org/message/209042):
# This patch file was generated by NetBeans IDE
# Following Index: paths are relative to: openfire_3_7_0/src/plugins/clustering/src
# This patch can be applied using context Tools: Patch action on respective folder.
# It uses platform neutral UTF-8 encoding and \n newlines.
# Above lines and this line are ignored by the patching process.
Index: java/com/jivesoftware/util/cache/ClusteredCache.java
--- java/com/jivesoftware/util/cache/ClusteredCache.java Base (BASE)
+++ java/com/jivesoftware/util/cache/ClusteredCache.java Locally Modified (Based On LOCAL)
@@ -190,7 +190,7 @@
public long getCacheHits() {
if (map instanceof NearCache) {
- return ((NearCache)map).getCacheHits();
+ return ((NearCache)map).getCacheStatistics().getCacheHits();
}
else if (backingCache != null) {
return backingCache.getCacheHits();
@@ -202,7 +202,7 @@
public long getCacheMisses() {
if (map instanceof NearCache) {
- return ((NearCache)map).getCacheMisses();
+ return ((NearCache)map).getCacheStatistics().getCacheMisses();
}
else if (backingCache != null) {
return backingCache.getCacheMisses();
Index: java/com/jivesoftware/util/cache/CoherenceClusteredCacheFactory.java
--- java/com/jivesoftware/util/cache/CoherenceClusteredCacheFactory.java Base (BASE)
+++ java/com/jivesoftware/util/cache/CoherenceClusteredCacheFactory.java Locally Modified (Based On LOCAL)
@@ -93,7 +93,7 @@
}
else {
com.tangosol.net.CacheFactory.getCache("opt-$cacheStats");
- taskService = com.tangosol.net.CacheFactory.getInvocationService("OpenFire Cluster Service");
+ taskService = (InvocationService) com.tangosol.net.CacheFactory.getService("OpenFire Cluster Service");
// Update the running state of the cluster
state = cluster != null ? State.started : State.stopped;
Index: java/com/jivesoftware/util/cache/CoherenceExternalizableUtil.java
--- java/com/jivesoftware/util/cache/CoherenceExternalizableUtil.java Base (BASE)
+++ java/com/jivesoftware/util/cache/CoherenceExternalizableUtil.java Locally Modified (Based On LOCAL)
@@ -286,7 +286,7 @@
}
public Serializable readSerializable(DataInput in) throws IOException {
- return ExternalizableHelper.readSerializable(in);
+ return (Serializable) ExternalizableHelper.readSerializable(in);
}
public void writeSafeUTF(DataOutput out, String value) throws IOException {
Index: java/com/jivesoftware/util/cluster/CoherenceInfo.java
--- java/com/jivesoftware/util/cluster/CoherenceInfo.java Base (BASE)
+++ java/com/jivesoftware/util/cluster/CoherenceInfo.java Locally Modified (Based On LOCAL)
@@ -64,7 +64,7 @@
*/
public static Map getNodeInfo() {
- InvocationService service = com.tangosol.net.CacheFactory.getInvocationService("OpenFire Cluster Service");
+ InvocationService service = (InvocationService) com.tangosol.net.CacheFactory.getService("OpenFire Cluster Service");
// Run cluster-wide stats query
Map results = service.query(new AbstractInvocable() {
@@ -107,7 +107,7 @@
*/
public static void clearCacheStats() {
- InvocationService service = com.tangosol.net.CacheFactory.getInvocationService("OpenFire Cluster Service");
+ InvocationService service = (InvocationService) com.tangosol.net.CacheFactory.getService("OpenFire Cluster Service");
service.execute(new AbstractInvocable() {
public void run() {
Index: web/system-clustering-node.jsp
--- web/system-clustering-node.jsp Base (BASE)
+++ web/system-clustering-node.jsp Locally Modified (Based On LOCAL)
@@ -123,7 +123,7 @@
}
// Get the cache stats object:
- Map cacheStats = com.tangosol.net.CacheFactory.getReplicatedCache(
+ Map cacheStats = com.tangosol.net.CacheFactory.getCache(
"opt-$cacheStats", com.tangosol.net.CacheFactory.class.getClassLoader());
// Decimal formatter for nubmers
@@ -354,8 +354,8 @@
double memUsed = (double) size / (1024 * 1024);
double totalMem = (double) maxSize / (1024 * 1024);
- double freeMem = 100 - 100 * memUsed / totalMem;
- double usedMem = 100 * memUsed / totalMem;
\ No newline at end of file
+ double freeMem = 100 - 100 * memUsed / Math.max(1, totalMem);
+ double usedMem = 100 * memUsed / Math.max(1, totalMem);
\ No newline at end of file
long hits = theStats[3];
long misses = theStats[4];
double hitPercent = 0.0;
到现在 Sip部分了
由于 下载回来的源代码中有 getNextHop 函数尚未重载 故在此文件的后面加入如下代码:
CommRouter.java (加入):
@override
public Hop getNextHop(Request arg0) throws SipException {
// TODO Auto-generated method stub
return null;
}
SipManager.java (加入)
@Override
public void processDialogTerminated(DialogTerminatedEvent arg0) {
// TODO Auto-generated method stub
}
@Override
public void processIOException(IOExceptionEvent arg0) {
// TODO Auto-generated method stub
}
@Override
public void processTransactionTerminated(TransactionTerminatedEvent arg0) {
// TODO Auto-generated method stub
}
到现在为止搞掂了所以红交叉了 ,接下来是ant的编译
1. 右击openfire_src项目=> Properties
2. 把 /openfire_src/build 目录勾上
3. 修改build.xml文件, 加入支持jdk 1.7 的ant 代码,记得保存哦!
4. 右击那build.xml文件, Run As => Ant Build…(记住选择有三个点的)
5. 按下 Run 按钮 如无意外你已经可以编译了
6. 下一步,复制src/i18n/openfire_i18n_en.properties和src/resources/jar/admin-sidebar.xml两个文件,到项目下的bin目录。
7. 编译后才可以调试程序,
(1)在eclipse的菜单栏中,选择Run->Open Run Dialog...,在弹出的对话框左侧的树形结构中选择Java Application,单击右键,选择New创建启动配置。
(2) 在Run窗口的Main选项卡中, 修改Name文本框中的值,改成包含要启动的类的工程名openfire
(3)在Run窗口的Main选项卡中,点Browse按钮,选择openfire
(4)在Run窗口的Main选项卡中,点Search按钮,选择Main class为
org.jivesoftware.openfire.starter.ServerStarter,单击Apply按钮。(这是openfire的启动类)
(5)点击进入Arguments选项卡,在VM arguments文本框中输入
-DopenfireHome="${workspace_loc:openfire_src}/target/openfire" (注意openfire_src,如果你的项目名叫AA 那么这里改为“AA”)
单击Apply按钮。这个是用于eclipse执行java命令时传递的参数,这样openfire程序可以通过System.getProperty(“openfireHome”)得到openfire的本地位置。
(6)点击进入Classpath选项卡,选中User Entries,这样Advanced...就处于可用状态;点击Advanced...按钮,在Advanced Options页面,选择Add Folders, 单击OK。(默认情况下,已经将工程openfire添加到了这里,而不需要进行该项操作,如果有多个工程的时候才需要执行该项操作。)
选择openfire\src\i18n, 点OK按钮将这个文件夹加入到Classpath选项卡中;同样的方式把openfire\src\resources目录下的jar文件夹也加到Classpath选项卡中。
(11)在Common选项卡中,勾选Run复选框,单击Apply按钮。
设置完毕,这样以后在run这个工程的时候就会按照正确的配置进行了,debug的设置和run的设置类似,不再多说。
注意:提示错误如下:
HTTP ERROR: 500
INTERNAL_SERVER_ERROR
RequestURI=/setup/index.jsp
Caused by:
java.lang.NullPointerException
atorg.jivesoftware.admin.AdminConsole.getAppName(AdminConsole.java:122)
atorg.jivesoftware.openfire.admin.decorators.setup_jsp._jspService(setup_jsp.java:168)
atorg.apache.jasper.runtime.HttpJspBase.service(HttpJspBase.java:97)
atjavax.servlet.http.HttpServlet.service(HttpServlet.java:820)
atorg.mortbay.jetty.servlet.ServletHolder.handle(ServletHolder.java:487)
atorg.mortbay.jetty.servlet.ServletHandler.handle(ServletHandler.java:362)
atorg.mortbay.jetty.security.SecurityHandler.handle(SecurityHandler.java:216)
atorg.mortbay.jetty.servlet.SessionHandler.handle(SessionHandler.java:181)
atorg.mortbay.jetty.handler.ContextHandler.handle(ContextHandler.java:726)
atorg.mortbay.jetty.webapp.WebAppContext.handle(WebAppContext.java:405)
atorg.mortbay.jetty.servlet.Dispatcher.include(Dispatcher.java:192)
atcom.opensymphony.module.sitemesh.filter.PageFilter.applyDecorator(PageFilter.java:156)
atcom.opensymphony.module.sitemesh.filter.PageFilter.doFilter(PageFilter.java:59)
atorg.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1084)
atorg.jivesoftware.util.LocaleFilter.doFilter(LocaleFilter.java:66)
atorg.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1084)
atorg.jivesoftware.util.SetCharacterEncodingFilter.doFilter(SetCharacterEncodingFilter.java:42)
at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1084)
atorg.jivesoftware.admin.PluginFilter.doFilter(PluginFilter.java:70)
atorg.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1084)
atorg.jivesoftware.admin.AuthCheckFilter.doFilter(AuthCheckFilter.java:99)
atorg.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1084)
atorg.mortbay.jetty.servlet.ServletHandler.handle(ServletHandler.java:360)
atorg.mortbay.jetty.security.SecurityHandler.handle(SecurityHandler.java:216)
atorg.mortbay.jetty.servlet.SessionHandler.handle(SessionHandler.java:181)
atorg.mortbay.jetty.handler.ContextHandler.handle(ContextHandler.java:726)
atorg.mortbay.jetty.webapp.WebAppContext.handle(WebAppContext.java:405)
atorg.mortbay.jetty.handler.ContextHandlerCollection.handle(ContextHandlerCollection.java:206)
atorg.mortbay.jetty.handler.HandlerCollection.handle(HandlerCollection.java:114)
atorg.mortbay.jetty.handler.HandlerWrapper.handle(HandlerWrapper.java:152)
atorg.mortbay.jetty.Server.handle(Server.java:324)
atorg.mortbay.jetty.HttpConnection.handleRequest(HttpConnection.java:505)
atorg.mortbay.jetty.HttpConnection$RequestHandler.headerComplete(HttpConnection.java:829)
atorg.mortbay.jetty.HttpParser.parseNext(HttpParser.java:514)
atorg.mortbay.jetty.HttpParser.parseAvailable(HttpParser.java:211)
at org.mortbay.jetty.HttpConnection.handle(HttpConnection.java:380)
atorg.mortbay.io.nio.SelectChannelEndPoint.run(SelectChannelEndPoint.java:395)
atorg.mortbay.thread.QueuedThreadPool$PoolThread.run(QueuedThreadPool.java:488)
Powered by Jetty://
这时因为是文件路径所导致的问题,需要将admin-sidebar.xml和openfire_i18n_en.properties这2个文件直接放在openfire\bin目录下即可解决这个问题。
如果再次出现,这样的问题,就需要将openfire目录下的你把openfire下的work 和target文件都删除了,然后重新发布一个。因为web的内容不会自动更新的,只有.class会自动更新。
8. 最后给出我的参考网站
中文资料:http://hi.baidu.com/gridrender/item/1309354fbaa43f0ee83504ee
http://blog.csdn.net/nomousewch/article/details/6534555
http://blog.csdn.net/shm10/article/details/6712664
最有权威的为:http://community.igniterealtime.org/docs/DOC-1020
初学者编译出现问题:http://community.igniterealtime.org/thread/42059