Skip to content

Commit

Permalink
WLFY-10048 - Deploying of malformed MDB should fail
Browse files Browse the repository at this point in the history
  • Loading branch information
rpelisse committed May 3, 2018
1 parent f6980eb commit 5ae1810
Show file tree
Hide file tree
Showing 11 changed files with 426 additions and 30 deletions.
Expand Up @@ -25,7 +25,6 @@
import static org.jboss.as.ejb3.deployment.processors.AbstractDeploymentUnitProcessor.getEjbJarDescription; import static org.jboss.as.ejb3.deployment.processors.AbstractDeploymentUnitProcessor.getEjbJarDescription;
import static org.jboss.as.ejb3.deployment.processors.ViewInterfaces.getPotentialViewInterfaces; import static org.jboss.as.ejb3.deployment.processors.ViewInterfaces.getPotentialViewInterfaces;


import java.lang.reflect.Modifier;
import java.util.Collection; import java.util.Collection;
import java.util.HashSet; import java.util.HashSet;
import java.util.Properties; import java.util.Properties;
Expand All @@ -41,6 +40,7 @@
import org.jboss.as.ejb3.component.messagedriven.MessageDrivenComponentDescription; import org.jboss.as.ejb3.component.messagedriven.MessageDrivenComponentDescription;
import org.jboss.as.ejb3.deployment.EjbJarDescription; import org.jboss.as.ejb3.deployment.EjbJarDescription;
import org.jboss.as.ejb3.logging.EjbLogger; import org.jboss.as.ejb3.logging.EjbLogger;
import org.jboss.as.ejb3.util.MdbValidationsUtil;
import org.jboss.as.server.deployment.DeploymentUnit; import org.jboss.as.server.deployment.DeploymentUnit;
import org.jboss.as.server.deployment.DeploymentUnitProcessingException; import org.jboss.as.server.deployment.DeploymentUnitProcessingException;
import org.jboss.as.server.deployment.EjbDeploymentMarker; import org.jboss.as.server.deployment.EjbDeploymentMarker;
Expand Down Expand Up @@ -101,7 +101,7 @@ private void processMessageBeans(final DeploymentUnit deploymentUnit, final Coll
for (final AnnotationInstance messageBeanAnnotation : messageBeanAnnotations) { for (final AnnotationInstance messageBeanAnnotation : messageBeanAnnotations) {
final AnnotationTarget target = messageBeanAnnotation.target(); final AnnotationTarget target = messageBeanAnnotation.target();
final ClassInfo beanClassInfo = (ClassInfo) target; final ClassInfo beanClassInfo = (ClassInfo) target;
if (!assertMDBClassValidity(beanClassInfo)) { if (! MdbValidationsUtil.assertMDBClassValidity(beanClassInfo).isEmpty() ) {
continue; continue;
} }
final String ejbName = beanClassInfo.name().local(); final String ejbName = beanClassInfo.name().local();
Expand Down Expand Up @@ -178,39 +178,11 @@ private String getMessageListenerInterface(final CompositeIndex compositeIndex,
// move to next super class // move to next super class
superClassDotName = superClass.superName(); superClassDotName = superClass.superName();
} }

if (interfaces.size() != 1) if (interfaces.size() != 1)
throw EjbLogger.ROOT_LOGGER.mdbDoesNotImplementNorSpecifyMessageListener(beanClass); throw EjbLogger.ROOT_LOGGER.mdbDoesNotImplementNorSpecifyMessageListener(beanClass);
return interfaces.iterator().next().toString(); return interfaces.iterator().next().toString();
} }



/**
* Returns true if the passed <code>mdbClass</code> meets the requirements set by the EJB3 spec about
* bean implementation classes. The passed <code>mdbClass</code> must not be an interface and must be public
* and not final and not abstract. If it passes these requirements then this method returns true. Else it returns false.
*
* @param mdbClass The MDB class
* @return
*/
private boolean assertMDBClassValidity(final ClassInfo mdbClass) {
final short flags = mdbClass.flags();
final String className = mdbClass.name().toString();
// must *not* be an interface
if (Modifier.isInterface(flags)) {
EjbLogger.DEPLOYMENT_LOGGER.mdbClassCannotBeAnInterface(className);
return false;
}
// bean class must be public, must *not* be abstract or final
if (!Modifier.isPublic(flags) || Modifier.isAbstract(flags) || Modifier.isFinal(flags)) {
EjbLogger.DEPLOYMENT_LOGGER.mdbClassMustBePublicNonAbstractNonFinal(className);
return false;
}
// valid class
return true;
}


private Properties getActivationConfigProperties(final ActivationConfigMetaData activationConfig) { private Properties getActivationConfigProperties(final ActivationConfigMetaData activationConfig) {
final Properties activationConfigProps = new Properties(); final Properties activationConfigProps = new Properties();
if (activationConfig == null || activationConfig.getActivationConfigProperties() == null) { if (activationConfig == null || activationConfig.getActivationConfigProperties() == null) {
Expand Down
16 changes: 16 additions & 0 deletions ejb3/src/main/java/org/jboss/as/ejb3/logging/EjbLogger.java
Expand Up @@ -3154,4 +3154,20 @@ public interface EjbLogger extends BasicLogger {
@LogMessage(level = ERROR) @LogMessage(level = ERROR)
@Message(id = 502, value = "Exception checking if timer %s should run") @Message(id = 502, value = "Exception checking if timer %s should run")
void exceptionCheckingIfTimerShouldRun(Timer timer, @Cause Exception e); void exceptionCheckingIfTimerShouldRun(Timer timer, @Cause Exception e);

@LogMessage(level = WARN)
@Message(id = 503, value = "[EJB3.2 spec, section 5.6.4] Message Driven Bean 'onMessage' method can not be final (MDB: %s).")
void mdbOnMessageMethodCantBeFinal(String className);

@LogMessage(level = WARN)
@Message(id = 504, value = "[EJB3.2 spec, section 5.6.4] Message Driven Bean 'onMessage' method can not be private (MDB: %s).")
void mdbOnMessageMethodCantBePrivate(String className);

@LogMessage(level = WARN)
@Message(id = 505, value = "[EJB3.2 spec, section 5.6.4] Message Driven Bean 'onMessage' method can not be static (MDB: %s).")
void mdbOnMessageMethodCantBeStatic(String className);

@LogMessage(level = WARN)
@Message(id = 506, value = "[EJB3.2 spec, section 5.6.2] Message Driven Bean can not have a 'finalize' method. (MDB: %s)")
void mdbCantHaveFinalizeMethod(String className);
} }
97 changes: 97 additions & 0 deletions ejb3/src/main/java/org/jboss/as/ejb3/util/MdbValidationsUtil.java
@@ -0,0 +1,97 @@
/*
* JBoss, Home of Professional Open Source.
* Copyright 2018, Red Hat, Inc., and individual contributors
* as indicated by the @author tags. See the copyright.txt file in the
* distribution for a full listing of individual contributors.
*
* This is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation; either version 2.1 of
* the License, or (at your option) any later version.
*
* This software is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this software; if not, write to the Free
* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
*/

package org.jboss.as.ejb3.util;

import java.lang.reflect.Modifier;
import java.util.ArrayList;
import java.util.Collection;

import org.jboss.as.ejb3.logging.EjbLogger;
import org.jboss.as.server.deployment.DeploymentUnitProcessingException;
import org.jboss.jandex.ClassInfo;
import org.jboss.jandex.MethodInfo;

/**
* @author Romain Pelisse - romain@redhat.com
*/
public final class MdbValidationsUtil {

private MdbValidationsUtil() {

}

/**
* Returns true if the passed <code>mdbClass</code> meets the requirements set by the EJB3 spec about bean implementation
* classes. The passed <code>mdbClass</code> must not be an interface and must be public and not final and not abstract. If
* it passes these requirements then this method returns true. Else it returns false.
*
* @param mdbClass The MDB class
* @return
* @throws DeploymentUnitProcessingException
*/
public static Collection<MdbValidityStatus> assertMDBClassValidity(final ClassInfo mdbClass) throws DeploymentUnitProcessingException {
Collection<MdbValidityStatus> mdbComplianceIssueList = new ArrayList<>(MdbValidityStatus.values().length);
final String className = mdbClass.name().toString();
verifyModifiers(className, mdbClass.flags(), mdbComplianceIssueList);
for (MethodInfo method : mdbClass.methods()) {
if ("onMessage".equals(method.name())) {
verifyOnMessageMethod(className, method.flags(), mdbComplianceIssueList);
}

if ("finalize".equals(method.name())) {
EjbLogger.DEPLOYMENT_LOGGER.mdbCantHaveFinalizeMethod(className);
mdbComplianceIssueList.add(MdbValidityStatus.MDB_SHOULD_NOT_HAVE_FINALIZE_METHOD);
}
}
return mdbComplianceIssueList;
}

private static void verifyModifiers(final String className, final short flags, final Collection<MdbValidityStatus>mdbComplianceIssueList) {
// must *not* be an interface
if (Modifier.isInterface(flags)) {
EjbLogger.DEPLOYMENT_LOGGER.mdbClassCannotBeAnInterface(className);
mdbComplianceIssueList.add(MdbValidityStatus.MDB_CANNOT_BE_AN_INTERFACE);
}
// bean class must be public, must *not* be abstract or final
if (!Modifier.isPublic(flags) || Modifier.isAbstract(flags) || Modifier.isFinal(flags)) {
EjbLogger.DEPLOYMENT_LOGGER.mdbClassMustBePublicNonAbstractNonFinal(className);
mdbComplianceIssueList.add(MdbValidityStatus.MDB_CLASS_CANNOT_BE_PRIVATE_ABSTRACT_OR_FINAL);
}
}

private static void verifyOnMessageMethod(final String className, final short methodsFlags, final Collection<MdbValidityStatus>mdbComplianceIssueList) {
if (Modifier.isFinal(methodsFlags)) {
EjbLogger.DEPLOYMENT_LOGGER.mdbOnMessageMethodCantBeFinal(className);
mdbComplianceIssueList.add(MdbValidityStatus.MDB_ON_MESSAGE_METHOD_CANT_BE_FINAL);
}
if (Modifier.isStatic(methodsFlags)) {
EjbLogger.DEPLOYMENT_LOGGER.mdbOnMessageMethodCantBeStatic(className);
mdbComplianceIssueList.add(MdbValidityStatus.MDB_ON_MESSAGE_METHOD_CANT_BE_STATIC);
}
if (Modifier.isPrivate(methodsFlags)) {
EjbLogger.DEPLOYMENT_LOGGER.mdbOnMessageMethodCantBePrivate(className);
mdbComplianceIssueList.add(MdbValidityStatus.MDB_ON_MESSAGE_METHOD_CANT_BE_PRIVATE);
}
}
}

31 changes: 31 additions & 0 deletions ejb3/src/main/java/org/jboss/as/ejb3/util/MdbValidityStatus.java
@@ -0,0 +1,31 @@
/*
* JBoss, Home of Professional Open Source.
* Copyright 2018, Red Hat, Inc., and individual contributors
* as indicated by the @author tags. See the copyright.txt file in the
* distribution for a full listing of individual contributors.
*
* This is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation; either version 2.1 of
* the License, or (at your option) any later version.
*
* This software is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this software; if not, write to the Free
* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
*/


package org.jboss.as.ejb3.util;

/**
* @author Romain Pelisse - romain@redhat.com
*/
public enum MdbValidityStatus {
MDB_CANNOT_BE_AN_INTERFACE, MDB_CLASS_CANNOT_BE_PRIVATE_ABSTRACT_OR_FINAL, MDB_ON_MESSAGE_METHOD_CANT_BE_FINAL, MDB_ON_MESSAGE_METHOD_CANT_BE_STATIC, MDB_ON_MESSAGE_METHOD_CANT_BE_PRIVATE, MDB_SHOULD_NOT_HAVE_FINALIZE_METHOD, MDB_IS_VALID;
}
@@ -0,0 +1,33 @@
/*
* JBoss, Home of Professional Open Source.
* Copyright 2018, Red Hat, Inc., and individual contributors
* as indicated by the @author tags. See the copyright.txt file in the
* distribution for a full listing of individual contributors.
*
* This is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation; either version 2.1 of
* the License, or (at your option) any later version.
*
* This software is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this software; if not, write to the Free
* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
*/

package org.jboss.as.ejb3.util;

/**
*
* @author <a href="mailto:romain@redhat.com">Romain Pelisse</a>
*/
public final class InvalidMdbFinalClass {

public void aRegularMethod() {
};
}
32 changes: 32 additions & 0 deletions ejb3/src/test/java/org/jboss/as/ejb3/util/InvalidMdbInterface.java
@@ -0,0 +1,32 @@
/*
* JBoss, Home of Professional Open Source.
* Copyright 2018, Red Hat, Inc., and individual contributors
* as indicated by the @author tags. See the copyright.txt file in the
* distribution for a full listing of individual contributors.
*
* This is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation; either version 2.1 of
* the License, or (at your option) any later version.
*
* This software is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this software; if not, write to the Free
* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
*/

package org.jboss.as.ejb3.util;

/**
*
* @author <a href="mailto:romain@redhat.com">Romain Pelisse</a>
*/
public interface InvalidMdbInterface {

void aMethod();
}
@@ -0,0 +1,32 @@
/*
* JBoss, Home of Professional Open Source.
* Copyright 2018, Red Hat, Inc., and individual contributors
* as indicated by the @author tags. See the copyright.txt file in the
* distribution for a full listing of individual contributors.
*
* This is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation; either version 2.1 of
* the License, or (at your option) any later version.
*
* This software is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this software; if not, write to the Free
* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
*/
package org.jboss.as.ejb3.util;

/**
*
* @author <a href="mailto:romain@redhat.com">Romain Pelisse</a>
*/
public class InvalidMdbOnMessageCantBeFinal {

public final void onMessage() {
};
}
@@ -0,0 +1,32 @@
/*
* JBoss, Home of Professional Open Source.
* Copyright 2018, Red Hat, Inc., and individual contributors
* as indicated by the @author tags. See the copyright.txt file in the
* distribution for a full listing of individual contributors.
*
* This is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation; either version 2.1 of
* the License, or (at your option) any later version.
*
* This software is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this software; if not, write to the Free
* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
*/
package org.jboss.as.ejb3.util;

/**
*
* @author <a href="mailto:romain@redhat.com">Romain Pelisse</a>
*/
public class InvalidMdbOnMessageCantBePrivate {

private void onMessage() {
};
}
@@ -0,0 +1,29 @@
/*
* JBoss, Home of Professional Open Source.
* Copyright 2018, Red Hat, Inc., and individual contributors
* as indicated by the @author tags. See the copyright.txt file in the
* distribution for a full listing of individual contributors.
*
* This is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation; either version 2.1 of
* the License, or (at your option) any later version.
*
* This software is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this software; if not, write to the Free
* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
*/
package org.jboss.as.ejb3.util;

public class InvalidMdbOnMessageCantBeStatic {

public static void onMessage() {

}
}

0 comments on commit 5ae1810

Please sign in to comment.