package org.jboss.loom.actions.review;
import java.io.File;
import java.util.List;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Unmarshaller;
import javax.xml.bind.annotation.XmlAttribute;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
import org.jboss.loom.actions.CopyFileAction;
import org.jboss.loom.actions.IMigrationAction;
import org.jboss.loom.ex.MigrationException;
/**
* TODO: Check each <bean class="...">. If the class is org.jboss.*, WARN.
*
* TBC: This concept has very narrow usage, or is inefficient.
* Fore example this one - if CopyAction uses Ant pathMask, it would have to scan all that files.
* Could it hook at different level? E.g. to some "onCopyFileToDeployments" event?
* Or should it be entirely left up to migrators?
*
* @author Ondrej Zizka, ozizka at redhat.com
*/
public class BeansXmlReview extends ActionReviewBase {
@Override
public void review( IMigrationAction action ) throws MigrationException {
// Only accept CopyActions with -beans.xml
if( ! ( action instanceof CopyFileAction ) ) return;
CopyFileAction ca = (CopyFileAction) action;
// It may have Ant-like $pathMaks instead of $src.
if( ca.getSrc() == null ) return;
String fName = ca.getSrc().getName();
if( ! fName.endsWith("-beans.xml")) return;
// Check each <bean class="...">. If the class is org.jboss.*, WARN.
List<Bean> beans = extractBeans( ca.getSrc() );
for( Bean bean : beans ) {
if( bean.cls.startsWith("org.jboss.")){
action.getWarnings().add("A bean in " + fName + " uses org.jboss.* class: " + bean.cls + "\n"
+ "Using MBeans is only supported as a legacy technology.\n"
+ "Server boot may fail with ClassNotFoundException.\n"
+ "Consult server documentation about classloading and modules.");
}
}
}
private List<Bean> extractBeans( File beansFile ) throws MigrationException {
try {
Unmarshaller unmarshaller = JAXBContext.newInstance(Deployment.class).createUnmarshaller();
Deployment depl = (Deployment) unmarshaller.unmarshal(beansFile);
return depl.beans;
} catch( JAXBException ex ) {
throw new MigrationException("Failed parsing " + beansFile.getAbsolutePath() + ":\n " + ex, ex);
}
}
}// class
/**
<deployment xmlns="urn:jboss:bean-deployer:2.0">
<!-- JMX notifier to trigger a resync with JDK log levels when the log4j config changes-->
<bean name="LogBridgeNotifier" class="org.jboss.logbridge.LogNotificationListener">
<property name="logBridgeHandler"><inject bean="LogBridgeHandler"/></property>
<property name="MBeanServer"><inject bean="JMXKernel" property="mbeanServer"/></property>
<property name="loggingMBeanName">jboss.system:service=Logging,type=Log4jService</property>
<depends>jboss.system:service=Logging,type=Log4jService</depends>
</bean>
</deployment>
*/
@XmlRootElement(name = "deployment", namespace = "urn:jboss:bean-deployer:2.0")
class Deployment {
@XmlElement(name = "bean", namespace = "urn:jboss:bean-deployer:2.0")
List<Bean> beans;
}
class Bean {
@XmlAttribute(name = "class") String cls;
@XmlAttribute(name = "name") String name;
}