openfire源码分析之启动
? ? 由于是看完mina源码来看openfire的,上来就找到了nio那个文件夹看,但是不知道在哪用到了那些handler,所以就各种寻找handler的使用地方,最后发现openfire是插件驱动的,所有功能都由插件来完成,无论是扩展还是系统内部提供的功能。
? ? 一点点来,今天首先看openfire的启动,openfire的启动是通过自己家在class来完成的,代码是分布在\Source\openfire_src\src\java\org\jivesoftware\openfire\starter文件夹里的ServerStarter.java,再家在openfire服务器的主Server类之前,会对lib文件夹和插件中admin中的lib文件夹进行解包,解包知识参考java.util.jar.Pack200,解包代码中发现了作者的一个小失误,注释的失误,嘿嘿,代码如下:
?
/** * Converts any pack files in a directory into standard JAR files. Each * pack file will be deleted after being converted to a JAR. If no * pack files are found, this method does nothing. * * @param libDir the directory containing pack files. * @param printStatus true if status ellipses should be printed when unpacking. */ private void unpackArchives(File libDir, boolean printStatus) { // Get a list of all packed files in the lib directory. File [] packedFiles = libDir.listFiles(new FilenameFilter() { public boolean accept(File dir, String name) { return name.endsWith(".pack"); } }); if (packedFiles == null) { // 这的注释是错误的,我查看了listFiles的文档,只有libDir不是目录 //或者IO错误才会返回null,不存在.pack文件应该返回的是个空数组 // Do nothing since no .pack files were found return; } // Unpack each. boolean unpacked = false; for (File packedFile : packedFiles) { try { String jarName = packedFile.getName().substring(0, packedFile.getName().length() - ".pack".length()); // Delete JAR file with same name if it exists (could be due to upgrade // from old Openfire release). File jarFile = new File(libDir, jarName); if (jarFile.exists()) { jarFile.delete(); } InputStream in = new BufferedInputStream(new FileInputStream(packedFile)); JarOutputStream out = new JarOutputStream(new BufferedOutputStream( new FileOutputStream(new File(libDir, jarName)))); Pack200.Unpacker unpacker = Pack200.newUnpacker(); // Print something so the user knows something is happening. if (printStatus) { System.out.print("."); } // Call the unpacker unpacker.unpack(in, out); in.close(); out.close(); packedFile.delete(); unpacked = true; } catch (Exception e) { e.printStackTrace(); } } // Print newline if unpacking happened. if (unpacked && printStatus) { System.out.println(); } }?
解包完事,就加载openfire的主服务器,代码如下:
?
ClassLoader loader = new JiveClassLoader(parent, libDir);Thread.currentThread().setContextClassLoader(loader);Class containerClass = loader.loadClass( "org.jivesoftware.openfire.XMPPServer");containerClass.newInstance();
?其中JiveClassLoader跟ServerStarter在同一个目录,继承自UrlClassLoader,能够加载本地和网络Jar文件,
其中XMPPServer就是openfire的主Server,实际主要就是加载了一些插件,openfire的插件机制还没细看,看完再写,今天写的不算流水账吧,锻炼锻炼自己的写作能力。哎,我的语文好差哦!