JBoss에 디플로이된 어플리케이션을 백업할 경우에 한 가지 주의할 사항이 있는데, deploy 디렉터리에 백업 디렉터리를 만들어서 백업을 보관하면 안된다는 것이다.
아래는 deploy 디렉터리 아래에 백업 디렉터리를 만들어서 어플리케이션을 카피해서 백업할 경우 발생할 수 있는 에러의 예이다.
$mkdir backup/0225
$cp -r eartest.ear backup/0225
13:41:05,802 INFO [EARDeployer] Init J2EE application: file:/D:/Workplace/jboss-eap-4.3/jboss-as/server/default/deploy/backup/0225/eartest.ear/
13:41:06,453 WARN [ServiceController] Problem creating service jboss.j2ee:module=ejbapp.jar,uid=18965738,service=EJB3
java.lang.IllegalStateException: Container jboss.j2ee:ear=eartest.ear,jar=ejbapp.jar,name=CalculatorBean,service=EJB3,VMID=32712701987592b5:-10a355f2:1184ee37c1a:-7ffc + is already registered
at org.jboss.ejb3.Ejb3Registry.register(Ejb3Registry.java:114)
at org.jboss.ejb3.Ejb3Deployment.deployElement(Ejb3Deployment.java:494)
at org.jboss.ejb3.Ejb3Deployment.deployElement(Ejb3Deployment.java:442)
at org.jboss.ejb3.Ejb3Deployment.deployUrl(Ejb3Deployment.java:423)
at org.jboss.ejb3.Ejb3Deployment.deploy(Ejb3Deployment.java:384)
... ...
13:41:06,463 INFO [EARDeployment] Registration is not done -> stop
13:41:06,463 ERROR [MainDeployer] Could not create deployment: file:/D:/Workplace/jboss-eap-4.3/jboss-as/server/default/deploy/backup/0225/eartest.ear/
org.jboss.deployment.DeploymentException: Error during create of EARDeployment: file:/D:/Workplace/jboss-eap-4.3/jboss-as/server/default/deploy/backup/0225/eartest.ear/; - nested throwable: (javax.management.InstanceAlreadyExistsException: jboss.j2ee:service=EARDeployment,url='eartest.ear' already registered.)
at org.jboss.deployment.DeploymentException.rethrowAsDeploymentException
(DeploymentException.java:53)
... ...
--> 에러에서 알 수 있듯이 .war나 .ear 같은 아카이브 확장자 없이 디렉터리를 만들었음에도 JBoss는 하위 디렉터리까지 뒤져 어플리케이션을 디플로이하려 한다.
$cp -r webapp.war backup/0225
13:53:52,114 INFO [TomcatDeployer] deploy, ctxPath=/webapp, warUrl=.../deploy/backup/0225/webapp.war/
--> 백업받은 어플리케이션이 디플로이가 되버린 경우이다.
위와 같은 에러를 방지할 수 있는 방법으로 DeploymentScanner 서비스의 FilterInstance를 설정하는 방법이 있다.
$JBOSS_HOME/server/<instance>/conf/jboss-service.xml |
<!-- The FilterInstance specifies a URLLister.URLFilter for scanned directories. This DeploymentFilter is initialized with the given prefixes, suffixes and matches that define which URLs should be ignored. --> <attribute name="FilterInstance" attributeClass="org.jboss.deployment.scanner.DeploymentFilter" serialDataType="javaBean"> <!-- Files starting with theses strings are ignored --> <property name="prefixes">#,%,\,,.,_$</property> <!-- Files ending with theses strings are ignored --> <property name="suffixes">#,$,%,~,\,v,.BAK,.bak,.old,.orig,.tmp,.rej,.sh</property> <!-- Files matching with theses strings are ignored --> <property name="matches">backup,.make.state,.nse_depinfo,CVS,CVS.admin,RCS,RCSLOG,SCCS,TAGS,core,tags</property> </attribute> |
DeploymentFilter를 사용하면 디플로이시 무시해야할 파일명 패턴을 지정할 수 있다.
만약 matches 항목에 backup을 추가하면 위에서 예로 든 에러들은 방지할 수 있다.
하지만 backup이 아닌 Backup이라는 디렉터리를 만들어 백업한다면 문제는 또 다시 발생하게 된다.
어떻게 일일이 DeploymentFilter에 무시해야할 파일명 패턴을 다 지정할 수 있을까?
이 보다는 디플로이할 수 있는 파일명 패턴을 지정하는 것이 더 쉬울 것이다.
가장 간단한 방법은 DeploymentFilter 소스를 이용해 별도의 Filter를 직접 만드는 것이다.
JBoss는 오픈 소스라는 점을 잊지 말자. 소스를 다운로드 받아 직접 필요한 기능을 만들어 사용할 수 있다.
DeploymentAcceptFilter.java |
package com.acme.jboss.deployment;
import java.io.FileFilter; import org.jboss.net.protocol.URLLister; import org.jboss.deployment.scanner.*;
/** /** the default prefix list */ /** the default suffix list */ /** the default matches list */
/** The list of allowed prefixes */ /** The list of allowed values */ /** Use the default values for suffixes, prefixes, and matches */ /** if( prefixes == null ) if( suffixes == null )
public void delPrefix(String prefix) public void addSuffix(String suffix) public void delSuffix(String suffix) public String[] getSuffixes() public String[] getPrefixes() public String[] getMatches() public boolean accept(URL baseURL, String memberName)
private boolean accept(String name) for (Iterator<String> iter = suffixes.iterator(); iter.hasNext(); )
for (Iterator<String> iter = prefixes.iterator(); iter.hasNext(); )
for (Iterator<String> iter = matches.iterator(); iter.hasNext(); )
return false; |
소스를 컴파일한 후 jar로 묶어 $JBOSS_HOME/lib 디렉터리에 복사한다.
이제 jboss-service.xml에서 FilterInstance를 새로 만든 DeploymentAcceptFilter로 교체한다.
$JBOSS_HOME/server/<instance>/conf/jboss-service.xml |
<attribute name="FilterInstance" attributeClass="com.acme.jboss.deployment.DeploymentAcceptFilter" serialDataType="javaBean"> <property name="prefixes"></property> <property name="suffixes">.war,.ear,.jar,.zip,.rar,.wsr,.sar,-ds.xml,-service.xml,-deployer.xml,-aop.xml,.deployer</property> <property name="matches">management,jms</property> </attribute> |