aspose file tools*
The moose likes Java in General and the fly likes how to hot deploy jar files Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login


Win a copy of Soft Skills this week in the Jobs Discussion forum!
JavaRanch » Java Forums » Java » Java in General
Bookmark "how to hot deploy jar files" Watch "how to hot deploy jar files" New topic
Author

how to hot deploy jar files

chris liao
Greenhorn

Joined: Jul 24, 2005
Posts: 27
I am in trouble, and very painful! My boss want me to design hot deploy
for his application,which is a small java server and need hot-deploy jars
But,util now, i don't know about hot-deploy!

Hand-masters,please help me, What should i do ? write some classLoader or other? I hope you give me some very userful source code.
Thanks!
chris liao
Greenhorn

Joined: Jul 24, 2005
Posts: 27
for this, I wrote a classLoader, below is source code:

package org.jmin.bridge.loader;

import java.io.*;
import java.net.*;
import java.util.*;
import org.jmin.bridge.deploy.*;
import org.jmin.bridge.config.*;
import org.jmin.logger.Logger;

public class RuntimeLoader extends URLClassLoader{
private static Logger logger = Logger.getLogger(RuntimeLoader.class);
private static RuntimeLoader loader = null;
private static List urlList = new LinkedList();

public static RuntimeLoader getClassLoader(){
if(loader == null){
loader= new RuntimeLoader(AutoDetector.getInstance().getURLs(),
getSystemClassLoader());
} else {
URL[] urls = AutoDetector.getInstance().getURLs();
for(int i=0;i < urls.length;i++){
loader.addURL(urls[i]);
}
}
return loader;
}

public RuntimeLoader(URL[] urls) {
super(urls);
}

public Class loadClass(String clsname)
throws ClassNotFoundException {
return super.loadClass(clsname);
}

private List getList(){
if(urlList == null)
urlList = new LinkedList();
return urlList;
}

public RuntimeLoader(URL[] urls,ClassLoader parent) {
super(urls,parent);
}

public RuntimeLoader(URL[] urls, ClassLoader parent,
URLStreamHandlerFactory factory) {
super(urls,parent,factory);
}

public void addURL(URL url) {
if(!getList().contains(url)){
logger.debug("add url: " +url);
super.addURL(url);
getList().add(url);
}
}

protected void finalize() throws Throwable{
super.finalize();
}

private ClassLoader getParentClassLoader(){
if(loader == null)
return (OBClassLoader.class).getClassLoader();
else
return loader;
}

public static ClassLoader getSystemClassLoader(){
return (OBClassLoader.class).getClassLoader();
}
}
chris liao
Greenhorn

Joined: Jul 24, 2005
Posts: 27
and I wrote a Detector, source code is below:

package org.jmin.bridge.deploy;

import java.io.*;
import java.net.*;
import java.util.*;

import org.jmin.bridge.util.*;
import org.jmin.bridge.config.*;
import org.jmin.bridge.core.*;
import org.jmin.bridge.loader.*;
import org.jmin.bridge.common.*;
import org.jmin.bridge.server.*;
import org.jmin.logger.Logger;

public class AutoDetector extends Thread {
private static Logger logger = Logger.getLogger(AutoDetector.class);

private static String deployFolder = null;
private static String workFolder = null;
private static int PoolDetectTime =0;
private static AutoDetector deploy = null;

private File detectFolder = null;
private List currentFileList = null;
private List lastFileList = null;
private Map urlMap = null;

private Map fileServiceMap = null;
private Thread fatherThread = null;

static{
PoolDetectTime =
Config.getInstance().
getInt(ConfigKey.KEY_Thread_Pool_Detect_Time,
ConfigConstants.Thread_Pool_Detect_Time);

deployFolder = Config.getInstance().
getString(
ConfigKey.KEY_Deploy_Path);
workFolder = Config.getInstance().
getString(
ConfigKey.KEY_Work_Path);

deployFolder = "D:\\bridge\\deploy";// test
workFolder = "D:\\bridge\\work";//test

if(Util.isNull(deployFolder)&& CurrentRole.isServerRole()){
deployFolder = getDeployPath();
}

if(Util.isNull(workFolder)&& CurrentRole.isServerRole()){
workFolder = getWorkPath();
}

if(!Util.isNull(deployFolder) && !deployFolder.endsWith("\\")){
deployFolder = deployFolder +"\\";
}

if(!Util.isNull(workFolder) && !workFolder.endsWith("\\")){
workFolder = workFolder +"\\";
}
}

public static AutoDetector getInstance(){
if(deploy == null)
deploy = new AutoDetector();
return deploy;
}

public AutoDetector() {
this.prepare();
this.currentFileList = new LinkedList();
this.lastFileList = new LinkedList();
this.urlMap = new Hashtable();
this.fileServiceMap = new Hashtable();
this.fatherThread = Thread.currentThread();
if(!Util.isNull(workFolder) && !Util.isNull(workFolder)){
this.start();
}
}

private void prepare(){
detectFolder = new File(deployFolder);
if(!detectFolder.exists()&& CurrentRole.isServerRole()){
detectFolder.mkdirs();
}

File work = new File(workFolder);
if(!work.exists()&& CurrentRole.isServerRole()){
work.mkdirs();
}else{
File[] files = work.listFiles();
for(int i =0;i<files.length;i++)
files[i].delete();
}
}

public void run(){
ThreadPool.getInstance().push(fatherThread,this);
while(fatherThread.isAlive()){
this.getDeployFileList();
this.detectNewFile();
this.detectDelFile();
this.detectUpdateFile();
this.storeDeployFileList();
this.wait(PoolDetectTime);
}
}

private void wait(int time){
try{
Thread.sleep(time);
}catch(Exception e){
}
}

private void detectNewFile(){
for(int i =0;i< currentFileList.size();i++){
if(!lastFileList.contains(currentFileList.get(i))){
try{
FilePair file = (FilePair)currentFileList.get(i);
String filename = file.getFileName();
String wkFile = concludeWkPath(filename);
this.copyFile(file.getFile(),wkFile);
logger.debug("deploy file: " + filename);
Map map = XMLParser.parse(wkFile);
addNewService(filename,map);
addNewURL(filename,new File(wkFile).toURL());

}catch(Exception e){
e.printStackTrace();
}
}
}
}

private void addNewURL(String filename,URL ulr){
urlMap.put(filename,ulr);
}

private void removeURL(String filename){
urlMap.remove(filename);
}

private void detectDelFile(){
for(int i =0;i< lastFileList.size();i++){
if(!currentFileList.contains(lastFileList.get(i))){
FilePair file = (FilePair)lastFileList.get(i);
String filename = file.getFileName();
removeService(filename);
removeURL(filename);
logger.debug("undeploy file: " + filename);
}
}
}

private void detectUpdateFile(){
for(int i=0; i < lastFileList.size();i++){
try{
FilePair lastFile = (FilePair)lastFileList.get(i);
FilePair currentFile = getCurrentFile(lastFile);
if(currentFile != null && (currentFile.isModified(lastFile))){
String filename = currentFile.getFileName();
logger.debug("redeploy file: " + filename);
String wkFile = concludeWkPath(filename);
this.copyFile(currentFile.getFile(),wkFile);
Map map = XMLParser.parse(wkFile);
addNewService(filename,map);
addNewURL(filename,new File(wkFile).toURL());

}
}catch(Exception e){
}
}
}


private FilePair getCurrentFile(FilePair pair){
FilePair currentPair = null;
for(int i = 0;i < currentFileList.size();i++){
FilePair temp = (FilePair)currentFileList.get(i);
if(temp.equals(pair)){
currentPair = temp;
break;
}
}
return currentPair;
}

private synchronized void getDeployFileList(){
currentFileList.clear();
File[] files = detectFolder.listFiles();
for(int i = 0;i < files.length;i++){
if(files[i].getName().endsWith("jar") ||
files[i].getName().endsWith("zip")){
currentFileList.add(new FilePair(files[i]));
}
}
}

private void storeDeployFileList(){
this.lastFileList.clear();
this.lastFileList.addAll(currentFileList);
}

private String concludeWkPath(String shortname){
return workFolder + Counter.getValue()+ shortname;
}

private void copyFile(File deployJar, String file2)
throws IOException,FileNotFoundException{
FileInputStream deployjar = new FileInputStream(deployJar);
FileOutputStream workjar = new FileOutputStream(file2);
while(true){
int byteValue = deployjar.read();
if(byteValue == -1)
break;
workjar.write(byteValue);
}
workjar.close();
deployjar.close();
}

private static String getDeployPath(){
String path = CurrentRole.getAppPath();
if(!path.substring(path.length()).equals("\\")){
path = path + "\\";
}
path = path + "deploy";
File deployDict = new File(path);
if(!deployDict.exists()){
logger.debug("create folder: " + path);
deployDict.mkdirs();
}
return path;
}

private static String getWorkPath(){
String path = CurrentRole.getAppPath();
if(!path.substring(path.length()).equals("\\")){
path = path + "\\";
}
path = path + "work";
File workDict = new File(path);
if(!workDict.exists()){
logger.debug("create folder: " + path);
workDict.mkdirs();
}
return path;
}

private void addNewService(String file, Map newMap){
removeService(file);
fileServiceMap.put(file,newMap);
addServiceToManager(newMap);
}

private void removeService(String file){
Map oldMap = (Map)fileServiceMap.get(file);
if(oldMap != null){
removeServiceFromManager(oldMap);
fileServiceMap.remove(file);
}
}

private void addServiceToManager(Map map){
Iterator it = map.entrySet().iterator();
while(it.hasNext()){
Map.Entry entry = (Map.Entry)it.next();
String key = (String)entry.getKey();
String value = (String)entry.getValue();
ServiceManager.getInstance().addServiceClass(key,value);
}
}

private void removeServiceFromManager(Map map){
Iterator it = map.entrySet().iterator();
while(it.hasNext()){
Map.Entry entry = (Map.Entry)it.next();
String key = (String)entry.getKey();
ServiceManager.getInstance().remove(key);
}
}

private synchronized Collection getWorkFileList(){
return urlMap.values();
}

public URL[] getURLs(){
Collection col = getWorkFileList();
URL[] arry = new URL[col.size()];
Iterator it = col.iterator();
int i = 0;
while(it.hasNext()){
arry[i]=(URL)it.next();
}
return arry;
}
}

class Counter {
private static long value = 1;
public static long getValue(){
return value++;
}
}
chris liao
Greenhorn

Joined: Jul 24, 2005
Posts: 27
when load some class:

ClassNotFoundException is throwed.
Tony Morris
Ranch Hand

Joined: Sep 24, 2003
Posts: 1608
I didn't go through your code, but "hot loading" (definition assumed) is really quite easy. The main point is that you must load classes with a new class loader each time you use the, since classes cannot be unloaded from class loaders, and so they cannot be redefined within the same class loader.


Tony Morris
Java Q&A (FAQ, Trivia)
Stan James
(instanceof Sidekick)
Ranch Hand

Joined: Jan 29, 2003
Posts: 8791
Anyone know if you must write a custom class loader to do this? I dug through JUnit to find the one it uses and it is pretty simple, but I didn't try to figure out why they needed a custom one at all.

What's a common way to make a whole application start using a new class loader? If you're doing plain old "new Object()" all over the place you'll just keep using the loader that loaded the class you're in, right? Do you need a global loader or a factory that knows when laoders change?


A good question is never answered. It is not a bolt to be tightened into place but a seed to be planted and to bear more seed toward the hope of greening the landscape of the idea. John Ciardi
 
I agree. Here's the link: http://aspose.com/file-tools
 
subject: how to hot deploy jar files