/** * All methods should have a * * @param descriptor the Enterprise Java Bean deployment descriptor * @return <code>Result</code> the results for this assertion */ public Result check(EjbDescriptor descriptor) { result = getInitializedResult(); // boolean oneFailed = false; try { if (descriptor instanceof EjbSessionDescriptor || descriptor instanceof EjbEntityDescriptor) { Set methods = descriptor.getMethodDescriptors(); // Set methodPermissions = new HashSet(); boolean noPermissions = false; for (Iterator i = methods.iterator(); i.hasNext(); ) { MethodDescriptor md = (MethodDescriptor) i.next(); Set permissions = descriptor.getMethodPermissionsFor(md); if (permissions.isEmpty() || (permissions == null)) { result.addWarningDetails( smh.getLocalString( getClass().getName() + ".failed", "Warning: Method [ {0} ] of EJB [ {1} ] does not have assigned security-permissions", new Object[] {md.getName(), descriptor.getName()})); result.setStatus(result.WARNING); noPermissions = true; } } if (!noPermissions) { result.passed( smh.getLocalString( getClass().getName() + ".passed", "Valid: All [ {0} ]EJB interfaces methods have security-permissions assigned.", new Object[] {descriptor.getName()})); } } else { result.notApplicable( smh.getLocalString( getClass().getName() + ".notApplicable", "The bean [ {0} ] is neither a Session nor Entity Bean", new Object[] {descriptor.getName()})); return result; } } catch (Exception e) { result.failed( smh.getLocalString( getClass().getName() + ".exception", "The test generated the following exception [ {0} ]", new Object[] {e.getLocalizedMessage()})); } return result; }
public Result check(EjbDescriptor descriptor) { Result result = getInitializedResult(); ComponentNameConstructor compName = getVerifierContext().getComponentNameConstructor(); boolean oneFailed = false; try { Set resRef = descriptor.getResourceReferenceDescriptors(); if (!(resRef.isEmpty())) { Iterator it = resRef.iterator(); while (it.hasNext()) { ResourceReferenceDescriptor resDesc = ((ResourceReferenceDescriptor) it.next()); String refName = resDesc.getName(); if (refName == null || refName.length() == 0) { addErrorDetails(result, compName); result.failed( smh.getLocalString( getClass().getName() + ".failed", "FAILED [AS-EJB resource-ref] : resource-ref has empty res-ref-name")); } else { addGoodDetails(result, compName); result.passed( smh.getLocalString( getClass().getName() + ".passed", "PASSED [AS-EJB resource-ref] : res-ref-name is {0}", new Object[] {refName})); } } } else { addNaDetails(result, compName); result.notApplicable( smh.getLocalString( getClass().getName() + ".notApplicable", "{0} Does not define any resource-ref Elements", new Object[] {descriptor.getName()})); } } catch (Exception ex) { addErrorDetails(result, compName); result.addErrorDetails( smh.getLocalString( getClass().getName() + ".notRun", "NOT RUN [AS-EJB] : Could not create the descriptor object")); } return result; }
private void commonToBothInterfaces(String intf, EjbDescriptor descriptor) { try { Class intfClass = Class.forName(intf, false, getVerifierContext().getClassLoader()); for (Method remoteMethod : intfClass.getMethods()) { // we don't test the EJB methods if (remoteMethod.getDeclaringClass().getName().equals("javax.ejb.EJBObject")) continue; Class beanClass = Class.forName( descriptor.getEjbClassName(), false, getVerifierContext().getClassLoader()); for (Method method : beanClass.getMethods()) { if (method.getName().equals(remoteMethod.getName()) && !RmiIIOPUtils.isValidRmiIIOPReturnType(method.getReturnType())) { // The methods arguments types must be legal types for // RMI-IIOP. This means that their return values must // be of valid types for RMI-IIOP, addErrorDetails(result, compName); result.failed( smh.getLocalString( getClass().getName() + ".failed", "Error: business method [ {0} ] was found, but " + "business method has invalid return type [ {1} ]. Business " + "method return type must be a valid type for RMI-IIOP.", new Object[] {method.getName(), method.getReturnType()})); } } } } catch (ClassNotFoundException e) { Verifier.debug(e); addErrorDetails(result, compName); result.failed( smh.getLocalString( getClass().getName() + ".failedException", "Error: Remote interface [ {0} ] or bean class [ {1} ] does " + "not exist or is not loadable within bean [ {2} ].", new Object[] { descriptor.getRemoteClassName(), descriptor.getEjbClassName(), descriptor.getName() })); } }
/** * Entity bean's Primary Key Class test. If the enterprise bean is a Entity Bean, the Bean * provider specifies the fully qualified name of the Entity bean's primary key class in the * "primary-class" element. The Bean provider 'must' specify the primary key class for an Entity * with bean managed persistence, and 'may' (but is not required to) specify the primary key class * for an Entity with Container-managed persistence. * * @param descriptor the Enterprise Java Bean deployment descriptor * @return <code>Result</code> the results for this assertion */ public Result check(EjbDescriptor descriptor) { Result result = getInitializedResult(); ComponentNameConstructor compName = getVerifierContext().getComponentNameConstructor(); if (descriptor instanceof EjbEntityDescriptor) { String persistence = ((EjbEntityDescriptor) descriptor).getPersistenceType(); if (EjbEntityDescriptor.BEAN_PERSISTENCE.equals(persistence)) { logger.log( Level.FINE, getClass().getName() + ".debug1", new Object[] {descriptor.getName(), "bean"}); String primkey = ((EjbEntityDescriptor) descriptor).getPrimaryKeyClassName(); if (!primkey.equals("java.lang.String")) { try { Class c = Class.forName(primkey, false, getVerifierContext().getClassLoader()); result.addGoodDetails( smh.getLocalString( "tests.componentNameConstructor", "For [ {0} ]", new Object[] {compName.toString()})); result.passed( smh.getLocalString( getClass().getName() + ".passed", "Primary Key Class [ {0} ] exist and is loadable", new Object[] {primkey})); } catch (Exception e) { Verifier.debug(e); result.addErrorDetails( smh.getLocalString( "tests.componentNameConstructor", "For [ {0} ]", new Object[] {compName.toString()})); result.failed( smh.getLocalString( getClass().getName() + ".failedException", "Error: Loading Primary Key Class [ {0} ]", new Object[] {primkey})); return result; } } else { result.addGoodDetails( smh.getLocalString( "tests.componentNameConstructor", "For [ {0} ]", new Object[] {compName.toString()})); result.passed( smh.getLocalString( getClass().getName() + ".passed1", "Primary Key Class is [ {0} ]", new Object[] {primkey})); } return result; } else if (EjbEntityDescriptor.CONTAINER_PERSISTENCE.equals(persistence)) { result.addNaDetails( smh.getLocalString( "tests.componentNameConstructor", "For [ {0} ]", new Object[] {compName.toString()})); result.notApplicable( smh.getLocalString( getClass().getName() + ".notApplicable1", "Entity Bean [ {0} ] with [ {1} ] managed persistence, primkey optional.", new Object[] {descriptor.getName(), persistence})); return result; } else { result.addNaDetails( smh.getLocalString( "tests.componentNameConstructor", "For [ {0} ]", new Object[] {compName.toString()})); result.notApplicable( smh.getLocalString( getClass().getName() + ".notApplicable2", "Expected [ {0} ] managed persistence, but [ {1} ] bean has [ {2} ] managed persistence.", new Object[] { EjbEntityDescriptor.BEAN_PERSISTENCE, descriptor.getName(), persistence })); return result; } } else { result.addNaDetails( smh.getLocalString( "tests.componentNameConstructor", "For [ {0} ]", new Object[] {compName.toString()})); result.notApplicable( smh.getLocalString( getClass().getName() + ".notApplicable", "[ {0} ] expected {1} bean, but called with {2} bean.", new Object[] {getClass(), "Entity", "Session"})); return result; } }
/** * Entity Bean's ejbCreate(...) methods return test. Each entity Bean class may define zero or * more ejbCreate(...) methods. The number and signatures of a entity Bean's create methods are * specific to each EJB class. The method signatures must follow these rules: * * <p>The method name must be ejbCreate. * * <p>The return type must be primary key type. * * @param descriptor the Enterprise Java Bean deployment descriptor * @return <code>Result</code> the results for this assertion */ public Result check(EjbDescriptor descriptor) { Result result = getInitializedResult(); ComponentNameConstructor compName = getVerifierContext().getComponentNameConstructor(); if (descriptor instanceof EjbEntityDescriptor) { String persistence = ((EjbEntityDescriptor) descriptor).getPersistenceType(); if (EjbEntityDescriptor.BEAN_PERSISTENCE.equals(persistence)) { boolean oneFailed = false; boolean oneWarning = false; int foundAtLeastOne = 0; try { Context context = getVerifierContext(); ClassLoader jcl = context.getClassLoader(); Class c = Class.forName( descriptor.getEjbClassName(), false, getVerifierContext().getClassLoader()); String primaryKeyType = ((EjbEntityDescriptor) descriptor).getPrimaryKeyClassName(); boolean ejbCreateFound = false; boolean returnsPrimaryKeyType = false; // start do while loop here.... do { Method[] methods = c.getDeclaredMethods(); for (int i = 0; i < methods.length; i++) { // reset flags from last time thru loop ejbCreateFound = false; returnsPrimaryKeyType = false; // The method name must be ejbCreate. if (methods[i].getName().startsWith("ejbCreate")) { foundAtLeastOne++; ejbCreateFound = true; // The return type must be primary key type. Class rt = methods[i].getReturnType(); if (rt.getName().equals(primaryKeyType)) { returnsPrimaryKeyType = true; } // now display the appropriate results for this particular ejbCreate // method if (ejbCreateFound && !returnsPrimaryKeyType) { if (primaryKeyType.equals("java.lang.Object")) { oneWarning = true; result.addWarningDetails( smh.getLocalString( "tests.componentNameConstructor", "For [ {0} ]", new Object[] {compName.toString()})); result.addWarningDetails( smh.getLocalString( getClass().getName() + ".debug1", "For EJB Class [ {0} ] method [ {1} ]", new Object[] {descriptor.getEjbClassName(), methods[i].getName()})); result.addWarningDetails( smh.getLocalString( getClass().getName() + ".warning", "Warning: An [ {0} ] method was found, but [ {1} ] method has [ {2} ] return type. Deployment descriptor primary key type [ {3} ]. Definition of the primary key type is deferred to deployment time ?", new Object[] { methods[i].getName(), methods[i].getName(), methods[i].getReturnType().getName(), primaryKeyType })); } else { oneFailed = true; result.addErrorDetails( smh.getLocalString( "tests.componentNameConstructor", "For [ {0} ]", new Object[] {compName.toString()})); result.addErrorDetails( smh.getLocalString( getClass().getName() + ".debug1", "For EJB Class [ {0} ] method [ {1} ]", new Object[] {descriptor.getEjbClassName(), methods[i].getName()})); result.addErrorDetails( smh.getLocalString( getClass().getName() + ".failed", "Error: An [ {0} ] method was found, but [ {1} ] method has illegal return value. [ {2} ] methods must return primary key type [ {3} ].", new Object[] { methods[i].getName(), methods[i].getName(), methods[i].getName(), primaryKeyType })); break; } } } } if (oneFailed == true) break; } while (((c = c.getSuperclass()) != null) && (foundAtLeastOne == 0)); if (foundAtLeastOne == 0) { result.addNaDetails( smh.getLocalString( "tests.componentNameConstructor", "For [ {0} ]", new Object[] {compName.toString()})); result.notApplicable( smh.getLocalString( getClass().getName() + ".notApplicable0", "[ {0} ] does not declare any ejbCreate(...) methods.", new Object[] {descriptor.getEjbClassName()})); } if (oneFailed == false && foundAtLeastOne > 0) { result.addGoodDetails( smh.getLocalString( "tests.componentNameConstructor", "For [ {0} ]", new Object[] {compName.toString()})); result.addGoodDetails( smh.getLocalString( getClass().getName() + ".debug1", "For EJB Class [ {0} ]", new Object[] {descriptor.getEjbClassName()})); result.addGoodDetails( smh.getLocalString( getClass().getName() + ".passed", "[ {0} ] properly declares ejbCreate<method> method to return primary key type [ {1} ].", new Object[] {descriptor.getEjbClassName(), primaryKeyType})); } } catch (ClassNotFoundException e) { Verifier.debug(e); result.addErrorDetails( smh.getLocalString( "tests.componentNameConstructor", "For [ {0} ]", new Object[] {compName.toString()})); result.failed( smh.getLocalString( getClass().getName() + ".failedException", "Error: [ {0} ] class not found.", new Object[] {descriptor.getEjbClassName()})); oneFailed = true; } if (oneFailed) { result.setStatus(result.FAILED); } else if (foundAtLeastOne == 0) { result.setStatus(result.NOT_APPLICABLE); } else { if (oneWarning) { result.setStatus(result.WARNING); } else { result.setStatus(result.PASSED); } } return result; } else { // if (CONTAINER_PERSISTENCE.equals(persistence)) { result.addNaDetails( smh.getLocalString( "tests.componentNameConstructor", "For [ {0} ]", new Object[] {compName.toString()})); result.notApplicable( smh.getLocalString( getClass().getName() + ".notApplicable1", "Expected [ {0} ] managed persistence, but [ {1} ] bean has [ {2} ] managed persistence.", new Object[] { EjbEntityDescriptor.BEAN_PERSISTENCE, descriptor.getName(), persistence })); return result; } } else { result.addNaDetails( smh.getLocalString( "tests.componentNameConstructor", "For [ {0} ]", new Object[] {compName.toString()})); result.notApplicable( smh.getLocalString( getClass().getName() + ".notApplicable", "[ {0} ] expected {1} bean, but called with {2} bean.", new Object[] {getClass(), "Entity", "Session"})); return result; } }
/** * Entity bean's Primary Key Class type test. If the enterprise bean is a Entity Bean, the Bean * provider specifies the fully qualified name of the Entity bean's primary key class in the * "primary-class" element. The Bean provider 'must' specify the primary key class for an Entity * with bean managed persistence, and 'may' (but is not required to) specify the primary key class * for an Entity with Container-managed persistence. * * <p>Special case: Unknown primary key class In special situations, the Bean Provider may choose * not to specify the primary key class for an entity bean with container-managed persistence. * This case happens if the Bean Provider wants to allow the Deployer to select the primary key * fields at deployment time. The Deployer uses instructions supplied by the Bean Provider (these * instructions are beyond the scope of the EJB spec.) to define a suitable primary key class. * * <p>In this special case, the type of the argument of the findByPrimaryKey method must be * declared as java.lang.Object, and the return value of ejbCreate() must be declared as * java.lang.Object. The Bean Provider must specify the primary key class in the deployment * descriptor as of the type java.lang.Object. * * <p>The primary key class is specified at deployment time when the Bean Provider develops * enterprise beans that is intended to be used with multiple back-ends that provide persistence, * and when these multiple back-ends require different primary key structures. * * @param descriptor the Enterprise Java Bean deployment descriptor * @return <code>Result</code> the results for this assertion */ public Result check(EjbDescriptor descriptor) { Result result = getInitializedResult(); ComponentNameConstructor compName = getVerifierContext().getComponentNameConstructor(); if (descriptor instanceof EjbEntityDescriptor) { String persistence = ((EjbEntityDescriptor) descriptor).getPersistenceType(); if (EjbEntityDescriptor.CONTAINER_PERSISTENCE.equals(persistence)) { String primkey = ((EjbEntityDescriptor) descriptor).getPrimaryKeyClassName(); // primkey can be not set, via setting xml element // <prim-key-class> to "java.lang.Object" if (primkey.equals("java.lang.Object")) { result.addGoodDetails( smh.getLocalString( "tests.componentNameConstructor", "For [ {0} ]", new Object[] {compName.toString()})); result.passed( smh.getLocalString( getClass().getName() + ".passed", "Properly defined primary key class type [ {0} ]", new Object[] {"java.lang.Object"})); } else { result.addNaDetails( smh.getLocalString( "tests.componentNameConstructor", "For [ {0} ]", new Object[] {compName.toString()})); result.notApplicable( smh.getLocalString( getClass().getName() + ".notApplicable1", "Primary Key Class is [ {0} ]", new Object[] {primkey})); } return result; } else if (EjbEntityDescriptor.BEAN_PERSISTENCE.equals(persistence)) { result.addNaDetails( smh.getLocalString( "tests.componentNameConstructor", "For [ {0} ]", new Object[] {compName.toString()})); result.notApplicable( smh.getLocalString( getClass().getName() + ".notApplicable2", "Entity Bean with [ {0} ] managed persistence, primkey mandatory.", new Object[] {persistence})); return result; } else { result.addNaDetails( smh.getLocalString( "tests.componentNameConstructor", "For [ {0} ]", new Object[] {compName.toString()})); result.notApplicable( smh.getLocalString( getClass().getName() + ".notApplicable3", "Expected [ {0} ] managed persistence, but [ {1} ] bean has [ {2} ] managed persistence.", new Object[] { EjbEntityDescriptor.CONTAINER_PERSISTENCE, descriptor.getName(), persistence })); return result; } } else { result.addNaDetails( smh.getLocalString( "tests.componentNameConstructor", "For [ {0} ]", new Object[] {compName.toString()})); result.notApplicable( smh.getLocalString( getClass().getName() + ".notApplicable", "[ {0} ] expected {1} bean, but called with {2} bean.", new Object[] {getClass(), "Entity", "Session"})); return result; } }
/** * Define ejbFindByPrimaryKey method arguments test. * * <p>Every entity enterprise Bean class must define the ejbFindByPrimaryKey method. * * <p>The methods arguments types must be legal types for RMI-IIOP. * * @param descriptor the Enterprise Java Bean deployment descriptor * @return <code>Result</code> the results for this assertion */ public Result check(EjbDescriptor descriptor) { Result result = getInitializedResult(); ComponentNameConstructor compName = getVerifierContext().getComponentNameConstructor(); if (descriptor instanceof EjbEntityDescriptor) { String persistentType = ((EjbEntityDescriptor) descriptor).getPersistenceType(); if (EjbEntityDescriptor.BEAN_PERSISTENCE.equals(persistentType)) { Class[] ejbFinderMethodParameterTypes; boolean ejbFindByPrimaryKeyMethodFound = false; boolean oneFailed = false; boolean isLegalRMIIIOP = false; try { // retrieve the EJB Class Methods Context context = getVerifierContext(); ClassLoader jcl = context.getClassLoader(); Class EJBClass = Class.forName( descriptor.getEjbClassName(), false, getVerifierContext().getClassLoader()); // start do while loop here.... do { Method[] ejbFinderMethods = EJBClass.getDeclaredMethods(); for (int j = 0; j < ejbFinderMethods.length; ++j) { if (ejbFinderMethods[j].getName().equals("ejbFindByPrimaryKey")) { // Every entity enterprise Bean class must define the // ejbFindByPrimaryKey method. ejbFindByPrimaryKeyMethodFound = true; // The methods arguments types must be legal types for RMI-IIOP. ejbFinderMethodParameterTypes = ejbFinderMethods[j].getParameterTypes(); if (RmiIIOPUtils.isValidRmiIIOPParameters(ejbFinderMethodParameterTypes)) { // these method parameters are valid, continue isLegalRMIIIOP = true; } if (ejbFindByPrimaryKeyMethodFound && isLegalRMIIIOP) { result.addGoodDetails( smh.getLocalString( "tests.componentNameConstructor", "For [ {0} ]", new Object[] {compName.toString()})); result.addGoodDetails( smh.getLocalString( getClass().getName() + ".debug1", "For EJB Class [ {0} ] Finder Method [ {1} ]", new Object[] {EJBClass.getName(), ejbFinderMethods[j].getName()})); result.addGoodDetails( smh.getLocalString( getClass().getName() + ".passed", "An [ {0} ] method with valid RMI-IIOP argument types was found.", new Object[] {ejbFinderMethods[j].getName()})); } else if (ejbFindByPrimaryKeyMethodFound && (!isLegalRMIIIOP)) { oneFailed = true; result.addErrorDetails( smh.getLocalString( "tests.componentNameConstructor", "For [ {0} ]", new Object[] {compName.toString()})); result.addErrorDetails( smh.getLocalString( getClass().getName() + ".debug1", "For EJB Class [ {0} ] Finder Method [ {1} ]", new Object[] {EJBClass.getName(), ejbFinderMethods[j].getName()})); result.addErrorDetails( smh.getLocalString( getClass().getName() + ".failed", "Error: An [ {0} ] method was found, but [ {1} ] method has illegal parameter values. [ {2} ] methods arguments types must be legal types for RMI-IIOP.", new Object[] { ejbFinderMethods[j].getName(), ejbFinderMethods[j].getName(), ejbFinderMethods[j].getName() })); } // found one, and there should only be one, break out break; } } } while (((EJBClass = EJBClass.getSuperclass()) != null) && (!ejbFindByPrimaryKeyMethodFound)); if (!ejbFindByPrimaryKeyMethodFound) { oneFailed = true; result.addErrorDetails( smh.getLocalString( "tests.componentNameConstructor", "For [ {0} ]", new Object[] {compName.toString()})); result.addErrorDetails( smh.getLocalString( getClass().getName() + ".debug3", "For EJB Class [ {0} ]", new Object[] {descriptor.getEjbClassName()})); result.addErrorDetails( smh.getLocalString( getClass().getName() + ".failed1", "Error: No ejbFindByPrimaryKey method was found in bean class.")); } } catch (ClassNotFoundException e) { Verifier.debug(e); result.addErrorDetails( smh.getLocalString( "tests.componentNameConstructor", "For [ {0} ]", new Object[] {compName.toString()})); result.failed( smh.getLocalString( getClass().getName() + ".failedException", "Error: EJB Class [ {0} ] does not exist or is not loadable.", new Object[] {descriptor.getEjbClassName()})); oneFailed = true; } if (oneFailed) { result.setStatus(result.FAILED); } else { result.setStatus(result.PASSED); } } else { // (CONTAINER_PERSISTENCE.equals(persistentType)) result.addNaDetails( smh.getLocalString( "tests.componentNameConstructor", "For [ {0} ]", new Object[] {compName.toString()})); result.notApplicable( smh.getLocalString( getClass().getName() + ".notApplicable2", "Expected persistence type [ {0} ], but bean [ {1} ] has persistence type [ {2} ]", new Object[] { EjbEntityDescriptor.BEAN_PERSISTENCE, descriptor.getName(), persistentType })); } return result; } else { result.addNaDetails( smh.getLocalString( "tests.componentNameConstructor", "For [ {0} ]", new Object[] {compName.toString()})); result.notApplicable( smh.getLocalString( getClass().getName() + ".notApplicable", "[ {0} ] expected {1} bean, but called with {2} bean.", new Object[] {getClass(), "Entity", "Session"})); return result; } }
/** * run an individual home method test * * @param method the home method to test * @param descriptor the deployment descriptor for the entity bean * @param result the result object */ protected void runIndividualHomeMethodTest( Method method, EjbDescriptor descriptor, Result result) { Method m; ComponentNameConstructor compName = getVerifierContext().getComponentNameConstructor(); try { // retrieve the remote interface methods ClassLoader jcl = getVerifierContext().getClassLoader(); Class ejbClass = Class.forName(descriptor.getEjbClassName(), false, jcl); // Bug: 4952890. first character of this name should be converted to UpperCase. String methodName = method .getName() .replaceFirst( method.getName().substring(0, 1), method.getName().substring(0, 1).toUpperCase()); String expectedMethodName = "ejbHome" + methodName; do { // retrieve the EJB Class Methods m = getMethod(ejbClass, expectedMethodName, method.getParameterTypes()); } while (((ejbClass = ejbClass.getSuperclass()) != null) && (m == null)); if (m != null) { int modifiers = m.getModifiers(); if (Modifier.isPublic(modifiers) && !Modifier.isStatic(modifiers)) { addGoodDetails(result, compName); result.addGoodDetails( smh.getLocalString( getClass().getName() + ".passed", "For method [ {1} ] in Home Interface [ {0} ], ejbHome method is public and not static", new Object[] {method.getDeclaringClass().getName(), method.getName()})); result.setStatus(Result.PASSED); // return true; } else { addErrorDetails(result, compName); result.addErrorDetails( smh.getLocalString( getClass().getName() + ".notApplicable", "Error : For method [ {1} ] defined in Home Interface [ {0} ], the ejbHome method is either static or not public", new Object[] {method.getDeclaringClass().getName(), method.getName()})); result.setStatus(Result.FAILED); // return false; } } else { addErrorDetails(result, compName); result.addErrorDetails( smh.getLocalString( getClass().getName() + ".failed", "Error : For method [ {1} ] defined in Home Interface [ {0} ], no ejbHome name matching method was found", new Object[] {method.getDeclaringClass().getName(), method.getName()})); result.setStatus(Result.FAILED); // return true; } } catch (ClassNotFoundException e) { Verifier.debug(e); addErrorDetails(result, compName); result.failed( smh.getLocalString( getClass().getName() + ".failedException", "Error: Home interface [ {0} ] does not exist or is not loadable within bean [ {1} ]", new Object[] {getClassName(descriptor), descriptor.getName()})); // return false; result.setStatus(Result.FAILED); } }
@Override public HandlerProcessingResult processAnnotation(AnnotationInfo annInfo) throws AnnotationProcessorException { AnnotatedElementHandler annCtx = annInfo.getProcessingContext().getHandler(); AnnotatedElement annElem = annInfo.getAnnotatedElement(); AnnotatedElement origAnnElem = annElem; boolean ejbInWar = ignoreWebserviceAnnotations(annElem, annCtx); // Bug http://monaco.sfbay/detail.jsf?cr=6956406 // When there is an ejb webservice packaged in a war // ignore the annotation processing for WebBundleDescriptor // In Ejb webservice in a war there are 2 bundle descriptors // so we should just allow the processing for the EjbBundleDescriptor // and add webservices to that BundleDescriptor if (ejbInWar) { return HandlerProcessingResultImpl.getDefaultResult( getAnnotationType(), ResultType.PROCESSED); } // sanity check if (!(annElem instanceof Class)) { AnnotationProcessorException ape = new AnnotationProcessorException( wsLocalStrings.getLocalString( "enterprise.deployment.annotation.handlers.wrongannotationlocation", "WS00022: symbol annotation can only be specified on TYPE"), annInfo); annInfo.getProcessingContext().getErrorHandler().error(ape); return HandlerProcessingResultImpl.getDefaultResult(getAnnotationType(), ResultType.FAILED); } // Ignore @WebService annotation on an interface; process only those in an actual service impl // class if (((Class) annElem).isInterface()) { return HandlerProcessingResultImpl.getDefaultResult( getAnnotationType(), ResultType.PROCESSED); } if (isJaxwsRIDeployment(annInfo)) { // Looks like JAX-WS RI specific deployment, do not process Web Service annotations otherwise // would end up as two web service endpoints conLogger.log( Level.INFO, LogUtils.DEPLOYMENT_DISABLED, new Object[] { annInfo.getProcessingContext().getArchive().getName(), "WEB-INF/sun-jaxws.xml" }); return HandlerProcessingResultImpl.getDefaultResult( getAnnotationType(), ResultType.PROCESSED); } // let's get the main annotation of interest. javax.jws.WebService ann = (javax.jws.WebService) annInfo.getAnnotation(); BundleDescriptor bundleDesc = null; // Ensure that an EJB endpoint is packaged in EJBJAR and a servlet endpoint is packaged in a WAR try { /* TODO These conditions will change since ejb in war will be supported //uncomment if needed if(annCtx instanceof EjbContext && (provider !=null) && (provider.getType("javax.ejb.Stateless") == null)) { AnnotationProcessorException ape = new AnnotationProcessorException( localStrings.getLocalString("enterprise.deployment.annotation.handlers.webeppkgwrong", "Class {0} is annotated with @WebService and without @Stateless but is packaged in a JAR." + " If it is supposed to be a servlet endpoint, it should be packaged in a WAR; Deployment will continue assuming this " + "class to be just a POJO used by other classes in the JAR being deployed", new Object[] {((Class)annElem).getName()}),annInfo); ape.setFatal(false); throw ape; } if(annCtx instanceof EjbBundleContext && (provider !=null) && (provider.getType("javax.ejb.Stateless") == null)) { AnnotationProcessorException ape = new AnnotationProcessorException( localStrings.getLocalString ("enterprise.deployment.annotation.handlers.webeppkgwrong", "Class {0} is annotated with @WebService and without @Stateless but is packaged in a JAR." + " If it is supposed to be a servlet endpoint, it should be packaged in a WAR; Deployment will continue assuming this " + "class to be just a POJO used by other classes in the JARbeing deployed", new Object[] {((Class)annElem).getName()}),annInfo); ape.setFatal(false); throw ape; } if(annCtx instanceof WebBundleContext && (provider !=null) && (provider.getType("javax.ejb.Stateless") != null)) { AnnotationProcessorException ape = new AnnotationProcessorException( localStrings.getLocalString ("enterprise.deployment.annotation.handlers.ejbeppkgwrong", "Class {0} is annotated with @WebService and @Stateless but is packaged in a WAR." +" If it is supposed to be an EJB endpoint, it should be packaged in a JAR; Deployment will continue assuming this " +" class to be just a POJO used by other classes in the WAR being deployed", new Object[] {((Class)annElem).getName()}),annInfo); ape.setFatal(false); throw ape; }*/ // let's see the type of web service we are dealing with... if ((ejbProvider != null) && ejbProvider.getType("javax.ejb.Stateless") != null && (annCtx instanceof EjbContext)) { // this is an ejb ! EjbContext ctx = (EjbContext) annCtx; bundleDesc = ctx.getDescriptor().getEjbBundleDescriptor(); bundleDesc.setSpecVersion("3.0"); } else { // this has to be a servlet since there is no @Servlet annotation yet if (annCtx instanceof WebComponentContext) { bundleDesc = ((WebComponentContext) annCtx).getDescriptor().getWebBundleDescriptor(); } else if (!(annCtx instanceof WebBundleContext)) { return getInvalidAnnotatedElementHandlerResult( annInfo.getProcessingContext().getHandler(), annInfo); } bundleDesc = ((WebBundleContext) annCtx).getDescriptor(); bundleDesc.setSpecVersion("2.5"); } } catch (Exception e) { throw new AnnotationProcessorException( wsLocalStrings.getLocalString( "webservice.annotation.exception", "WS00023: Exception in processing @Webservice : {0}", e.getMessage())); } // WebService.name in the impl class identifies port-component-name // If this is specified in impl class, then that takes precedence String portComponentName = ann.name(); // As per JSR181, the serviceName is either specified in the deployment descriptor // or in @WebSErvice annotation in impl class; if neither service name implclass+Service String svcNameFromImplClass = ann.serviceName(); String implClassName = ((Class) annElem).getSimpleName(); String implClassFullName = ((Class) annElem).getName(); // In case user gives targetNameSpace in the Impl class, that has to be used as // the namespace for service, port; typically user will do this in cases where // port_types reside in a different namespace than that of server/port. // Store the targetNameSpace, if any, in the impl class for later use String targetNameSpace = ann.targetNamespace(); // As per JSR181, the portName is either specified in deployment desc or in @WebService // in impl class; if neither, it will @WebService.name+Port; if @WebService.name is not there, // then port name is implClass+Port String portNameFromImplClass = ann.portName(); if ((portNameFromImplClass == null) || (portNameFromImplClass.length() == 0)) { if ((portComponentName != null) && (portComponentName.length() != 0)) { portNameFromImplClass = portComponentName + "Port"; } else { portNameFromImplClass = implClassName + "Port"; } } // Store binding type specified in Impl class String userSpecifiedBinding = null; javax.xml.ws.BindingType bindingAnn = (javax.xml.ws.BindingType) ((Class) annElem).getAnnotation(javax.xml.ws.BindingType.class); if (bindingAnn != null) { userSpecifiedBinding = bindingAnn.value(); } // Store wsdlLocation in the impl class (if any) String wsdlLocation = null; if (ann.wsdlLocation() != null && ann.wsdlLocation().length() != 0) { wsdlLocation = ann.wsdlLocation(); } // At this point, we need to check if the @WebService points to an SEI // with the endpointInterface attribute, if that is the case, the // remaining attributes should be extracted from the SEI instead of SIB. if (ann.endpointInterface() != null && ann.endpointInterface().length() > 0) { Class endpointIntf; try { endpointIntf = ((Class) annElem).getClassLoader().loadClass(ann.endpointInterface()); } catch (java.lang.ClassNotFoundException cfne) { throw new AnnotationProcessorException( localStrings.getLocalString( "enterprise.deployment.annotation.handlers.classnotfound", "class {0} referenced from annotation symbol cannot be loaded", new Object[] {ann.endpointInterface()}), annInfo); } annElem = endpointIntf; ann = annElem.getAnnotation(javax.jws.WebService.class); if (ann == null) { throw new AnnotationProcessorException( wsLocalStrings.getLocalString( "no.webservice.annotation", "WS00025: SEI {0} referenced from the @WebService annotation on {1} does not contain a @WebService annotation", ((javax.jws.WebService) annInfo.getAnnotation()).endpointInterface(), ((Class) annElem).getName())); } // SEI cannot have @BindingType if (annElem.getAnnotation(javax.xml.ws.BindingType.class) != null) { throw new AnnotationProcessorException( wsLocalStrings.getLocalString( "cannot.have.bindingtype", "WS00026: SEI {0} cannot have @BindingType", ((javax.jws.WebService) annInfo.getAnnotation()).endpointInterface())); } } WebServicesDescriptor wsDesc = bundleDesc.getWebServices(); // WebService.name not found; as per 109, default port-component-name // is the simple class name as long as the simple class name will be a // unique port-component-name for this module if (portComponentName == null || portComponentName.length() == 0) { portComponentName = implClassName; } // Check if this port-component-name is unique for this module WebServiceEndpoint wep = wsDesc.getEndpointByName(portComponentName); if (wep != null) { // there is another port-component by this name in this module; // now we have to look at the SEI/impl of that port-component; if that SEI/impl // is the same as the current SEI/impl then it means we have to override values; // If the SEI/impl classes do not match, then no overriding should happen; we should // use fully qualified class name as port-component-name for the current endpoint if ((wep.getServiceEndpointInterface() != null) && (wep.getServiceEndpointInterface().length() != 0) && (!((Class) annElem).getName().equals(wep.getServiceEndpointInterface()))) { portComponentName = implClassFullName; } } // Check if the same endpoint is already defined in webservices.xml // This has to be done again after applying the 109 rules as above // for port-component-name WebServiceEndpoint endpoint = wsDesc.getEndpointByName(portComponentName); WebService newWS; if (endpoint == null) { if (DOLUtils.warType().equals(bundleDesc.getModuleType())) { // http://java.net/jira/browse/GLASSFISH-17204 WebComponentDescriptor[] wcByImplName = ((WebBundleDescriptor) bundleDesc).getWebComponentByImplName(implClassFullName); for (WebComponentDescriptor wc : wcByImplName) { if (!wsDesc.getEndpointsImplementedBy(wc).isEmpty()) { // URL mapping for annotated service exists - it can be JAX-RPC service // as well as some servlet or maybe only invalid port-component-name, // so let user know about possible error logger.log( Level.SEVERE, LogUtils.WS_URLMAPPING_EXISTS, new Object[] {implClassFullName}); break; } } } // Check if a service with the same name is already present // If so, add this endpoint to the existing service if (svcNameFromImplClass != null && svcNameFromImplClass.length() != 0) { newWS = wsDesc.getWebServiceByName(svcNameFromImplClass); } else { newWS = wsDesc.getWebServiceByName(implClassName + "Service"); } if (newWS == null) { newWS = new WebService(); // service name from annotation if (svcNameFromImplClass != null && svcNameFromImplClass.length() != 0) { newWS.setName(svcNameFromImplClass); } else { newWS.setName(implClassName + "Service"); } wsDesc.addWebService(newWS); } endpoint = new WebServiceEndpoint(); if (portComponentName != null && portComponentName.length() != 0) { endpoint.setEndpointName(portComponentName); } else { endpoint.setEndpointName(((Class) annElem).getName()); } newWS.addEndpoint(endpoint); wsDesc.setSpecVersion(WebServicesDescriptorNode.SPEC_VERSION); } else { newWS = endpoint.getWebService(); } // If wsdl-service is specified in the descriptor, then the targetnamespace // in wsdl-service should match the @WebService.targetNameSpace, if any. // make that assertion here - and the targetnamespace in wsdl-service, if // present overrides everything else if (endpoint.getWsdlService() != null) { if ((targetNameSpace != null) && (targetNameSpace.length() != 0) && (!endpoint.getWsdlService().getNamespaceURI().equals(targetNameSpace))) { AnnotationProcessorException ape = new AnnotationProcessorException( wsLocalStrings.getLocalString( "mismatch.targetnamespace", "WS00027: Target Namespace in wsdl-service element does not match @WebService.targetNamespace"), annInfo); annInfo.getProcessingContext().getErrorHandler().error(ape); return HandlerProcessingResultImpl.getDefaultResult(getAnnotationType(), ResultType.FAILED); } targetNameSpace = endpoint.getWsdlService().getNamespaceURI(); } // Service and port should reside in the same namespace - assert that if ((endpoint.getWsdlService() != null) && (endpoint.getWsdlPort() != null)) { if (!endpoint .getWsdlService() .getNamespaceURI() .equals(endpoint.getWsdlPort().getNamespaceURI())) { AnnotationProcessorException ape = new AnnotationProcessorException( wsLocalStrings.getLocalString( "mismatch.port.targetnamespace", "WS00028: Target Namespace for wsdl-service and wsdl-port should be the same"), annInfo); annInfo.getProcessingContext().getErrorHandler().error(ape); return HandlerProcessingResultImpl.getDefaultResult(getAnnotationType(), ResultType.FAILED); } } // Use annotated values only if the deployment descriptor equivalen has not been specified // If wsdlLocation was not given in Impl class, see if it is present in SEI // Set this in DOL if there is no Depl Desc entry // Precedence given for wsdlLocation in impl class if (newWS.getWsdlFileUri() == null) { if (wsdlLocation != null) { newWS.setWsdlFileUri(wsdlLocation); } else { if (ann.wsdlLocation() != null && ann.wsdlLocation().length() != 0) { newWS.setWsdlFileUri(ann.wsdlLocation()); } } } // Set binding id id @BindingType is specified by the user in the impl class if ((!endpoint.hasUserSpecifiedProtocolBinding()) && (userSpecifiedBinding != null) && (userSpecifiedBinding.length() != 0)) { endpoint.setProtocolBinding(userSpecifiedBinding); } if (endpoint.getServiceEndpointInterface() == null) { // take SEI from annotation if (ann.endpointInterface() != null && ann.endpointInterface().length() != 0) { endpoint.setServiceEndpointInterface(ann.endpointInterface()); } else { endpoint.setServiceEndpointInterface(((Class) annElem).getName()); } } // at this point the SIB has to be used no matter what @WebService was used. annElem = annInfo.getAnnotatedElement(); if (DOLUtils.warType().equals(bundleDesc.getModuleType())) { if (endpoint.getServletImplClass() == null) { // Set servlet impl class here endpoint.setServletImplClass(((Class) annElem).getName()); } // Servlet link name WebBundleDescriptor webBundle = (WebBundleDescriptor) bundleDesc; if (endpoint.getWebComponentLink() == null) { // <servlet-link> = fully qualified name of the implementation class endpoint.setWebComponentLink(implClassFullName); } if (endpoint.getWebComponentImpl() == null) { WebComponentDescriptor webComponent = (WebComponentDescriptor) webBundle.getWebComponentByCanonicalName(endpoint.getWebComponentLink()); if (webComponent == null) { // GLASSFISH-3297 WebComponentDescriptor[] wcs = webBundle.getWebComponentByImplName(implClassFullName); if (wcs.length > 0) { webComponent = wcs[0]; } } // if servlet is not known, we should add it now if (webComponent == null) { webComponent = new WebComponentDescriptorImpl(); webComponent.setServlet(true); webComponent.setWebComponentImplementation(((Class) annElem).getCanonicalName()); webComponent.setName(endpoint.getEndpointName()); webComponent.addUrlPattern("/" + newWS.getName()); webBundle.addWebComponentDescriptor(webComponent); } endpoint.setWebComponentImpl(webComponent); } } else { // TODO BM handle stateless Stateless stateless = null; try { stateless = annElem.getAnnotation(javax.ejb.Stateless.class); } catch (Exception e) { if (logger.isLoggable(Level.FINE)) { // This can happen in the web.zip installation where there is no ejb // Just logging the error conLogger.log(Level.FINE, LogUtils.EXCEPTION_THROWN, e); } } Singleton singleton = null; try { singleton = annElem.getAnnotation(javax.ejb.Singleton.class); } catch (Exception e) { if (logger.isLoggable(Level.FINE)) { // This can happen in the web.zip installation where there is no ejb // Just logging the error conLogger.log(Level.FINE, LogUtils.EXCEPTION_THROWN, e); } } String name; if ((stateless != null) && ((stateless).name() == null || stateless.name().length() > 0)) { name = stateless.name(); } else if ((singleton != null) && ((singleton).name() == null || singleton.name().length() > 0)) { name = singleton.name(); } else { name = ((Class) annElem).getSimpleName(); } EjbDescriptor ejb = ((EjbBundleDescriptor) bundleDesc).getEjbByName(name); endpoint.setEjbComponentImpl(ejb); ejb.setWebServiceEndpointInterfaceName(endpoint.getServiceEndpointInterface()); if (endpoint.getEjbLink() == null) endpoint.setEjbLink(ejb.getName()); } if (endpoint.getWsdlPort() == null) { // Use targetNameSpace given in wsdl-service/Impl class for port and service // If none, derive the namespace from package name and this will be used for // service and port - targetNamespace, if any, in SEI will be used for pprtType // during wsgen phase if (targetNameSpace == null || targetNameSpace.length() == 0) { // No targerNameSpace anywhere; calculate targetNameSpace and set wsdl port // per jax-ws 2.0 spec, the target name is the package name in // the reverse order prepended with http:// if (((Class) annElem).getPackage() != null) { StringTokenizer tokens = new StringTokenizer(((Class) annElem).getPackage().getName(), ".", false); if (tokens.hasMoreElements()) { while (tokens.hasMoreElements()) { if (targetNameSpace == null || targetNameSpace.length() == 0) { targetNameSpace = tokens.nextElement().toString(); } else { targetNameSpace = tokens.nextElement().toString() + "." + targetNameSpace; } } } else { targetNameSpace = ((Class) annElem).getPackage().getName(); } } else { throw new AnnotationProcessorException( wsLocalStrings.getLocalString( "missing.targetnamespace", "WS00029: The javax.jws.WebService annotation targetNamespace must be used for classes or interfaces that are in no package")); } targetNameSpace = "http://" + (targetNameSpace == null ? "" : targetNameSpace + "/"); } // WebService.portName = wsdl-port endpoint.setWsdlPort(new QName(targetNameSpace, portNameFromImplClass, "ns1")); } if (endpoint.getWsdlService() == null) { // Set wsdl-service properly; namespace is the same as that of wsdl port; // service name derived from deployment desc / annotation / default String serviceNameSpace = endpoint.getWsdlPort().getNamespaceURI(); String serviceName = null; if ((svcNameFromImplClass != null) && (svcNameFromImplClass.length() != 0)) { // Use the serviceName annotation if available serviceName = svcNameFromImplClass; } else { serviceName = newWS.getName(); } endpoint.setWsdlService(new QName(serviceNameSpace, serviceName, "ns1")); } // Now force a HandlerChain annotation processing // This is to take care of the case where the endpoint Impl class does not // have @HandlerChain but the SEI has one specified through JAXWS customization if ((((Class) origAnnElem).getAnnotation(javax.jws.HandlerChain.class)) == null) { return (new HandlerChainHandler()) .processHandlerChainAnnotation(annInfo, annCtx, origAnnElem, (Class) origAnnElem, true); } return HandlerProcessingResultImpl.getDefaultResult(getAnnotationType(), ResultType.PROCESSED); }