2011-05-16 163 views
0

我想重新启动一个servlet(在JBoss运行时在web.xml中声明),因为它的init-param指向一个内容已更改的文件(即下面的providers.fac已被修改) 。重新启动/重新启动一个servlet

如果有一种方法可以在不重新启动servlet的情况下重新加载init-param,那也不错。

我想我可以修改这个servlet来添加一个请求参数和函数来重启它自己吗? 还有其他选择吗?

<servlet> 
    <servlet-name>coverage</servlet-name> 
    <servlet-class>coverageServlet</servlet-class> 
    <init-param> 
     <param-name>ConfigUrl</param-name> 
     <param-value>file:///C:/coverage/providers.fac</param-value> 
    </init-param> 
    <init-param> 
     <param-name>CacheDir</param-name> 
     <param-value>coverage</param-value> 
    </init-param>   
    <load-on-startup>1</load-on-startup> 
</servlet> 

环境: Servlet API的2.4 的JBoss 4.2 Spring框架2.5

回答

0

2个选择:

  1. 添加额外的检查上doGet()doPost()其中重新加载当特定请求参数被设定,而管理员用户登录并提供管理屏幕它调用该请求的文件。

  2. 重写的servlet(或重构部分ServletContextListener)以将其存储在ServletContext而不是作为servlet的一个实例变量,并有一些管理屏幕,其在重新加载ServletContext该文件。

+0

谢谢,我最终这样做了。 – portoalet 2011-05-17 03:28:22

1

如果你是在JBoss中,你可以简单地重新启动通过改变web.xml文件,如果你的servlet被爆炸的servlet。在Linux上触摸会做。

不知道什么格式的配置文件是,但如果你想自动重新加载一个属性配置文件,我想看看公地配置LIB支持此开箱即用(FileChangedReloadingStrategy

+0

谢谢,我会尝试FilechangedReloadingStrategy,因为手动重启是不可接受的。 – portoalet 2011-05-16 06:56:27

1

如果您计划在一天/一周内自动重启你的servlet并多次重启你的servlet,你应该确保你的permgen足够处理servlet重载。有些情况下,我在制作过程中做了这些事情,并因PermGen的许多错误而让自己陷入困境。

+0

你重新启动了一个servlet还是全部?是的,当我多次手动重新部署* .war时,我看到一些PermGen错误 – portoalet 2011-05-16 07:20:33

+0

@portoalet这是一个servlet,但是是一个控制器servlet,完成所有繁重的工作 – 2011-05-16 07:32:43

0

我将文件管理从servlet中拉出来放到JBoss JMX ServiceMBean中,以分开这些问题。 MBean可以在需要时关注文件的更改和重新加载,还可以向[调用的servlet]公开所需的操作。这将允许您不必重新加载和重新启动相当重量级操作的servlet(或WAR)。

我会发明了几个操作的文件管理:

public interface FileManagerMBean extends org.jboss.system.ServiceMBean { 
    public void setFileName(String fileName); 
    public void setCheckFrequency(long freq); 
    public String getCoverageData(......); 
    public String getProviderData(......); 
} 

的实现可能(在同一个包,请:))

public class FileManager extends org.jboss.system.ServiceMBeanSupport implements FileManagerMBean { 
    public void setFileName(String fileName) { .... } 
    public void setCheckFrequency(long freq) { .... } 
    public String getCoverageData(......) { /* impl */ } 
    public String getProviderData(......) { /* impl */ } 
    public void startService() throws Exception { 
     /* Start a file watcher thread */ 
    } 
    public void stopService() throws Exception { 
     /* Stop the file watcher thread */ 
    } 

} 

你的servlet可能是这样的:

// A ref to the MBean 
FileManagerMBean fileMgr = null; 
// The JMX MBean's ObjectName 
ObjectName fileMgrOn = org.jboss.mx.util.ObjectNameFactory.create("portoalet.com:service=FileManager"); 

public void init() { 
    // Get the JBoss MBeanServer 
    MBeanServer server = org.jboss.mx.util.MBeanServerLocator.locateJBoss(); 
    // Create an MBeanInvoker for the service 
    fileMgr = (FileManagerMBean)javax.management.MBeanServerInvocationHandler.newProxyInstance(server, fileMgrOn,FileManagerMBean.class, false);  
} 

现在你可以使用fileMgr实例调用FileManager MBean,它应该是线程安全的,除非您同步访问fileMgr

我意识到这看起来有些过度设计,但你真的应该将servlet的功能与管理文件的功能分开。