Перезапустить / переустановить сервлет
Я хочу перезапустить сервлет (объявленный в web.xml, когда JBoss работает) просто потому, что его init-param указывает на файл, содержимое которого было изменено (т.е. был изменен нижеприведенный provider.fac).
Если есть способ перезагрузить init-param без перезапуска сервлета, это тоже будет хорошо.
Я полагаю, я могу изменить сервлет для добавления параметра запроса и функции для перезапуска? Есть ли другой вариант?
<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 Framework 2.5
4 ответа
2 варианта:
Добавить дополнительную проверку на
doGet()
или жеdoPost()
который перезагружает файл, когда задан определенный параметр запроса, когда пользователь-администратор вошел в систему, и предоставляет экран администратора, который вызывает этот запрос.Переписать сервлет (или реорганизовать деталь в
ServletContextListener
) хранить его вServletContext
вместо того, чтобы в качестве переменной экземпляра сервлета и иметь некоторый экран администратора, который перезагружает файл вServletContext
,
Если вы планируете перезапускать ваш сервлет автоматически и много раз в день / неделю, вы должны убедиться, что ваш permgen достаточно хорош, чтобы справиться с перезагрузками сервлета. Были случаи, когда я делал это на производстве и сгорал от множества ошибок PermGen.
Если вы находитесь в jboss, вы можете просто перезапустить сервлет, изменив файл web.xml, если ваш сервлет взорван. На Linux касание сделало бы.
Не уверен, в каком формате находится ваш файл конфигурации, но если вы пытаетесь автоматически перезагрузить файл конфигурации свойств, я бы посмотрел библиотеку конфигурации commons, которая поддерживает это из коробки ( FileChangedReloadingStrategy)
Я бы отделил эти проблемы, вытащив управление файлами из сервлета и поместив его в JBoss JMX ServiceMBean. MBean может следить за изменениями в файле и, при необходимости, перезагружать его, а также может предоставлять необходимые операции [вызывающему сервлету]. Это позволит вам не загружать и не перезапускать сервлет (или WAR), которые являются довольно тяжелыми операциями.
Я придумаю пару операций для FileManager:
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 */
}
}
Ваш сервлет может выглядеть так:
// 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.
Я понимаю, что это выглядит немного перегруженным, но вы действительно должны отделить функции сервлета от функций управления файлом.