/******************************************************************************* * Copyright (c) 2010 Red Hat, Inc. * Distributed under license by Red Hat, Inc. All rights reserved. * This program is made available under the terms of the * Eclipse Public License v1.0 which accompanies this distribution, * and is available at http://www.eclipse.org/legal/epl-v10.html * * Contributors: * Red Hat, Inc. - initial API and implementation ******************************************************************************/ package org.jboss.tools.cdi.core.test.tck.validation; import java.text.MessageFormat; import java.util.Collection; import java.util.HashSet; import java.util.Set; import org.eclipse.core.resources.IFile; import org.jboss.tools.cdi.core.IBean; import org.jboss.tools.cdi.core.IInjectionPointField; import org.jboss.tools.cdi.core.IInjectionPointParameter; import org.jboss.tools.cdi.internal.core.validation.CDIValidationMessages; /** * @author Alexey Kazakov */ public class DeploymentProblemsValidationTests extends ValidationTest { /** * 5.1.3. Inconsistent specialization * - Suppose an enabled bean X specializes a second bean Y. If there is another enabled bean that specializes Y we say that inconsistent * specialization exists. The container automatically detects inconsistent specialization and treats it as a deployment problem. * * @throws Exception */ public void testInconsistentSpecialization() throws Exception { IFile file = tckProject.getFile("JavaSource/org/jboss/jsr299/tck/tests/inheritance/specialization/simple/broken/inconsistent/Maid.java"); getAnnotationTest().assertAnnotationIsCreated(file, MessageFormat.format(CDIValidationMessages.INCONSISTENT_SPECIALIZATION[getVersionIndex()], "Maid, Manager", "Employee"), 21); file = tckProject.getFile("JavaSource/org/jboss/jsr299/tck/tests/inheritance/specialization/simple/broken/inconsistent/Manager.java"); getAnnotationTest().assertAnnotationIsCreated(file, MessageFormat.format(CDIValidationMessages.INCONSISTENT_SPECIALIZATION[getVersionIndex()], "Manager, Maid", "Employee"), 21); } /** * 5.2.1. Unsatisfied and ambiguous dependencies * - If an unresolvable ambiguous dependency exists, the container automatically detects the problem and treats it as a deployment problem. * * @throws Exception */ public void testAmbiguousDependency() throws Exception { IFile file = tckProject.getFile("JavaSource/org/jboss/jsr299/tck/tests/lookup/dependency/resolution/broken/ambiguous/Farm_Broken.java"); getAnnotationTest().assertAnnotationIsCreated(file, CDIValidationMessages.AMBIGUOUS_INJECTION_POINTS[getVersionIndex()], 25); file = tckProject.getFile("JavaSource/org/jboss/jsr299/tck/tests/decorators/definition/inject/delegateField/TimestampLogger.java"); getAnnotationTest().assertAnnotationIsNotCreated(file, CDIValidationMessages.AMBIGUOUS_INJECTION_POINTS[getVersionIndex()], 34); } public void testAmbiguousDependencyWithNamed() throws Exception { String path = "JavaSource/org/jboss/jsr299/tck/tests/jbt/lookup/duplicateName/TestNamed.java"; IFile file = tckProject.getFile(path); getAnnotationTest().assertAnnotationIsCreated(file, CDIValidationMessages.AMBIGUOUS_INJECTION_POINTS[getVersionIndex()], 9, 25, 26); IInjectionPointField p = getInjectionPointField(path, "s5"); Collection<IBean> bs = cdiProject.getBeans(false, p); assertEquals(3, bs.size()); Set<String> keys = new HashSet<String>(); for(IBean b: bs) { keys.add(b.getElementName()); } assertTrue(!keys.contains("TestNamed.foo4")); assertTrue(keys.contains("TestNamed.foo4()")); assertTrue(keys.contains("TestNamed.foo5()")); assertTrue(keys.contains("TestNamed.foo6()")); IInjectionPointParameter pp = getInjectionPointParameter(path, "doSmth"); Collection<IBean> bs2 = cdiProject.getBeans(false, pp); assertEquals(3, bs2.size()); bs2.removeAll(bs); assertTrue(bs2.isEmpty()); } /** * 5.2.1. Unsatisfied and ambiguous dependencies * - If an unsatisfied dependency exists, the container automatically detects the problem and treats it as a deployment problem. * * @throws Exception */ public void testUnsatisfiedDependency() throws Exception { IFile file = tckProject.getFile("JavaSource/org/jboss/jsr299/tck/tests/lookup/dependency/resolution/broken/unsatisfied/Bean_Broken.java"); getAnnotationTest().assertAnnotationIsCreated(file, CDIValidationMessages.UNSATISFIED_INJECTION_POINTS[getVersionIndex()], 25); file = tckProject.getFile("JavaSource/org/jboss/jsr299/tck/tests/decorators/definition/inject/delegateField/TimestampLogger.java"); getAnnotationTest().assertAnnotationIsNotCreated(file, CDIValidationMessages.UNSATISFIED_INJECTION_POINTS[getVersionIndex()], 34); } public void testUnsatisfiedDependencyWithNamed() throws Exception { IFile file = tckProject.getFile("JavaSource/org/jboss/jsr299/tck/tests/jbt/lookup/duplicateName/TestNamed.java"); getAnnotationTest().assertAnnotationIsCreated(file, CDIValidationMessages.UNSATISFIED_INJECTION_POINTS[getVersionIndex()], 22, 23, 19, 20); int[] lines = {10, 11, 13, 14, 16, 17}; for (int i: lines) { getAnnotationTest().assertAnnotationIsNotCreated(file, CDIValidationMessages.UNSATISFIED_INJECTION_POINTS[getVersionIndex()], i); } } /** * CDI validator should not complain if there ambiguous dependencies for @Inject Instance<[type]> * See https://issues.jboss.org/browse/JBIDE-7949 * * @throws Exception */ public void testAmbiguousDependencyForInstance() throws Exception { IFile file = tckProject.getFile("JavaSource/org/jboss/jsr299/tck/tests/jbt/resolution/InjectionInstance.java"); getAnnotationTest().assertAnnotationIsNotCreated(file, CDIValidationMessages.AMBIGUOUS_INJECTION_POINTS[getVersionIndex()], 8); getAnnotationTest().assertAnnotationIsCreated(file, CDIValidationMessages.AMBIGUOUS_INJECTION_POINTS[getVersionIndex()], 11); } /** * CDI validator should not complain if there unsatisfied dependencies for @Inject Instance<[type]> * See https://issues.jboss.org/browse/JBIDE-7949 * * @throws Exception */ public void testUnsatisfiedDependencyForInstance() throws Exception { IFile file = tckProject.getFile("JavaSource/org/jboss/jsr299/tck/tests/jbt/resolution/InjectionInstance.java"); getAnnotationTest().assertAnnotationIsNotCreated(file, CDIValidationMessages.UNSATISFIED_INJECTION_POINTS[getVersionIndex()], 9); getAnnotationTest().assertAnnotationIsCreated(file, CDIValidationMessages.UNSATISFIED_INJECTION_POINTS[getVersionIndex()], 12); } /** * https://issues.jboss.org/browse/JBIDE-7967 * * @throws Exception */ public void testBeansWithDefaultCounstructor() throws Exception { IFile file = tckProject.getFile("JavaSource/org/jboss/jsr299/tck/tests/jbt/resolution/defaultconstructors/CurrentProject.java"); getAnnotationTest().assertAnnotationIsNotCreated(file, CDIValidationMessages.AMBIGUOUS_INJECTION_POINTS[getVersionIndex()], 12); getAnnotationTest().assertAnnotationIsNotCreated(file, CDIValidationMessages.UNSATISFIED_INJECTION_POINTS[getVersionIndex()], 12); getAnnotationTest().assertAnnotationIsCreated(file, CDIValidationMessages.AMBIGUOUS_INJECTION_POINTS[getVersionIndex()], 15); } /** * 5.2.4. Primitive types and null values * - injection point of primitive type resolves to a bean that may have null values, such as a producer method with a non-primitive return type or a producer field with a non-primitive type * * @throws Exception */ public void testPrimitiveInjectionPointResolvedToNonPrimitiveProducerMethod() throws Exception { IFile file = tckProject.getFile("JavaSource/org/jboss/jsr299/tck/tests/jbt/validation/inject/GameBroken.java"); getAnnotationTest().assertAnnotationIsCreated(file, CDIValidationMessages.INJECT_RESOLVES_TO_NULLABLE_BEAN[getVersionIndex()], 7, 19); getAnnotationTest().assertAnnotationIsNotCreated(file, CDIValidationMessages.INJECT_RESOLVES_TO_NULLABLE_BEAN[getVersionIndex()], 9); getAnnotationTest().assertAnnotationIsNotCreated(file, CDIValidationMessages.INJECT_RESOLVES_TO_NULLABLE_BEAN[getVersionIndex()], 10); getAnnotationTest().assertAnnotationIsNotCreated(file, CDIValidationMessages.INJECT_RESOLVES_TO_NULLABLE_BEAN[getVersionIndex()], 11); getAnnotationTest().assertAnnotationIsNotCreated(file, CDIValidationMessages.INJECT_RESOLVES_TO_NULLABLE_BEAN[getVersionIndex()], 20); getAnnotationTest().assertAnnotationIsNotCreated(file, CDIValidationMessages.INJECT_RESOLVES_TO_NULLABLE_BEAN[getVersionIndex()], 21); getAnnotationTest().assertAnnotationIsNotCreated(file, CDIValidationMessages.INJECT_RESOLVES_TO_NULLABLE_BEAN[getVersionIndex()], 22); } /** * 5.4.1. Unproxyable bean types * - Array types cannot be proxied by the container. * - If an injection point whose declared type cannot be proxied by the container resolves to a bean with a normal scope, * the container automatically detects the problem and treats it as a deployment problem. * * @throws Exception */ public void testInjectionPointWithArrayType() throws Exception { IFile file = tckProject.getFile("JavaSource/org/jboss/jsr299/tck/tests/jbt/validation/unproxyable/InjectionPointBean_Broken.java"); getAnnotationTest().assertAnnotationIsCreated(file, MessageFormat.format(CDIValidationMessages.UNPROXYABLE_BEAN_ARRAY_TYPE[getVersionIndex()], "TestType[]", "ArrayProducer.produce()"), 6); getAnnotationTest().assertAnnotationIsNotCreated(file, MessageFormat.format(CDIValidationMessages.UNPROXYABLE_BEAN_ARRAY_TYPE[getVersionIndex()], "TestType", "TestType"), 7); getAnnotationTest().assertAnnotationIsNotCreated(file, MessageFormat.format(CDIValidationMessages.UNPROXYABLE_BEAN_ARRAY_TYPE[getVersionIndex()], "TestType[]", "ArrayProducer.produce2()"), 8); } public void testNormalBeanWithArrayType() throws Exception { IFile file = tckProject.getFile("JavaSource/org/jboss/jsr299/tck/tests/jbt/validation/unproxyable/ArrayProducer.java"); getAnnotationTest().assertAnnotationIsCreated(file, MessageFormat.format(CDIValidationMessages.UNPROXYABLE_BEAN_ARRAY_TYPE_2[getVersionIndex()], "TestType[]", "ArrayProducer.produce()"), 8); getAnnotationTest().assertAnnotationIsNotCreated(file, MessageFormat.format(CDIValidationMessages.UNPROXYABLE_BEAN_ARRAY_TYPE_2[getVersionIndex()], "TestType[]", "ArrayProducer.produce2()"), 8); } /** * 5.4.1. Unproxyable bean types * - Primitive types cannot be proxied by the container. * - If an injection point whose declared type cannot be proxied by the container resolves to a bean with a normal scope, * the container automatically detects the problem and treats it as a deployment problem. * * @throws Exception */ public void testInjectionPointWithUnproxyableTypeWhichResolvesToNormalScopedBean() throws Exception { IFile file = tckProject.getFile("JavaSource/org/jboss/jsr299/tck/tests/jbt/validation/unproxyable/Number_Broken.java"); getAnnotationTest().assertAnnotationIsCreated(file, MessageFormat.format(CDIValidationMessages.UNPROXYABLE_BEAN_PRIMITIVE_TYPE[getVersionIndex()], "int", "NumberProducer.produce()"), 9); getAnnotationTest().assertAnnotationIsCreated(file, MessageFormat.format(CDIValidationMessages.UNPROXYABLE_BEAN_PRIMITIVE_TYPE[getVersionIndex()], "long", "NumberProducer.foo"), 13); getAnnotationTest().assertAnnotationIsNotCreated(file, MessageFormat.format(CDIValidationMessages.UNPROXYABLE_BEAN_PRIMITIVE_TYPE[getVersionIndex()], "Short", "NumberProducer.foo2"), 17); getAnnotationTest().assertAnnotationIsNotCreated(file, MessageFormat.format(CDIValidationMessages.UNPROXYABLE_BEAN_PRIMITIVE_TYPE[getVersionIndex()], "boolean", "NumberProducer.foo3"), 21); } public void testNormalScopedBeanWithUnproxyableType() throws Exception { IFile file = tckProject.getFile("JavaSource/org/jboss/jsr299/tck/tests/jbt/validation/unproxyable/NumberProducer.java"); getAnnotationTest().assertAnnotationIsCreated(file, MessageFormat.format(CDIValidationMessages.UNPROXYABLE_BEAN_PRIMITIVE_TYPE_2[getVersionIndex()], "int", "NumberProducer.produce()"), 9); getAnnotationTest().assertAnnotationIsCreated(file, MessageFormat.format(CDIValidationMessages.UNPROXYABLE_BEAN_PRIMITIVE_TYPE_2[getVersionIndex()], "long", "NumberProducer.foo"), 16); getAnnotationTest().assertAnnotationIsNotCreated(file, MessageFormat.format(CDIValidationMessages.UNPROXYABLE_BEAN_PRIMITIVE_TYPE_2[getVersionIndex()], "Short", "NumberProducer.foo2"), 21); getAnnotationTest().assertAnnotationIsNotCreated(file, MessageFormat.format(CDIValidationMessages.UNPROXYABLE_BEAN_PRIMITIVE_TYPE_2[getVersionIndex()], "boolean", "NumberProducer.foo3"), 21); } /** * 5.4.1. Unproxyable bean types * - Classes which don't have a non-private constructor with no parameters cannot be proxied by the container. * - If an injection point whose declared type cannot be proxied by the container resolves to a bean with a normal scope, * the container automatically detects the problem and treats it as a deployment problem. * * @throws Exception */ public void testClassWithPrivateConstructor() throws Exception { IFile file = tckProject.getFile("JavaSource/org/jboss/jsr299/tck/tests/lookup/clientProxy/unproxyable/privateConstructor/InjectionPointBean.java"); getAnnotationTest().assertAnnotationIsCreated(file, MessageFormat.format(CDIValidationMessages.UNPROXYABLE_BEAN_TYPE_WITH_NPC[getVersionIndex()], "Unproxyable_Broken", "Unproxyable_Broken"), 23); getAnnotationTest().assertAnnotationIsNotCreated(file, CDIValidationMessages.UNPROXYABLE_BEAN_TYPE_WITH_NPC[getVersionIndex()].substring(0, 0), 25); } /** * https://issues.jboss.org/browse/JBIDE-8018 * @throws Exception */ public void testClassWithDefaultConstructor() throws Exception { IFile file = tckProject.getFile("JavaSource/org/jboss/jsr299/tck/tests/jbt/validation/unproxyable/Number_Broken.java"); getAnnotationTest().assertAnnotationIsNotCreated(file, MessageFormat.format(CDIValidationMessages.UNPROXYABLE_BEAN_TYPE_WITH_NPC[getVersionIndex()], "BeanWithDefaultConsturctor", "BeanWithDefaultConsturctor"), 24); } /** * 5.4.1. Unproxyable bean types * - Classes which are declared final cannot be proxied by the container. * - If an injection point whose declared type cannot be proxied by the container resolves to a bean with a normal scope, * the container automatically detects the problem and treats it as a deployment problem. * * @throws Exception */ public void testInjectionPointWhichResolvesToNormalScopedFinalBean() throws Exception { IFile file = tckProject.getFile("JavaSource/org/jboss/jsr299/tck/tests/lookup/clientProxy/unproxyable/finalClass/FishFarm.java"); getAnnotationTest().assertAnnotationIsCreated(file, MessageFormat.format(CDIValidationMessages.UNPROXYABLE_BEAN_FINAL_TYPE[getVersionIndex()], "Tuna_Broken", "Tuna_Broken"), 24); getAnnotationTest().assertAnnotationIsNotCreated(file, CDIValidationMessages.UNPROXYABLE_BEAN_FINAL_TYPE[getVersionIndex()].substring(0, 0) + ".*", 26); file = tckProject.getFile("JavaSource/org/jboss/jsr299/tck/tests/lookup/clientProxy/unproxyable/finalClass/Opportunity.java"); getAnnotationTest().assertAnnotationIsCreated(file, MessageFormat.format(CDIValidationMessages.UNPROXYABLE_BEAN_FINAL_TYPE[getVersionIndex()], "String", "Opportunity.t"), 26); } public void testNormalScopedFinalBean() throws Exception { IFile file = tckProject.getFile("JavaSource/org/jboss/jsr299/tck/tests/lookup/clientProxy/unproxyable/finalClass/Tuna_Broken.java"); getAnnotationTest().assertAnnotationIsCreated(file, MessageFormat.format(CDIValidationMessages.UNPROXYABLE_BEAN_FINAL_TYPE_2[getVersionIndex()], "Tuna_Broken", "Tuna_Broken"), 21); file = tckProject.getFile("JavaSource/org/jboss/jsr299/tck/tests/lookup/clientProxy/unproxyable/finalClass/Opportunity.java"); getAnnotationTest().assertAnnotationIsCreated(file, MessageFormat.format(CDIValidationMessages.UNPROXYABLE_BEAN_FINAL_TYPE_2[getVersionIndex()], "String", "Opportunity.t"), 32); } /** * 5.4.1. Unproxyable bean types * - Classes which have final methods cannot be proxied by the container. * - If an injection point whose declared type cannot be proxied by the container resolves to a bean with a normal scope, * the container automatically detects the problem and treats it as a deployment problem. * * @throws Exception */ public void testClassWithFinalMethodCannotBeProxied() throws Exception { IFile file = tckProject.getFile("JavaSource/org/jboss/jsr299/tck/tests/lookup/clientProxy/unproxyable/finalMethod/FishFarm.java"); getAnnotationTest().assertAnnotationIsCreated(file, MessageFormat.format(CDIValidationMessages.UNPROXYABLE_BEAN_TYPE_WITH_FM[getVersionIndex()], "Tuna_Broken", "Tuna_Broken"), 23); getAnnotationTest().assertAnnotationIsNotCreated(file, CDIValidationMessages.UNPROXYABLE_BEAN_TYPE_WITH_FM[getVersionIndex()].substring(0, 0) + ".*", 25); file = tckProject.getFile("JavaSource/org/jboss/jsr299/tck/tests/lookup/clientProxy/unproxyable/finalMethod/Tuna_Broken.java"); getAnnotationTest().assertAnnotationIsCreated(file, MessageFormat.format(CDIValidationMessages.UNPROXYABLE_BEAN_TYPE_WITH_FM_2[getVersionIndex()], "Tuna_Broken", "Tuna_Broken"), 21); } /** * 5.3.1. Ambiguous EL names * - All unresolvable ambiguous EL names are detected by the container when the application is initialized. * Suppose two beans are both available for injection in a certain war, and either: * • the two beans have the same EL name and the name is not resolvable, or * * @throws Exception */ public void testDuplicateNamedBeans() throws Exception { IFile file = tckProject.getFile("JavaSource/org/jboss/jsr299/tck/tests/lookup/byname/duplicateNameResolution/Cod.java"); getAnnotationTest().assertAnnotationIsCreated(file, MessageFormat.format(CDIValidationMessages.DUPLCICATE_EL_NAME[getVersionIndex()], "Cod, Sole"), 21); file = tckProject.getFile("JavaSource/org/jboss/jsr299/tck/tests/lookup/byname/duplicateNameResolution/Sole.java"); getAnnotationTest().assertAnnotationIsCreated(file, MessageFormat.format(CDIValidationMessages.DUPLCICATE_EL_NAME[getVersionIndex()], "Sole, Cod"), 21); file = tckProject.getFile("JavaSource/org/jboss/jsr299/tck/tests/jbt/lookup/duplicateName/TestNamed.java"); getAnnotationTest().assertAnnotationIsCreated(file, MessageFormat.format(CDIValidationMessages.DUPLCICATE_EL_NAME[getVersionIndex()], "TestNamed.foo4.*"), 40, 49); getAnnotationTest().assertAnnotationIsCreated(file, MessageFormat.format(CDIValidationMessages.DUPLCICATE_EL_NAME[getVersionIndex()], "TestNamed.foo5.*"), 43); getAnnotationTest().assertAnnotationIsCreated(file, MessageFormat.format(CDIValidationMessages.DUPLCICATE_EL_NAME[getVersionIndex()], "TestNamed.foo6.*"), 46); } /** * • the EL name of one bean is of the form x.y, where y is a valid bean EL name, and x is the EL name of the other bean, * the container automatically detects the problem and treats it as a deployment problem. * * @throws Exception */ public void testDuplicateBeanNamePrefix() throws Exception { IFile file = tckProject.getFile("JavaSource/org/jboss/jsr299/tck/tests/lookup/byname/duplicatePrefixResolution/ExampleWebsite_Broken.java"); getAnnotationTest().assertAnnotationIsCreated(file, MessageFormat.format(CDIValidationMessages.UNRESOLVABLE_EL_NAME[getVersionIndex()], "example.com", "com", "example", "Example"), 22); } /** * 8.3 - Decorator resolution * - If a decorator matches a managed bean, and the managed bean class is declared final, the container automatically detects * the problem and treats it as a deployment problem. * * @throws Exception */ public void testAppliesToFinalManagedBeanClass() throws Exception { IFile file = tckProject.getFile("JavaSource/org/jboss/jsr299/tck/tests/decorators/definition/broken/finalBeanClass/TimestampLogger.java"); getAnnotationTest().assertAnnotationIsCreated(file, MessageFormat.format(CDIValidationMessages.DECORATOR_RESOLVES_TO_FINAL_CLASS[getVersionIndex()], "MockLogger"), 31); } /** * 8.3 - Decorator resolution * - If a decorator matches a managed bean with a non-static, non-private, final method, and the decorator also implements that method, * the container automatically detects the problem and treats it as a deployment problem. * * @throws Exception */ public void testAppliesToFinalMethodOnManagedBeanClass() throws Exception { IFile file = tckProject.getFile("JavaSource/org/jboss/jsr299/tck/tests/decorators/definition/broken/finalBeanMethod/TimestampLogger.java"); getAnnotationTest().assertAnnotationIsCreated(file, MessageFormat.format(CDIValidationMessages.DECORATOR_RESOLVES_TO_FINAL_METHOD[getVersionIndex()], "MockLogger", "log(String string)"), 31); } /** * 6.6.4 Validation of passivation capable beans and dependencies * - If a managed bean which declares a passivating scope is not passivation capable, then the container automatically detects the problem and treats it as a deployment problem. * * See https://issues.jboss.org/browse/JBIDE-3126 * @throws Exception */ public void testSimpleWebBeanWithNonSerializableImplementationClassFails() throws Exception { IFile file = tckProject.getFile("JavaSource/org/jboss/jsr299/tck/tests/context/passivating/broken/nonPassCapableManBeanHasPassScope/Hamina_Broken.java"); getAnnotationTest().assertAnnotationIsCreated(file, MessageFormat.format(CDIValidationMessages.NOT_PASSIVATION_CAPABLE_BEAN[getVersionIndex()], "Hamina_Broken", "SessionScoped"), 22); } }