You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@openwebbeans.apache.org by st...@apache.org on 2016/02/02 18:48:15 UTC

svn commit: r1728163 [1/2] - in /openwebbeans/branches/cdi-2.0: ./ webbeans-doc/src/docbkx/userguide/ webbeans-ee/src/main/java/org/apache/webbeans/ee/event/ webbeans-impl/src/main/java/org/apache/webbeans/component/ webbeans-impl/src/main/java/org/apa...

Author: struberg
Date: Tue Feb  2 17:48:14 2016
New Revision: 1728163

URL: http://svn.apache.org/viewvc?rev=1728163&view=rev
Log:
Merged from trunk
properly set enabled flag for interceptors [from revision 1680659]
collapse statements [from revision 1680660]
remove unused method parameters [from revision 1680662]
remove unused method and field [from revision 1680664]
remove unused variable [from revision 1680666]
avoid NPE if cc.getbean is null [from revision 1680825]
remove redundant public qualifier from interface [from revision 1681040]
remove wrong JavaDoc [from revision 1681041]
remove unused 'withAnnotaions'

This was initially intended for CDI Extension support but turned out
not to be needed. [from revision 1681042]
OWB-1065 fix Incorrect matching of parameterized events

txs to Harald Wellmann for the catch and ideas for the unit test. [from revision 1681043]
OWB-1066 fix endless loop in GenericsUtil [from revision 1681576]
OWB-989 mark utility class ct as private [from revision 1681617]
OWB-798 do event binding check only if no observer could be found.

saves a lot of performance for most events [from revision 1681618]
OWB-798 improve performance of various event type checks [from revision 1681620]
OWB-1053 cache raw event types [from revision 1681630]
OWB-1075 improve annotation check performance [from revision 1681638]
OWB-1044 only fire @Destroyed and @Initialized if there are any observers for them. [from revision 1681646]
OWB-1044 improve lifecycle event caching even further

We cache RequestScoped even more agressively as this gets used
even for resource requests [from revision 1681652]
OWB-1051 move cache request scope proxies by default

* RequestScopedBeanInterceptorHandler got moved from owb-web to owb-core and enabled by default
* Also enable caches for @SessionScoped beans [from revision 1681656]
fix spi pom by making not mandatory ee specs optional [from revision 1681657]
OWB-851 improve registration of EE beans [from revision 1681659]
OWB-1061 mark ApplicationContext as already destroyed

We cannot immediately kill out the whole ApplicationContext and not even set it to inactive
as it is needed for delivering @BeforeShutdown events. [from revision 1681661]
OWB-1048 remove OpenWebBeansWebPlugin

Not needed anymore, we don't use the sessionId as it gets permanently rewritten anyway [from revision 1681663]
OWB-1048 remove now unused Tomcat ContainerListener

we do not use the sessionId anymore to track things as 
it got changed way too often to be of any use. [from revision 1681665]
OWB-812 extract commonly used "WebBeansContext" param name [from revision 1681689]
OWB-812 extract common nullcheck paramete [from revision 1681692]
OWB-821 extract common string [from revision 1681693]
OWB-821 make utility classes final [from revision 1681726]
OWB-1076 remove sample sources from binary distribution

They are already contained in the source distribution anyway [from revision 1681935]
OWB-933 adding test to verify all works now [from revision 1681961]
OWB-989 remove unecessary nullcheck [from revision 1681964]
OWB-989 remove redundant array creation [from revision 1681967]
OWB-989 using entrySet is faster [from revision 1681970]
OWB-989 remove TODOs as those cases should never happen. [from revision 1681971]
OWB-989 fix potential nullpointer [from revision 1681973]
OWB-989 avoid possible NPE [from revision 1681977]
OWB-989 remove redundant null checks [from revision 1681978]
OWB-989 don't throw NPEs [from revision 1681984]
OWB-1056 add missing dependencies [from revision 1682241]
OWB-1077 create install script for OWB on tomcat7 [from revision 1682245]
OWB-1077 also add an install script for tomcat6 integration of OWB [from revision 1682246]
OWB-1077 fix script documentation for tomat6 [from revision 1682249]
OWB-1077 rework distribution pom

Now you can also build a 'local' distribution zip with -Pbuild-dist [from revision 1682297]
OWB-1077 chmod to 0777 by default to have shell scripts executable [from revision 1682321]
OWB-1077 add a windows installer as well [from revision 1682328]
OWB-989 remove unused variable [from revision 1682371]
OWB-989 fix potential NPE and dead code [from revision 1682375]
OWB-989 avoid empty if blocks [from revision 1682377]
OWB-989 remove unecessary cast [from revision 1682379]
OWB-989 fix potential NPEs [from revision 1682380]
fix modifier ordering

to make sonar happy... [from revision 1682626]
OWB-1077 add install script for OWB + MyFaces on Tomcat7 & 8 [from revision 1682645]
add ASM license and notice to our distribution packages [from revision 1682655]
OWB-654 fix manual lookup of beans with generic types

Txs to Daniel Cunha (soro) for the patch! [from revision 1682658]
OWB-654 fix manual lookup of beans with generic types

Missed to add a few classes from the patch.
Txs to Daniel Cunha (soro) for the patch! [from revision 1682689]
OWB-1080 support for other JVM versions in our proxies

The new configuration affects which bytecode we generate in our proxy classes
* By default we now generate Java6 bytecode instead of Java5
* A new config org.apache.webbeans.generator.javaVersion=auto supports automatically
  detecting the current JVM java.version and use this
* Switch from CALC_MAX to real FRAME calculateion for our generated bytecode
* org.apache.webbeans.generator.javaVersion=1.8 etc can be used to specify a java version [from revision 1682898]
OWB-1055 fold back Begin and End listeners into one single Listener

It turned out not to be needed. [from revision 1682905]
OWB-1079 upgrade to xbean-4.3 which contains a shaded ASM-5.0.4 [from revision 1682910]
add release notes for OWB-1.6.0 [from revision 1682911]
OWB-1082 set serializable BeanManager wrapper into ServletContext and similar 'external' usages [from revision 1684722]
upgrade samples to latest available MyFaces version [from revision 1685115]
OWB-1083 avoid HttpSession creation during context destroyal

Txs to Adam Cornett for the report and partly fix! [from revision 1685118]
OWB-1081 check Reception.IF_EXISTS in case of an inactive context [from revision 1685641]
release preparation for owb-1.6.1 [from revision 1685698]
OWB-1084 tracking session to get the right (from owb point of view) session instance for destroy event [from revision 1688063]
OWB-935 add unit test 

A standard bean observing CDI Extension event which should not get triggered.
Extension events can only get observed in Extensions [from revision 1694733]
add description about how to debug the ITs [from revision 1694734]
add release notes for OWB-1.6.2 [from revision 1694735]
OWB-1093 WebApp beans scanning broken with maven and jetty [from revision 1704602]
OWB-1094 Move bean scanning excludes to openwebbeans.properties [from revision 1704889]
OWB-1094 renamed config name [from revision 1704908]
OWB-1094 possible NPE [from revision 1705018]
OWB-1096 Enable > CDI1.0 unit tests [from revision 1710680]
OWB-1095 fixed InjectionResolver cache handling on startup [from revision 1710767]
OWB-1098 improve getRootCause logic

txs to Tobias Stoeckmann for the patch! [from revision 1713935]
adding whitelist to BlacklistClassResolver [from revision 1716862]
fixing copy/paste from tomee [from revision 1716863]
useless method [from revision 1716866]
checkstyle sorry to have forgotten you my love [from revision 1716930]
improve documentation of our Conversation configuration [from revision 1719452]
improve conversation timeout documentation [from revision 1719453]
OWB-1034 improve BeanCacheKey performance

we actually don't need such a good qualifier hash as all gets compared
later anyways. So we now only look at the annotationTypes hash
and be good. 
I also enabled a special handling for qualifiers which are known 
to have no parameters. [from revision 1719457]
OWB-1104 add tomcat bootstrap.jar to scan-excludes [from revision 1723351]
OWB-1102 fix generic assignability check for ProcessInjectionPoint event

txs to Antonin Stefanutti for the bug report and providing a draft for a unit test! [from revision 1723685]
OWB-1108 destroy all SPI servicec which implement the Closeable interface [from revision 1723999]
OWB-1103 improve the DefaultApplicationBoundaryService to max return the Application CL as outermost CL. [from revision 1724000]
OWB-1103 add JavaDoc and make it easier to subclass [from revision 1724539]
OWB-1054 move all shutdown caches cleanup calls to the BeanManager [from revision 1724542]
OWB-1110 implement allowProxying logic

User can now define that classes are proxyable - even if they have final methods

* comma separated class list in java sytem prop -Djavax.enterprise.inject.allowProxying.classes=...
* or an environment key with the name JAVAX_ENTERPRISE_INJECT_ALLOWPROXYING_CLASSES=...
* or via beans.xml:
  <beans>
    <allowProxying>
      <class>Class1</class>
      <class>some.OtherClass</class>
    </allowProxying>
  </beans> [from revision 1724876]
OWB-1111 proper ections in case of errors 

* SystemExceptions will blow up as they indicate a systematic setup problem
* AFTER_SUCCESS gets skipped, on Rollback or IllegalState
* for all other phases (AFTER_COMPLETION, BEFORE_COMLETION, AFTER_FAILURE) 
  the event will get delivered immediate [from revision 1726303]
OWB-1111 also deliver the AFTER_SUCCESS if there is no active transaction [from revision 1726366]
OWB-1107 introduce bean-discovery-mode="scoped"

with this bean-discovery-mode we will create AnnotatedTypes and fire PAT for all scanned classes
but only pick up AnnotatedTypes as Bean<T> IF they are:
* have an explicit CDI scope annotation, or
* are an Interceptor or a Decorator, or
* are a JavaEE bean, or
* have a StereoType

This commit also removes a duplicate scanning which erronously got introduced accidently [from revision 1727788]
OWB-1107 adding <scopedBeansOnly/> backward compat option

adding a scopedBeansOnly tag to your beans.xml will make OWB only pick up scoped beans.
This is a backward compat option for bean-discovery-mode="scoped" [from revision 1727792]

Added:
    openwebbeans/branches/cdi-2.0/webbeans-impl/src/test/java/org/apache/webbeans/test/events/injectiontarget/ProcessInjectionPointTest.java
      - copied unchanged from r1723685, openwebbeans/trunk/webbeans-impl/src/test/java/org/apache/webbeans/test/events/injectiontarget/ProcessInjectionPointTest.java
    openwebbeans/branches/cdi-2.0/webbeans-impl/src/test/java/org/apache/webbeans/test/performance/BeanResolvingPerformanceTest.java
      - copied unchanged from r1719457, openwebbeans/trunk/webbeans-impl/src/test/java/org/apache/webbeans/test/performance/BeanResolvingPerformanceTest.java
    openwebbeans/branches/cdi-2.0/webbeans-impl/src/test/java/org/apache/webbeans/test/proxy/unproxyable/
      - copied from r1724876, openwebbeans/trunk/webbeans-impl/src/test/java/org/apache/webbeans/test/proxy/unproxyable/
    openwebbeans/branches/cdi-2.0/webbeans-impl/src/test/resources/org/apache/webbeans/test/xml/allowproxying/
      - copied from r1724876, openwebbeans/trunk/webbeans-impl/src/test/resources/org/apache/webbeans/test/xml/allowproxying/
    openwebbeans/branches/cdi-2.0/webbeans-impl/src/test/resources/org/apache/webbeans/test/xml/strict/cdi11_discovery_scoped.xml
      - copied unchanged from r1727792, openwebbeans/trunk/webbeans-impl/src/test/resources/org/apache/webbeans/test/xml/strict/cdi11_discovery_scoped.xml
    openwebbeans/branches/cdi-2.0/webbeans-impl/src/test/resources/org/apache/webbeans/test/xml/strict/cdi11_discovery_scopedBeansOnly.xml
      - copied unchanged from r1727792, openwebbeans/trunk/webbeans-impl/src/test/resources/org/apache/webbeans/test/xml/strict/cdi11_discovery_scopedBeansOnly.xml
    openwebbeans/branches/cdi-2.0/webbeans-spi/src/main/java/org/apache/webbeans/spi/BdaScannerService.java
      - copied unchanged from r1727788, openwebbeans/trunk/webbeans-spi/src/main/java/org/apache/webbeans/spi/BdaScannerService.java
    openwebbeans/branches/cdi-2.0/webbeans-tck/src/test/java/
      - copied from r1727788, openwebbeans/trunk/webbeans-tck/src/test/java/
Modified:
    openwebbeans/branches/cdi-2.0/   (props changed)
    openwebbeans/branches/cdi-2.0/webbeans-doc/src/docbkx/userguide/chapter1.xml
    openwebbeans/branches/cdi-2.0/webbeans-ee/src/main/java/org/apache/webbeans/ee/event/TransactionalEventNotifier.java
    openwebbeans/branches/cdi-2.0/webbeans-impl/src/main/java/org/apache/webbeans/component/AbstractOwbBean.java
    openwebbeans/branches/cdi-2.0/webbeans-impl/src/main/java/org/apache/webbeans/component/creation/BeanAttributesBuilder.java
    openwebbeans/branches/cdi-2.0/webbeans-impl/src/main/java/org/apache/webbeans/config/BeansDeployer.java
    openwebbeans/branches/cdi-2.0/webbeans-impl/src/main/java/org/apache/webbeans/config/DeploymentValidationService.java
    openwebbeans/branches/cdi-2.0/webbeans-impl/src/main/java/org/apache/webbeans/config/OpenWebBeansConfiguration.java
    openwebbeans/branches/cdi-2.0/webbeans-impl/src/main/java/org/apache/webbeans/config/PropertyLoader.java
    openwebbeans/branches/cdi-2.0/webbeans-impl/src/main/java/org/apache/webbeans/config/WebBeansContext.java
    openwebbeans/branches/cdi-2.0/webbeans-impl/src/main/java/org/apache/webbeans/container/BeanCacheKey.java
    openwebbeans/branches/cdi-2.0/webbeans-impl/src/main/java/org/apache/webbeans/container/BeanManagerImpl.java
    openwebbeans/branches/cdi-2.0/webbeans-impl/src/main/java/org/apache/webbeans/corespi/scanner/AbstractMetaDataDiscovery.java
    openwebbeans/branches/cdi-2.0/webbeans-impl/src/main/java/org/apache/webbeans/corespi/se/DefaultApplicationBoundaryService.java
    openwebbeans/branches/cdi-2.0/webbeans-impl/src/main/java/org/apache/webbeans/event/NotificationManager.java
    openwebbeans/branches/cdi-2.0/webbeans-impl/src/main/java/org/apache/webbeans/lifecycle/AbstractLifeCycle.java
    openwebbeans/branches/cdi-2.0/webbeans-impl/src/main/java/org/apache/webbeans/util/ClassUtil.java
    openwebbeans/branches/cdi-2.0/webbeans-impl/src/main/java/org/apache/webbeans/util/OwbCustomObjectInputStream.java
    openwebbeans/branches/cdi-2.0/webbeans-impl/src/main/java/org/apache/webbeans/util/SpecializationUtil.java
    openwebbeans/branches/cdi-2.0/webbeans-impl/src/main/java/org/apache/webbeans/util/WebBeansConstants.java
    openwebbeans/branches/cdi-2.0/webbeans-impl/src/main/java/org/apache/webbeans/xml/DefaultBeanArchiveInformation.java
    openwebbeans/branches/cdi-2.0/webbeans-impl/src/main/java/org/apache/webbeans/xml/DefaultBeanArchiveService.java
    openwebbeans/branches/cdi-2.0/webbeans-impl/src/main/resources/META-INF/openwebbeans/openwebbeans.properties
    openwebbeans/branches/cdi-2.0/webbeans-impl/src/test/java/org/apache/webbeans/test/annotation/binding/BeanCacheKeyUnitTest.java
    openwebbeans/branches/cdi-2.0/webbeans-impl/src/test/java/org/apache/webbeans/test/xml/BeanArchiveServiceTest.java
    openwebbeans/branches/cdi-2.0/webbeans-jsf/src/main/resources/META-INF/openwebbeans/openwebbeans.properties
    openwebbeans/branches/cdi-2.0/webbeans-jsf12/src/main/resources/META-INF/openwebbeans/openwebbeans.properties
    openwebbeans/branches/cdi-2.0/webbeans-spi/src/main/java/org/apache/webbeans/spi/ApplicationBoundaryService.java
    openwebbeans/branches/cdi-2.0/webbeans-spi/src/main/java/org/apache/webbeans/spi/BeanArchiveService.java
    openwebbeans/branches/cdi-2.0/webbeans-spi/src/main/java/org/apache/webbeans/spi/ScannerService.java

Propchange: openwebbeans/branches/cdi-2.0/
------------------------------------------------------------------------------
--- svn:mergeinfo (original)
+++ svn:mergeinfo Tue Feb  2 17:48:14 2016
@@ -1,2 +1,2 @@
 /openwebbeans/branches/owb_1.2.x:1640945,1641609,1641684
-/openwebbeans/trunk:1681165-1697479
+/openwebbeans/trunk:1681165-1697479,1704602,1704889,1704908,1705018,1710680,1710767,1713935,1716862-1716863,1716866,1716930,1719452-1719453,1719457,1723351,1723685,1723999-1724000,1724539,1724542,1724876,1726303,1726366,1727788,1727792

Modified: openwebbeans/branches/cdi-2.0/webbeans-doc/src/docbkx/userguide/chapter1.xml
URL: http://svn.apache.org/viewvc/openwebbeans/branches/cdi-2.0/webbeans-doc/src/docbkx/userguide/chapter1.xml?rev=1728163&r1=1728162&r2=1728163&view=diff
==============================================================================
--- openwebbeans/branches/cdi-2.0/webbeans-doc/src/docbkx/userguide/chapter1.xml (original)
+++ openwebbeans/branches/cdi-2.0/webbeans-doc/src/docbkx/userguide/chapter1.xml Tue Feb  2 17:48:14 2016
@@ -203,8 +203,8 @@ org.apache.webbeans.spi.JNDIService=org.
     				</listitem>
     				
     				<listitem>
-    					<para><emphasis>org.apache.webbeans.conversation.Conversation.periodicDelay:</emphasis>  Conversation removing thread periodic delay. Unused
-    					conversations are removed by the container periodically.</para>
+    					<para><emphasis>org.apache.webbeans.conversation.Conversation.timeoutInterval:</emphasis>  Conversation removing thread periodic delay. Unused
+    					conversations are removed by the container if they are not touched for this amount of time.</para>
     				</listitem>
     				
     				<listitem>

Modified: openwebbeans/branches/cdi-2.0/webbeans-ee/src/main/java/org/apache/webbeans/ee/event/TransactionalEventNotifier.java
URL: http://svn.apache.org/viewvc/openwebbeans/branches/cdi-2.0/webbeans-ee/src/main/java/org/apache/webbeans/ee/event/TransactionalEventNotifier.java?rev=1728163&r1=1728162&r2=1728163&view=diff
==============================================================================
--- openwebbeans/branches/cdi-2.0/webbeans-ee/src/main/java/org/apache/webbeans/ee/event/TransactionalEventNotifier.java (original)
+++ openwebbeans/branches/cdi-2.0/webbeans-ee/src/main/java/org/apache/webbeans/ee/event/TransactionalEventNotifier.java Tue Feb  2 17:48:14 2016
@@ -21,8 +21,10 @@ package org.apache.webbeans.ee.event;
 import javax.enterprise.event.TransactionPhase;
 import javax.enterprise.inject.spi.EventMetadata;
 import javax.enterprise.inject.spi.ObserverMethod;
+import javax.transaction.RollbackException;
 import javax.transaction.Status;
 import javax.transaction.Synchronization;
+import javax.transaction.SystemException;
 import javax.transaction.Transaction;
 
 import org.apache.webbeans.config.OWBLogConst;
@@ -46,6 +48,22 @@ public final class TransactionalEventNot
 
     /**
      * This will get called by the EJB integration code
+     *
+     * Since registration of the event can blow up if the tx is not active we have a matrix of assumed behaviour
+     *
+     * There are 3 different error cases when registering a TX Synchronization:
+     * RollbackException - Thrown to indicate that the transaction has been marked for rollback only.
+     * IllegalStateException - Thrown if the transaction in the target object is in the prepared state or the transaction is inactive.
+     * SystemException - Thrown if the transaction manager encounters an unexpected error condition.
+     *
+     * In case of the SystemException we simply let it blow up. This is usually the case if there
+     * is some setup problem.
+     *
+     * In case of a RollbackException or IllegalStateException we will perform different actions based on the
+     * desired TransactionPhase:
+     * For AFTER_COMPLETION, BEFORE_COMPLETION and AFTER_FAILURE we will deliver the event immediately.
+     * For AFTER_SUCCESS we copmletely skip the event. It will not get invoked at all because the transaction
+     * will not succeed.
      */
     public static void registerTransactionSynchronization(TransactionPhase phase, ObserverMethod<? super Object> observer, Object event, EventMetadata metadata) throws Exception
     {
@@ -61,19 +79,27 @@ public final class TransactionalEventNot
         {
             if (phase.equals(TransactionPhase.AFTER_COMPLETION))
             {
-                transaction.registerSynchronization(new AfterCompletion(observer, event, metadata));
+                registerEvent(transaction, new AfterCompletion(observer, event, metadata), true);
             }
             else if (phase.equals(TransactionPhase.AFTER_SUCCESS))
             {
-                transaction.registerSynchronization(new AfterCompletionSuccess(observer, event, metadata));
+                if (transaction.getStatus() == Status.STATUS_NO_TRANSACTION)
+                {
+                    // the AFTER_SUCCESS observers only get invoked if the TX succeeds or if there is no transaction
+                    new AfterCompletionSuccess(observer, event, metadata).notifyObserver();
+                }
+                else
+                {
+                    registerEvent(transaction, new AfterCompletionSuccess(observer, event, metadata), false);
+                }
             }
             else if (phase.equals(TransactionPhase.AFTER_FAILURE))
             {
-                transaction.registerSynchronization(new AfterCompletionFailure(observer, event, metadata));
+                registerEvent(transaction, new AfterCompletionFailure(observer, event, metadata), true);
             }
             else if (phase.equals(TransactionPhase.BEFORE_COMPLETION))
             {
-                transaction.registerSynchronization(new BeforeCompletion(observer, event, metadata));
+                registerEvent(transaction, new BeforeCompletion(observer, event, metadata), true);
             }
             else
             {
@@ -92,7 +118,30 @@ public final class TransactionalEventNot
             }
         }
     }
-    
+
+    private static void registerEvent(Transaction transaction, AbstractSynchronization synchronization, boolean immediateOnError)
+        throws SystemException
+    {
+        try
+        {
+            transaction.registerSynchronization(synchronization);
+        }
+        catch (RollbackException re)
+        {
+            if (immediateOnError)
+            {
+                synchronization.notifyObserver();
+            }
+        }
+        catch (IllegalStateException ise)
+        {
+            if (immediateOnError)
+            {
+                synchronization.notifyObserver();
+            }
+        }
+    }
+
     private static class AbstractSynchronization<T> implements Synchronization
     {
 

Modified: openwebbeans/branches/cdi-2.0/webbeans-impl/src/main/java/org/apache/webbeans/component/AbstractOwbBean.java
URL: http://svn.apache.org/viewvc/openwebbeans/branches/cdi-2.0/webbeans-impl/src/main/java/org/apache/webbeans/component/AbstractOwbBean.java?rev=1728163&r1=1728162&r2=1728163&view=diff
==============================================================================
--- openwebbeans/branches/cdi-2.0/webbeans-impl/src/main/java/org/apache/webbeans/component/AbstractOwbBean.java (original)
+++ openwebbeans/branches/cdi-2.0/webbeans-impl/src/main/java/org/apache/webbeans/component/AbstractOwbBean.java Tue Feb  2 17:48:14 2016
@@ -152,14 +152,12 @@ public abstract class AbstractOwbBean<T>
 
     private Throwable getRootException(Throwable throwable)
     {
-        if(throwable.getCause() == null || throwable.getCause() == throwable)
+        Throwable current = throwable;
+        while (current.getCause() != null && current.getCause() != current)
         {
-            return throwable;
-        }
-        else
-        {
-            return getRootException(throwable.getCause());
+            current = current.getCause();
         }
+        return current;
     }
 
     /*

Modified: openwebbeans/branches/cdi-2.0/webbeans-impl/src/main/java/org/apache/webbeans/component/creation/BeanAttributesBuilder.java
URL: http://svn.apache.org/viewvc/openwebbeans/branches/cdi-2.0/webbeans-impl/src/main/java/org/apache/webbeans/component/creation/BeanAttributesBuilder.java?rev=1728163&r1=1728162&r2=1728163&view=diff
==============================================================================
--- openwebbeans/branches/cdi-2.0/webbeans-impl/src/main/java/org/apache/webbeans/component/creation/BeanAttributesBuilder.java (original)
+++ openwebbeans/branches/cdi-2.0/webbeans-impl/src/main/java/org/apache/webbeans/component/creation/BeanAttributesBuilder.java Tue Feb  2 17:48:14 2016
@@ -27,6 +27,7 @@ import java.util.Iterator;
 import java.util.List;
 import java.util.Set;
 
+import javax.decorator.Decorator;
 import javax.enterprise.context.Dependent;
 import javax.enterprise.context.NormalScope;
 import javax.enterprise.inject.Alternative;
@@ -43,6 +44,7 @@ import javax.enterprise.inject.spi.Annot
 import javax.enterprise.util.Nonbinding;
 import javax.inject.Named;
 import javax.inject.Scope;
+import javax.interceptor.Interceptor;
 
 import org.apache.webbeans.annotation.AnnotationManager;
 import org.apache.webbeans.annotation.AnyLiteral;
@@ -106,9 +108,17 @@ public abstract class BeanAttributesBuil
 
     public BeanAttributesImpl<T> build()
     {
-        defineTypes();
+        // we need to check the stereotypes first because we might need it to determine the scope
         defineStereotypes();
+
         defineScope();
+        if (scope == null)
+        {
+            // this indicates that we shall not use this AnnotatedType to create Beans from it.
+            return null;
+        }
+
+        defineTypes();
         defineName();
         defineQualifiers();
         defineNullable();
@@ -281,10 +291,10 @@ public abstract class BeanAttributesBuil
 
     protected void defineScope(String errorMessage)
     {
-        defineScope(null, errorMessage);
+        defineScope(null, false, errorMessage);
     }
 
-    protected void defineScope(Class<?> declaringClass, String errorMessage)
+    protected void defineScope(Class<?> declaringClass, boolean onlyScopedBeans, String errorMessage)
     {
         Annotation[] annotations = AnnotationUtil.asArray(annotated.getAnnotations());
         boolean found = false;
@@ -364,24 +374,20 @@ public abstract class BeanAttributesBuil
 
         if (!found && declaringClass != null && !hasDeclaredNonInheritedScope(declaringClass))
         {
-            defineScope(declaringClass.getSuperclass(), errorMessage);
+            defineScope(declaringClass.getSuperclass(), onlyScopedBeans, errorMessage);
         }
         else if (!found)
         {
-            defineDefaultScope(errorMessage);
+            defineDefaultScope(errorMessage, onlyScopedBeans);
         }
     }
 
-    private void defineDefaultScope(String exceptionMessage)
+    private void defineDefaultScope(String exceptionMessage, boolean onlyScopedBeans)
     {
         if (scope == null)
         {
             Set<Class<? extends Annotation>> stereos = stereotypes;
-            if (stereos.size() == 0)
-            {
-                scope = Dependent.class;
-            }
-            else
+            if (stereos != null && stereos.size() >  0)
             {
                 Annotation defined = null;
                 Set<Class<? extends Annotation>> anns = stereotypes;
@@ -426,6 +432,17 @@ public abstract class BeanAttributesBuil
                     scope = Dependent.class;
                 }
             }
+            if (scope == null &&
+                    (!onlyScopedBeans ||
+                    annotated.getAnnotation(Interceptor.class) != null ||
+                    annotated.getAnnotation(Decorator.class) != null))
+            {
+                // only add a 'default' Dependent scope
+                // * if it's not in a bean-discovery-mode='scoped' module, or
+                // * if it's a Decorator or Interceptor
+                scope = Dependent.class;
+            }
+
         }
     }
 
@@ -558,9 +575,14 @@ public abstract class BeanAttributesBuil
         
         public <T> BeanAttributesBuilder<T, AnnotatedType<T>> newBeanAttibutes(AnnotatedType<T> annotatedType)
         {
-            return new AnnotatedTypeBeanAttributesBuilder<T>(webBeansContext, annotatedType);
+            return newBeanAttibutes(annotatedType, false);
         }
         
+        public <T> BeanAttributesBuilder<T, AnnotatedType<T>> newBeanAttibutes(AnnotatedType<T> annotatedType, boolean onlyScopedBeans)
+        {
+            return new AnnotatedTypeBeanAttributesBuilder<T>(webBeansContext, annotatedType, onlyScopedBeans);
+        }
+
         public <T> BeanAttributesBuilder<T, AnnotatedField<T>> newBeanAttibutes(AnnotatedField<T> annotatedField)
         {
             return new AnnotatedFieldBeanAttributesBuilder<T>(webBeansContext, annotatedField);
@@ -574,16 +596,19 @@ public abstract class BeanAttributesBuil
 
     private static class AnnotatedTypeBeanAttributesBuilder<C> extends BeanAttributesBuilder<C, AnnotatedType<C>>
     {
+        private final boolean onlyScopedBeans;
 
-        public AnnotatedTypeBeanAttributesBuilder(WebBeansContext webBeansContext, AnnotatedType<C> annotated)
+        public AnnotatedTypeBeanAttributesBuilder(WebBeansContext webBeansContext, AnnotatedType<C> annotated, boolean onlyScopedBeans)
         {
             super(webBeansContext, annotated);
+            this.onlyScopedBeans = onlyScopedBeans;
         }
 
         @Override
         protected void defineScope()
         {
-            defineScope(getAnnotated().getJavaClass(), WebBeansLoggerFacade.getTokenString(OWBLogConst.TEXT_MB_IMPL) + getAnnotated().getJavaClass().getName() +
+            defineScope(getAnnotated().getJavaClass(), onlyScopedBeans,
+                    WebBeansLoggerFacade.getTokenString(OWBLogConst.TEXT_MB_IMPL) + getAnnotated().getJavaClass().getName() +
                     WebBeansLoggerFacade.getTokenString(OWBLogConst.TEXT_SAME_SCOPE));
         }
 

Modified: openwebbeans/branches/cdi-2.0/webbeans-impl/src/main/java/org/apache/webbeans/config/BeansDeployer.java
URL: http://svn.apache.org/viewvc/openwebbeans/branches/cdi-2.0/webbeans-impl/src/main/java/org/apache/webbeans/config/BeansDeployer.java?rev=1728163&r1=1728162&r2=1728163&view=diff
==============================================================================
--- openwebbeans/branches/cdi-2.0/webbeans-impl/src/main/java/org/apache/webbeans/config/BeansDeployer.java (original)
+++ openwebbeans/branches/cdi-2.0/webbeans-impl/src/main/java/org/apache/webbeans/config/BeansDeployer.java Tue Feb  2 17:48:14 2016
@@ -70,6 +70,7 @@ import org.apache.webbeans.portable.even
 import org.apache.webbeans.portable.events.discovery.BeforeBeanDiscoveryImpl;
 import org.apache.webbeans.portable.events.generics.GProcessAnnotatedType;
 import org.apache.webbeans.portable.events.generics.GProcessManagedBean;
+import org.apache.webbeans.spi.BdaScannerService;
 import org.apache.webbeans.spi.BeanArchiveService;
 import org.apache.webbeans.spi.JNDIService;
 import org.apache.webbeans.spi.ScannerService;
@@ -82,6 +83,7 @@ import org.apache.webbeans.util.Injectio
 import org.apache.webbeans.util.SpecializationUtil;
 import org.apache.webbeans.util.WebBeansConstants;
 import org.apache.webbeans.util.WebBeansUtil;
+import org.apache.webbeans.xml.DefaultBeanArchiveInformation;
 
 import javax.enterprise.inject.AmbiguousResolutionException;
 import javax.enterprise.inject.Model;
@@ -121,6 +123,8 @@ import java.util.logging.Level;
 import java.util.logging.Logger;
 
 import static java.util.Arrays.asList;
+import static org.apache.webbeans.spi.BeanArchiveService.BeanDiscoveryMode;
+import static org.apache.webbeans.spi.BeanArchiveService.BeanArchiveInformation;
 
 /**
  * Deploys the all beans that are defined in the {@link org.apache.webbeans.spi.ScannerService} at
@@ -165,6 +169,12 @@ public class BeansDeployer
     private final Map<String, Boolean> packageVetoCache = new HashMap<String, Boolean>();
 
     /**
+     * This BdaInfo is used for all manually added annotated types or in case
+     * a non-Bda-aware ScannerService got configured.
+     */
+    private final DefaultBeanArchiveInformation defaultBeanArchiveInformation;
+
+    /**
      * Creates a new deployer with given xml configurator.
      * 
      * @param webBeansContext
@@ -179,6 +189,9 @@ public class BeansDeployer
 
         String usage = this.webBeansContext.getOpenWebBeansConfiguration().getProperty(OpenWebBeansConfiguration.USE_EJB_DISCOVERY);
         discoverEjb = Boolean.parseBoolean(usage);
+
+        defaultBeanArchiveInformation = new DefaultBeanArchiveInformation();
+        defaultBeanArchiveInformation.setBeanDiscoveryMode(BeanDiscoveryMode.ALL);
     }
 
     /**
@@ -224,44 +237,58 @@ public class BeansDeployer
                 //Configure Default Beans
                 configureDefaultBeans();
 
-                List<AnnotatedType<?>> annotatedTypes = annotatedTypesFromClassPath(scanner);
+                Map<BeanArchiveInformation, List<AnnotatedType<?>>> annotatedTypesPerBda = annotatedTypesFromClassPath(scanner);
 
-                //Deploy additional Annotated Types
-                addAdditionalAnnotatedTypes(webBeansContext.getBeanManagerImpl().getAdditionalAnnotatedTypes(), annotatedTypes);
+                List<AnnotatedType<?>> globalBdaAnnotatedTypes = annotatedTypesPerBda.get(defaultBeanArchiveInformation);
 
-                registerAlternativesDecoratorsAndInterceptorsWithPriority(annotatedTypes);
+                // Deploy additional Annotated Types which got added via BeforeBeanDiscovery#addAnnotatedType
+                addAdditionalAnnotatedTypes(webBeansContext.getBeanManagerImpl().getAdditionalAnnotatedTypes(), globalBdaAnnotatedTypes);
 
-                addAdditionalAnnotatedTypes(fireAfterTypeDiscoveryEvent(), annotatedTypes);
+                registerAlternativesDecoratorsAndInterceptorsWithPriority(globalBdaAnnotatedTypes);
+
+                addAdditionalAnnotatedTypes(fireAfterTypeDiscoveryEvent(), globalBdaAnnotatedTypes);
+
+                // Also configures deployments, interceptors, decorators.
+                deployFromXML(scanner);
 
                 SpecializationUtil specializationUtil = new SpecializationUtil(webBeansContext);
+                specializationUtil.removeDisabledTypes(annotatedTypesPerBda, null, true);
 
-                specializationUtil.removeDisabledTypes(annotatedTypes, null, true);
+                final Map<BeanArchiveInformation, Map<AnnotatedType<?>, ExtendedBeanAttributes<?>>> beanAttributesPerBda
+                    = getBeanAttributes(annotatedTypesPerBda);
 
-                final Map<AnnotatedType<?>, AnnotatedTypeData<?>> annotatedTypePreProcessing = getBeanAttributes(annotatedTypes);
-                annotatedTypes.clear(); // shouldn't be used anymore, view is now annotatedTypePreProcessing
+                // shouldn't be used anymore, view is now beanAttributes
+                annotatedTypesPerBda.clear();
 
-                //Deploy bean from XML. Also configures deployments, interceptors, decorators.
-                deployFromXML(scanner, annotatedTypePreProcessing);
 
                 //Checking stereotype conditions
                 checkStereoTypes(scanner);
 
                 // Handle Specialization
                 specializationUtil.removeDisabledTypes(
-                        annotatedTypePreProcessing.keySet(),
+                        annotatedTypesPerBda,
                         new SpecializationUtil.BeanAttributesProvider()
                         {
                             @Override
                             public <T> BeanAttributes get(final AnnotatedType<T> at)
                             {
-                                final AnnotatedTypeData<?> data = annotatedTypePreProcessing.get(at);
+                                ExtendedBeanAttributes<?> data = null;
+                                for (Map<AnnotatedType<?>, ExtendedBeanAttributes<?>> beanAttributes : beanAttributesPerBda.values())
+                                {
+                                    data = beanAttributes.get(at);
+                                    if (data != null)
+                                    {
+                                        break;
+                                    }
+
+                                }
                                 return data == null ? null : data.beanAttributes;
                             }
                         },
                         false);
 
                 // create beans from the discovered AnnotatedTypes
-                deployFromAnnotatedTypes(annotatedTypePreProcessing);
+                deployFromBeanAttributes(beanAttributesPerBda);
 
                 //X TODO configure specialized producer beans.
                 webBeansContext.getWebBeansUtil().configureProducerMethodSpecializations();
@@ -320,37 +347,56 @@ public class BeansDeployer
         }
     }
 
-    private Map<AnnotatedType<?>, AnnotatedTypeData<?>> getBeanAttributes(final List<AnnotatedType<?>> annotatedTypes)
+    private Map<BeanArchiveInformation, Map<AnnotatedType<?>, ExtendedBeanAttributes<?>>> getBeanAttributes(
+                                final Map<BeanArchiveInformation, List<AnnotatedType<?>>> annotatedTypesPerBda)
     {
-        final Map<AnnotatedType<?>, AnnotatedTypeData<?>> result = new IdentityHashMap<AnnotatedType<?>, AnnotatedTypeData<?>>(annotatedTypes.size());
-        final Iterator<AnnotatedType<?>> iterator = annotatedTypes.iterator();
-        while (iterator.hasNext())
-        {
-            final AnnotatedType<?> at = iterator.next();
-            final Class beanClass = at.getJavaClass();
-            final boolean isEjb = discoverEjb && EJBWebBeansConfigurator.isSessionBean(beanClass, webBeansContext);
-            try
+        final Map<BeanArchiveInformation, Map<AnnotatedType<?>, ExtendedBeanAttributes<?>>> beanAttributesPerBda
+            = new HashMap<BeanArchiveInformation, Map<AnnotatedType<?>, ExtendedBeanAttributes<?>>>();
+
+        for (Map.Entry<BeanArchiveInformation, List<AnnotatedType<?>>> atEntry : annotatedTypesPerBda.entrySet())
+        {
+            BeanArchiveInformation bdaInfo = atEntry.getKey();
+            List<AnnotatedType<?>> annotatedTypes = atEntry.getValue();
+
+            boolean onlyScopedBeans = BeanDiscoveryMode.SCOPED.equals(bdaInfo.getBeanDiscoveryMode());
+
+            final Map<AnnotatedType<?>, ExtendedBeanAttributes<?>> bdaBeanAttributes = new IdentityHashMap<AnnotatedType<?>, ExtendedBeanAttributes<?>>(annotatedTypes.size());
+            final Iterator<AnnotatedType<?>> iterator = annotatedTypes.iterator();
+            while (iterator.hasNext())
             {
-                if(isEjb || (ClassUtil.isConcrete(beanClass) || WebBeansUtil.isDecorator(at)) && isValidManagedBean(at))
+                final AnnotatedType<?> at = iterator.next();
+                final Class beanClass = at.getJavaClass();
+                final boolean isEjb = discoverEjb && EJBWebBeansConfigurator.isSessionBean(beanClass, webBeansContext);
+                try
                 {
-                    final BeanAttributesImpl tBeanAttributes = BeanAttributesBuilder.forContext(webBeansContext).newBeanAttibutes(at).build();
-                    final BeanAttributes<?> beanAttributes = webBeansContext.getWebBeansUtil().fireProcessBeanAttributes(at, at.getJavaClass(), tBeanAttributes);
-                    if (beanAttributes != null)
+                    if (isEjb || (ClassUtil.isConcrete(beanClass) || WebBeansUtil.isDecorator(at)) && isValidManagedBean(at))
                     {
-                        result.put(at, new AnnotatedTypeData(beanAttributes, isEjb));
+                        final BeanAttributesImpl tBeanAttributes = BeanAttributesBuilder.forContext(webBeansContext).newBeanAttibutes(at, onlyScopedBeans).build();
+                        if (tBeanAttributes != null)
+                        {
+                            final BeanAttributes<?> beanAttributes = webBeansContext.getWebBeansUtil().fireProcessBeanAttributes(at, at.getJavaClass(), tBeanAttributes);
+                            if (beanAttributes != null)
+                            {
+                                bdaBeanAttributes.put(at, new ExtendedBeanAttributes(beanAttributes, isEjb));
+                            }
+                        }
+                    }
+                    else
+                    {
+                        iterator.remove();
                     }
                 }
-                else
+                catch (final NoClassDefFoundError ncdfe)
                 {
-                    iterator.remove();
+                    logger.info("Skipping deployment of Class " + beanClass + "due to a NoClassDefFoundError: " + ncdfe.getMessage());
                 }
             }
-            catch (final NoClassDefFoundError ncdfe)
-            {
-                logger.info("Skipping deployment of Class " + beanClass + "due to a NoClassDefFoundError: " + ncdfe.getMessage());
-            }
+
+            beanAttributesPerBda.put(bdaInfo, bdaBeanAttributes);
         }
-        return result;
+
+
+        return beanAttributesPerBda;
     }
 
     private void validateDisposeParameters()
@@ -487,7 +533,6 @@ public class BeansDeployer
                 {
                     final Class<?> javaClass = annotatedType.getJavaClass();
                     interceptorsManager.addPriorityClazzInterceptor(javaClass, priority);
-                    // interceptorsManager.addEnabledInterceptorClass(javaClass);
                 }
             }
             if (annotatedType.getAnnotation(javax.decorator.Decorator.class) != null)
@@ -497,7 +542,6 @@ public class BeansDeployer
                 {
                     final Class<?> javaClass = annotatedType.getJavaClass();
                     decoratorsManager.addPriorityClazzDecorator(javaClass, priority);
-                    // decoratorsManager.addEnabledDecorator(javaClass);
                 }
             }
         }
@@ -880,13 +924,44 @@ public class BeansDeployer
     /**
      * Create AnnotatedTypes from the ClassPath via the ScannerService
      */
-    private List<AnnotatedType<?>> annotatedTypesFromClassPath(ScannerService scanner)
+    private Map<BeanArchiveInformation, List<AnnotatedType<?>>> annotatedTypesFromClassPath(ScannerService scanner)
     {
         logger.fine("Creating AnnotatedTypes from class files has started.");
 
-        // Start from the class
-        Set<Class<?>> classIndex = scanner.getBeanClasses();
+        Map<BeanArchiveInformation, List<AnnotatedType<?>>> annotatedTypesPerBda
+            = new HashMap<BeanArchiveInformation, List<AnnotatedType<?>>>();
+
+        if (scanner instanceof BdaScannerService)
+        {
+            Map<BeanArchiveInformation, Set<Class<?>>> beanClassesPerBda = ((BdaScannerService) scanner).getBeanClassesPerBda();
+
+            for (Map.Entry<BeanArchiveInformation, Set<Class<?>>> bdaEntry : beanClassesPerBda.entrySet())
+            {
+                BeanArchiveInformation bdaInfo = bdaEntry.getKey();
+                List<AnnotatedType<?>> annotatedTypes = annotatedTypesFromBdaClassPath(bdaEntry.getValue());
+                annotatedTypesPerBda.put(bdaEntry.getKey(), annotatedTypes);
+            }
+
+            // also add the rest of the class es to the default bda
+            // we also need this initialised in case annotatedTypes get added manually at a later step
+            annotatedTypesPerBda.put(defaultBeanArchiveInformation, annotatedTypesFromBdaClassPath(scanner.getBeanClasses()));
+        }
+        else
+        {
+            // this path is only for backward compat to older ScannerService implementations
+
+            Set<Class<?>> classIndex = scanner.getBeanClasses();
+            List<AnnotatedType<?>> annotatedTypes = annotatedTypesFromBdaClassPath(classIndex);
+
+            annotatedTypesPerBda.put(defaultBeanArchiveInformation, annotatedTypes);
+        }
+
+
+        return annotatedTypesPerBda;
+    }
 
+    private List<AnnotatedType<?>> annotatedTypesFromBdaClassPath(Set<Class<?>> classIndex)
+    {
         List<AnnotatedType<?>> annotatedTypes = new ArrayList<AnnotatedType<?>>();
 
         //Iterating over each class
@@ -1055,30 +1130,34 @@ public class BeansDeployer
     /**
      * Discovers and deploys classes from class path.
      * 
-     * @param annotatedTypes the AnnotatedTypes which got discovered so far and are not vetoed
+     * @param beanAttributesPerBda the AnnotatedTypes which got discovered so far and are not vetoed
      * @throws ClassNotFoundException if class not found
      */
-    protected void deployFromAnnotatedTypes(Map<AnnotatedType<?>, AnnotatedTypeData<?>> annotatedTypes)
+    protected void deployFromBeanAttributes( Map<BeanArchiveInformation, Map<AnnotatedType<?>, ExtendedBeanAttributes<?>>> beanAttributesPerBda)
     {
         logger.fine("Deploying configurations from class files has started.");
 
-        // Start from the class
-        for(Map.Entry<AnnotatedType<?>, AnnotatedTypeData<?>> annotatedType : annotatedTypes.entrySet())
+        for (Map<AnnotatedType<?>, ExtendedBeanAttributes<?>> beanAttributesMap : beanAttributesPerBda.values())
         {
-            try
-            {
-                deploySingleAnnotatedType(annotatedType.getKey(), annotatedType.getValue(), annotatedTypes);
-            }
-            catch (NoClassDefFoundError ncdfe)
+
+            // Start from the class
+            for (Map.Entry<AnnotatedType<?>, ExtendedBeanAttributes<?>> annotatedType : beanAttributesMap.entrySet())
             {
-                logger.info("Skipping deployment of Class " + annotatedType.getKey().getJavaClass() + "due to a NoClassDefFoundError: " + ncdfe.getMessage());
-            }
+                try
+                {
+                    deploySingleAnnotatedType(annotatedType.getKey(), annotatedType.getValue(), beanAttributesMap);
+                }
+                catch (NoClassDefFoundError ncdfe)
+                {
+                    logger.info("Skipping deployment of Class " + annotatedType.getKey().getJavaClass() + "due to a NoClassDefFoundError: " + ncdfe.getMessage());
+                }
 
-            // if the implClass already gets processed as part of the
-            // standard BDA scanning, then we don't need to 'additionally'
-            // deploy it anymore.
-            webBeansContext.getBeanManagerImpl().removeAdditionalAnnotatedType(annotatedType.getKey());
+                // if the implClass already gets processed as part of the
+                // standard BDA scanning, then we don't need to 'additionally'
+                // deploy it anymore.
+                webBeansContext.getBeanManagerImpl().removeAdditionalAnnotatedType(annotatedType.getKey());
 
+            }
         }
 
         logger.fine("Deploying configurations from class files has ended.");
@@ -1092,7 +1171,7 @@ public class BeansDeployer
      * 
      * @param annotatedTypeData the AnnotatedType representing the bean to be deployed with their already computed data
      */
-    private void deploySingleAnnotatedType(AnnotatedType annotatedType, AnnotatedTypeData annotatedTypeData, Map<AnnotatedType<?>, AnnotatedTypeData<?>> annotatedTypes)
+    private void deploySingleAnnotatedType(AnnotatedType annotatedType, ExtendedBeanAttributes annotatedTypeData, Map<AnnotatedType<?>, ExtendedBeanAttributes<?>> annotatedTypes)
     {
 
         Class beanClass = annotatedType.getJavaClass();
@@ -1160,7 +1239,8 @@ public class BeansDeployer
      *
      * @throws WebBeansDeploymentException if a problem occurs
      */
-    protected void deployFromXML(ScannerService scanner, Map<AnnotatedType<?>, AnnotatedTypeData<?>> preProcessing) throws WebBeansDeploymentException
+    protected void deployFromXML(ScannerService scanner)
+        throws WebBeansDeploymentException
     {
         logger.fine("Deploying configurations from XML files has started.");
 
@@ -1173,19 +1253,23 @@ public class BeansDeployer
 
             logger.fine("OpenWebBeans BeansDeployer configuring: " + url.toExternalForm());
 
-            BeanArchiveService.BeanArchiveInformation beanArchiveInformation = beanArchiveService.getBeanArchiveInformation(url);
+            BeanArchiveInformation beanArchiveInformation = beanArchiveService.getBeanArchiveInformation(url);
 
             configureDecorators(url, beanArchiveInformation.getDecorators());
             configureInterceptors(url, beanArchiveInformation.getInterceptors());
-            configureAlternatives(url, beanArchiveInformation.getAlternativeClasses(), false, preProcessing);
-            configureAlternatives(url, beanArchiveInformation.getAlternativeStereotypes(), true, preProcessing);
+            configureAlternatives(url, beanArchiveInformation.getAlternativeClasses(), false);
+            configureAlternatives(url, beanArchiveInformation.getAlternativeStereotypes(), true);
+            configureAllowProxying(url, beanArchiveInformation.getAllowProxyingClasses());
         }
 
         logger.fine("Deploying configurations from XML has ended successfully.");
     }
 
-    private void configureAlternatives(URL bdaLocation, List<String> alternatives, boolean isStereotype, Map<AnnotatedType<?>, AnnotatedTypeData<?>> preProcessing)
+    private void configureAlternatives(URL bdaLocation, List<String> alternatives, boolean isStereotype)
     {
+        AlternativesManager manager = webBeansContext.getAlternativesManager();
+        AnnotatedElementFactory annotatedElementFactory = webBeansContext.getAnnotatedElementFactory();
+
         // the alternatives in this beans.xml
         // this gets used to detect multiple definitions of the
         // same alternative in one beans.xml file.
@@ -1208,7 +1292,6 @@ public class BeansDeployer
             }
             else
             {
-                AlternativesManager manager = webBeansContext.getAlternativesManager();
                 if (isStereotype)
                 {
                     manager.addXmlStereoTypeAlternative(clazz);
@@ -1222,17 +1305,17 @@ public class BeansDeployer
                     }
                     else
                     {
-                        AnnotatedType annotatedType = webBeansContext.getAnnotatedElementFactory().getAnnotatedType(clazz);
+                        AnnotatedType annotatedType = annotatedElementFactory.getAnnotatedType(clazz);
                         if (annotatedType != null)
                         {
-                            AnnotatedTypeData data = preProcessing.get(annotatedType);
-                            if (data != null && data.beanAttributes.isAlternative())
+                            if (annotatedType.getAnnotation(Alternative.class) != null)
                             {
                                 manager.addXmlClazzAlternative(clazz);
+                                break;
                             }
                             else
                             {
-                                throw new WebBeansDeploymentException("Given alternative class : " + clazz.getName() + " is not decorated wih @Alternative" );
+                                throw new WebBeansDeploymentException("Given alternative class : " + clazz.getName() + " is not decorated wih @Alternative");
                             }
                         }
                     }
@@ -1345,6 +1428,15 @@ public class BeansDeployer
         }
     }
 
+    private void configureAllowProxying(URL url, List<String> allowProxyingClasses)
+    {
+        OpenWebBeansConfiguration owbConfiguration = webBeansContext.getOpenWebBeansConfiguration();
+        for (String allowProxyingClass : allowProxyingClasses)
+        {
+            owbConfiguration.addConfigListValue(OpenWebBeansConfiguration.ALLOW_PROXYING_PARAM, allowProxyingClass);
+        }
+    }
+
 
     /**
      * Gets error message for XML parsing of the current XML file.
@@ -1440,7 +1532,7 @@ public class BeansDeployer
      * Defines and configures managed bean.
      * @param <T> type info
      */
-    protected <T> void defineManagedBean(AnnotatedType<T> annotatedType, BeanAttributes<T> attributes, Map<AnnotatedType<?>, AnnotatedTypeData<?>> annotatedTypes)
+    protected <T> void defineManagedBean(AnnotatedType<T> annotatedType, BeanAttributes<T> attributes, Map<AnnotatedType<?>, ExtendedBeanAttributes<?>> annotatedTypes)
     {   
         //Fires ProcessInjectionTarget event for Java EE components instances
         //That supports injections but not managed beans
@@ -1625,12 +1717,12 @@ public class BeansDeployer
         webBeansContext.getWebBeansUtil().setInjectionTargetBeanEnableFlag(bean);
     }
 
-    private static class AnnotatedTypeData<T>
+    private static class ExtendedBeanAttributes<T>
     {
         private final BeanAttributes<T> beanAttributes;
         private final boolean isEjb;
 
-        public AnnotatedTypeData(final BeanAttributes<T> beanAttributes, final boolean isEjb)
+        public ExtendedBeanAttributes(final BeanAttributes<T> beanAttributes, final boolean isEjb)
         {
             this.beanAttributes = beanAttributes;
             this.isEjb = isEjb;

Modified: openwebbeans/branches/cdi-2.0/webbeans-impl/src/main/java/org/apache/webbeans/config/DeploymentValidationService.java
URL: http://svn.apache.org/viewvc/openwebbeans/branches/cdi-2.0/webbeans-impl/src/main/java/org/apache/webbeans/config/DeploymentValidationService.java?rev=1728163&r1=1728162&r2=1728163&view=diff
==============================================================================
--- openwebbeans/branches/cdi-2.0/webbeans-impl/src/main/java/org/apache/webbeans/config/DeploymentValidationService.java (original)
+++ openwebbeans/branches/cdi-2.0/webbeans-impl/src/main/java/org/apache/webbeans/config/DeploymentValidationService.java Tue Feb  2 17:48:14 2016
@@ -25,6 +25,7 @@ import java.lang.reflect.Constructor;
 import java.lang.reflect.Method;
 import java.lang.reflect.Modifier;
 import java.util.Set;
+import java.util.logging.Logger;
 
 import javax.enterprise.inject.Disposes;
 import javax.enterprise.inject.TransientReference;
@@ -42,14 +43,23 @@ import org.apache.webbeans.component.Pro
 import org.apache.webbeans.exception.WebBeansDeploymentException;
 import org.apache.webbeans.exception.helper.ViolationMessageBuilder;
 import org.apache.webbeans.intercept.InterceptorResolutionService.BeanInterceptorInfo;
+import org.apache.webbeans.logger.WebBeansLoggerFacade;
 import org.apache.webbeans.portable.InjectionTargetImpl;
 import org.apache.webbeans.util.SecurityUtil;
 
 public class DeploymentValidationService
 {
+    /**Logger instance*/
+    private static final Logger logger = WebBeansLoggerFacade.getLogger(DeploymentValidationService.class);
 
     private WebBeansContext webBeansContext;
 
+    /**
+     * Classes which are allowed to be proxies despite having a non-private, non-static final method
+     */
+    private Set<String> allowProxyingClasses = null;
+
+
     public DeploymentValidationService(WebBeansContext webBeansContext)
     {
         this.webBeansContext = webBeansContext;
@@ -62,13 +72,19 @@ public class DeploymentValidationService
      */
     public UnproxyableResolutionException validateProxyable(OwbBean<?> bean)
     {
+        if (allowProxyingClasses == null)
+        {
+            allowProxyingClasses = webBeansContext.getOpenWebBeansConfiguration().getConfigListValues(OpenWebBeansConfiguration.ALLOW_PROXYING_PARAM);
+        }
+
         // Unproxyable test for NormalScoped beans
         if (webBeansContext.getBeanManagerImpl().isNormalScope(bean.getScope()))
         {
             ViolationMessageBuilder violationMessage = ViolationMessageBuilder.newViolation();
 
             Class<?> beanClass = bean.getReturnType();
-            
+
+
             if(!beanClass.isInterface() && beanClass != Object.class)
             {
                 if(beanClass.isPrimitive())
@@ -91,7 +107,16 @@ public class DeploymentValidationService
                     String finalMethodName = hasNonPrivateFinalMethod(beanClass);
                     if (finalMethodName != null)
                     {
-                        violationMessage.addLine(beanClass.getName(), " has final method "+ finalMethodName + " CDI doesn't allow to proxy that.");
+                        if (allowProxyingClasses.contains(beanClass.getName()))
+                        {
+                            logger.info(beanClass.getName() +  " has final method " + finalMethodName + ". CDI doesn't allow to proxy that." +
+                                " Continuing because the class is explicitly configured to be treated as proxyable." +
+                                " Final methods shall not get invoked on this proxy!");
+                        }
+                        else
+                        {
+                            violationMessage.addLine(beanClass.getName(), " has final method " + finalMethodName + " CDI doesn't allow to proxy that.");
+                        }
                     }
 
 

Modified: openwebbeans/branches/cdi-2.0/webbeans-impl/src/main/java/org/apache/webbeans/config/OpenWebBeansConfiguration.java
URL: http://svn.apache.org/viewvc/openwebbeans/branches/cdi-2.0/webbeans-impl/src/main/java/org/apache/webbeans/config/OpenWebBeansConfiguration.java?rev=1728163&r1=1728162&r2=1728163&view=diff
==============================================================================
--- openwebbeans/branches/cdi-2.0/webbeans-impl/src/main/java/org/apache/webbeans/config/OpenWebBeansConfiguration.java (original)
+++ openwebbeans/branches/cdi-2.0/webbeans-impl/src/main/java/org/apache/webbeans/config/OpenWebBeansConfiguration.java Tue Feb  2 17:48:14 2016
@@ -18,14 +18,19 @@
  */
 package org.apache.webbeans.config;
 
+import java.io.IOException;
 import java.security.AccessController;
 import java.security.PrivilegedAction;
+import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Collections;
+import java.util.HashMap;
 import java.util.HashSet;
+import java.util.List;
 import java.util.Map;
 import java.util.Properties;
 import java.util.Set;
+import java.util.logging.Level;
 import java.util.logging.Logger;
 
 import org.apache.webbeans.exception.WebBeansConfigurationException;
@@ -33,7 +38,7 @@ import org.apache.webbeans.logger.WebBea
 
 /**
  * Defines configuration for OpenWebBeans.
- *
+ * 
  * The algorithm is easy:
  * <ul>
  * <li>Load all properties you can find with the name (META-INF/openwebbeans/openwebbeans.properties),</li>
@@ -49,13 +54,22 @@ public class OpenWebBeansConfiguration
     /**Logger instance*/
     private static final Logger logger = WebBeansLoggerFacade.getLogger(OpenWebBeansConfiguration.class);
 
-    /**Conversation periodic delay in ms.*/
+    /**
+     * Conversation periodic delay in ms. This is not used by OWB out of the box.
+     * Some Containers might implement it though.
+     */
     public static final String CONVERSATION_PERIODIC_DELAY = "org.apache.webbeans.conversation.Conversation.periodicDelay";
-
+    
     /**Timeout interval in ms*/
     public static final String CONVERSATION_TIMEOUT_INTERVAL = "org.apache.webbeans.conversation.Conversation.timeoutInterval";
 
     /**
+     * Environment property which comma separated list of classes which
+     * should NOT fail with UnproxyableResolutionException
+     */
+    public static final String ALLOW_PROXYING_PARAM = "javax.enterprise.inject.allowProxying.classes";
+
+    /**
      * Lifycycle methods like {@link javax.annotation.PostConstruct} and
      * {@link javax.annotation.PreDestroy} must not define a checked Exception
      * regarding to the spec. But this is often unnecessary restrictive so we
@@ -65,34 +79,34 @@ public class OpenWebBeansConfiguration
 
     /**Use EJB Discovery or not*/
     public static final String USE_EJB_DISCOVERY = "org.apache.webbeans.spi.deployer.useEjbMetaDataDiscoveryService";
-
+    
     /**Container lifecycle*/
     public static final String CONTAINER_LIFECYCLE = "org.apache.webbeans.spi.ContainerLifecycle";
-
+    
     /**JNDI Service SPI*/
-    public static final String JNDI_SERVICE = "org.apache.webbeans.spi.JNDIService";
-
+    public static final String JNDI_SERVICE = "org.apache.webbeans.spi.JNDIService";    
+    
     /**Scanner Service*/
     public static final String SCANNER_SERVICE = "org.apache.webbeans.spi.ScannerService";
 
     /**Contexts Service*/
     public static final String CONTEXTS_SERVICE = "org.apache.webbeans.spi.ContextsService";
-
+    
     /**Conversation Service*/
     public static final String CONVERSATION_SERVICE = "org.apache.webbeans.spi.ConversationService";
-
+    
     /**Resource Injection Service*/
     public static final String RESOURCE_INJECTION_SERVICE = "org.apache.webbeans.spi.ResourceInjectionService";
-
+    
     /**Security Service*/
     public static final String SECURITY_SERVICE = "org.apache.webbeans.spi.SecurityService";
-
+    
     /**Validator Service*/
     public static final String VALIDATOR_SERVICE = "org.apache.webbeans.spi.ValidatorService";
-
+    
     /**Transaction Service*/
     public static final String TRANSACTION_SERVICE = "org.apache.webbeans.spi.TransactionService";
-
+    
     /**Application is core JSP*/
     public static final String APPLICATION_IS_JSP = "org.apache.webbeans.application.jsp";
 
@@ -162,6 +176,23 @@ public class OpenWebBeansConfiguration
     private Set<String> ignoredInterfaces;
 
     /**
+     * All configured lists per key.
+     *
+     * For a single key the following configuration sources will get parsed:
+     * <ul>
+     *     <li>all {@link #DEFAULT_CONFIG_PROPERTIES_NAME} files</li>
+     *     <li>{@code System.getProperties()}</li>
+     *     <li>{@code System.env()}</li>
+     * </ul>
+     *
+     * All the found values will get split by comma (',') and all trimmed values
+     * will get stored in a Set.
+     *
+     */
+    private Map<String, Set<String>> configuredLists = new HashMap<String, Set<String>>();
+
+
+    /**
      * you can configure this externally as well.
      *
      * @param properties
@@ -183,6 +214,7 @@ public class OpenWebBeansConfiguration
     }
 
 
+
     /**
      * (re)read the configuration from the resources in the classpath.
      * @see #DEFAULT_CONFIG_PROPERTIES_NAME
@@ -204,6 +236,27 @@ public class OpenWebBeansConfiguration
 
     }
 
+    /**
+     * Take the given commaSeparatedVals and spit them by ',' and trim them.
+     * @return all trimmed values or an empty list
+     */
+    public List<String> splitValues(String commaSeparatedVals)
+    {
+        ArrayList<String> values = new ArrayList<String>();
+        if (commaSeparatedVals != null)
+        {
+            for (String value : commaSeparatedVals.split(","))
+            {
+                value = value.trim();
+                if (!value.isEmpty())
+                {
+                    values.add(value);
+                }
+            }
+        }
+        return values;
+    }
+
     private void overrideWithGlobalSettings(Properties configProperties)
     {
         logger.fine("Overriding properties from System and Env properties");
@@ -257,7 +310,7 @@ public class OpenWebBeansConfiguration
     {
         return configProperties.getProperty(key);
     }
-
+    
     /**
      * Gets property value.
      * @param key
@@ -268,8 +321,8 @@ public class OpenWebBeansConfiguration
     {
         return configProperties.getProperty(key, defaultValue);
     }
-
-
+    
+    
     /**
      * Sets given property.
      * @param key property name
@@ -279,7 +332,7 @@ public class OpenWebBeansConfiguration
     {
         configProperties.put(key, value);
     }
-
+    
 
     /**
      * Gets jsp property.
@@ -288,10 +341,10 @@ public class OpenWebBeansConfiguration
     public boolean isJspApplication()
     {
         String value = getProperty(APPLICATION_IS_JSP);
-
+        
         return Boolean.valueOf(value);
     }
-
+    
     /**
      * Gets conversation supports property.
      * @return true if supports
@@ -299,7 +352,7 @@ public class OpenWebBeansConfiguration
     public boolean supportsConversation()
     {
         String value = getProperty(APPLICATION_SUPPORTS_CONVERSATION);
-
+        
         return Boolean.valueOf(value);
     }
 
@@ -320,6 +373,68 @@ public class OpenWebBeansConfiguration
         return ignoredInterfaces;
     }
 
+    /**
+     * Scan all openwebbeans.properties files + system properties +
+     * syste.env for the given key.
+     * If the key is comma separated then use the separate tokens.
+     * All the values get put into a big set.
+     */
+    public synchronized Set<String> getConfigListValues(String keyName)
+    {
+        Set<String> allValues = configuredLists.get(keyName);
+        if (allValues != null)
+        {
+            return allValues;
+        }
+
+        allValues = new HashSet<String>();
+        try
+        {
+            List<Properties> properties = PropertyLoader.loadAllProperties(DEFAULT_CONFIG_PROPERTIES_NAME);
+            if (properties != null)
+            {
+                for (Properties property : properties)
+                {
+                    String values = (String) property.get(keyName);
+                    allValues.addAll(splitValues(values));
+                }
+            }
+        }
+        catch (IOException e)
+        {
+            logger.log(Level.SEVERE, "Error while loading the propertyFile " + DEFAULT_CONFIG_PROPERTIES_NAME, e);
+            return Collections.EMPTY_SET;
+        }
+
+        // search for the key in the properties
+        String value = System.getProperty(keyName);
+        allValues.addAll(splitValues(value));
+
+        // search for the key in the environment
+        String envKeyName = keyName.toUpperCase().replace(".", "_");
+        value = System.getenv(envKeyName);
+        allValues.addAll(splitValues(value));
+
+        configuredLists.put(keyName, allValues);
+
+        return allValues;
+    }
+
+    /**
+     * Add a configuration value to the Set of configured values registered
+     * under the keyName.
+     *
+     * Calling this method ensures that all the configured values are first
+     * read from the environment and configuration properties.
+     *
+     * @see #getConfigListValues(String) get's called internally to insure the list is initialised
+     */
+    public synchronized void addConfigListValue(String keyName, String value)
+    {
+        Set<String> configListValues = getConfigListValues(keyName);
+        configListValues.add(value);
+    }
+
     public boolean supportsInterceptionOnProducers()
     {
         return "true".equals(getProperty(PRODUCER_INTERCEPTION_SUPPORT, "true"));

Modified: openwebbeans/branches/cdi-2.0/webbeans-impl/src/main/java/org/apache/webbeans/config/PropertyLoader.java
URL: http://svn.apache.org/viewvc/openwebbeans/branches/cdi-2.0/webbeans-impl/src/main/java/org/apache/webbeans/config/PropertyLoader.java?rev=1728163&r1=1728162&r2=1728163&view=diff
==============================================================================
--- openwebbeans/branches/cdi-2.0/webbeans-impl/src/main/java/org/apache/webbeans/config/PropertyLoader.java (original)
+++ openwebbeans/branches/cdi-2.0/webbeans-impl/src/main/java/org/apache/webbeans/config/PropertyLoader.java Tue Feb  2 17:48:14 2016
@@ -95,7 +95,7 @@ public final class PropertyLoader
         }
     }
 
-    private static List<Properties> loadAllProperties(String propertyFileName)
+    public static List<Properties> loadAllProperties(String propertyFileName)
             throws IOException
     {
         ClassLoader cl = WebBeansUtil.getCurrentClassLoader();

Modified: openwebbeans/branches/cdi-2.0/webbeans-impl/src/main/java/org/apache/webbeans/config/WebBeansContext.java
URL: http://svn.apache.org/viewvc/openwebbeans/branches/cdi-2.0/webbeans-impl/src/main/java/org/apache/webbeans/config/WebBeansContext.java?rev=1728163&r1=1728162&r2=1728163&view=diff
==============================================================================
--- openwebbeans/branches/cdi-2.0/webbeans-impl/src/main/java/org/apache/webbeans/config/WebBeansContext.java (original)
+++ openwebbeans/branches/cdi-2.0/webbeans-impl/src/main/java/org/apache/webbeans/config/WebBeansContext.java Tue Feb  2 17:48:14 2016
@@ -18,12 +18,17 @@
  */
 package org.apache.webbeans.config;
 
+import java.io.Closeable;
+import java.io.IOException;
 import java.lang.reflect.Constructor;
 import java.lang.reflect.InvocationTargetException;
+import java.util.Collection;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
 import java.util.Properties;
+import java.util.logging.Level;
+import java.util.logging.Logger;
 
 import org.apache.webbeans.annotation.AnnotationManager;
 import org.apache.webbeans.container.BeanManagerImpl;
@@ -38,6 +43,7 @@ import org.apache.webbeans.inject.impl.I
 import org.apache.webbeans.intercept.InterceptorResolutionService;
 import org.apache.webbeans.intercept.InterceptorUtil;
 import org.apache.webbeans.intercept.InterceptorsManager;
+import org.apache.webbeans.logger.WebBeansLoggerFacade;
 import org.apache.webbeans.plugins.PluginLoader;
 import org.apache.webbeans.portable.AnnotatedElementFactory;
 import org.apache.webbeans.portable.events.ExtensionLoader;
@@ -64,6 +70,8 @@ import org.apache.webbeans.util.WebBeans
  */
 public class WebBeansContext
 {
+    private static final Logger logger = WebBeansLoggerFacade.getLogger(WebBeansContext.class);
+
     private final Map<Class<?>, Object> managerMap = new HashMap<Class<?>, Object>();
 
     private final Map<Class<?>, Object> serviceMap = new HashMap<Class<?>, Object>();
@@ -446,9 +454,35 @@ public class WebBeansContext
         }
     }
 
+    /**
+     * Clear and destroy the whole WebBeansContext.
+     * This will also properly destroy all SPI services
+     */
     public void clear()
     {
+        destroyServices(managerMap.values());
+        destroyServices(serviceMap.values());
+
         managerMap.clear();
+        serviceMap.clear();
+    }
+
+    private void destroyServices(Collection<Object> services)
+    {
+        for (Object spiService : services)
+        {
+            if (spiService instanceof Closeable)
+            {
+                try
+                {
+                    ((Closeable) spiService).close();
+                }
+                catch (IOException e)
+                {
+                    logger.log(Level.SEVERE, "Error while destroying SPI service " + spiService.getClass().getName(), e);
+                }
+            }
+        }
     }
 
     public LoaderService getLoaderService()

Modified: openwebbeans/branches/cdi-2.0/webbeans-impl/src/main/java/org/apache/webbeans/container/BeanCacheKey.java
URL: http://svn.apache.org/viewvc/openwebbeans/branches/cdi-2.0/webbeans-impl/src/main/java/org/apache/webbeans/container/BeanCacheKey.java?rev=1728163&r1=1728162&r2=1728163&view=diff
==============================================================================
--- openwebbeans/branches/cdi-2.0/webbeans-impl/src/main/java/org/apache/webbeans/container/BeanCacheKey.java (original)
+++ openwebbeans/branches/cdi-2.0/webbeans-impl/src/main/java/org/apache/webbeans/container/BeanCacheKey.java Tue Feb  2 17:48:14 2016
@@ -18,6 +18,7 @@
  */
 package org.apache.webbeans.container;
 
+import org.apache.webbeans.annotation.EmptyAnnotationLiteral;
 import org.apache.webbeans.util.AnnotationUtil;
 
 import javax.enterprise.util.Nonbinding;
@@ -177,96 +178,16 @@ public final class BeanCacheKey
     }
 
     /**
-     * Calculate the hashCode() of a qualifier, which ignores {@link Nonbinding} members.
+     * Calculate the hashCode() of a qualifier.
+     * We do not do any in-depth hashCode down to member hashes
+     * but only use the hashcode of the AnnotationType itself.
+     * This is WAY faster and spreads well enough in practice.
+     * We can do this as we do not need to return a perfectly unique
+     * result anyway.
      */
     private int getQualifierHashCode(Annotation a)
     {
-        Class annotationClass = getAnnotationClass(a.getClass());
-
-        if (annotationClass == null)
-        {
-            return getTypeHashCode(a.getClass());
-        }
-
-        // the hashCode of an Annotation is calculated solely via the hashCodes
-        // of it's members. If there are no members, it is 0.
-        // thus we first need to get the annotation-class hashCode
-        int hashCode = getTypeHashCode(annotationClass);
-
-        // and now add the hashCode of all it's Nonbinding members
-        // the following algorithm is defined by the Annotation class definition
-        // see the JavaDoc for Annotation!
-        // we only change it so far that we skip evaluating @Nonbinding members
-        final Method[] members = annotationClass.getDeclaredMethods();
-
-        for (Method member : members)
-        {
-            if (member.isAnnotationPresent(Nonbinding.class))
-            {
-                // ignore the non binding
-                continue;
-            }
-
-            // Member value
-            final Object object = callMethod(a, member);
-            final int value;
-            if(object.getClass().isArray())
-            {
-                Class<?> type = object.getClass().getComponentType();
-                if(type.isPrimitive())
-                {
-                    if(Long.TYPE == type)
-                    {
-                        value = Arrays.hashCode((long[]) object);
-                    }
-                    else if(Integer.TYPE == type)
-                    {
-                        value = Arrays.hashCode((int[])object);
-                    }
-                    else if(Short.TYPE == type)
-                    {
-                        value = Arrays.hashCode((short[])object);
-                    }
-                    else if(Double.TYPE == type)
-                    {
-                        value = Arrays.hashCode((double[])object);
-                    }
-                    else if(Float.TYPE == type)
-                    {
-                        value = Arrays.hashCode((float[])object);
-                    }
-                    else if(Boolean.TYPE == type)
-                    {
-                        value = Arrays.hashCode((boolean[])object);
-                    }
-                    else if(Byte.TYPE == type)
-                    {
-                        value = Arrays.hashCode((byte[])object);
-                    }
-                    else if(Character.TYPE == type)
-                    {
-                        value = Arrays.hashCode((char[])object);
-                    }
-                    else
-                    {
-                        value = 0;
-                    }
-                }
-                else
-                {
-                    value = Arrays.hashCode((Object[])object);
-                }
-            }
-            else
-            {
-                value = object.hashCode();
-            }
-
-            hashCode = 29 * hashCode + value;
-            hashCode = 29 * hashCode + member.getName().hashCode();
-        }
-
-        return hashCode;
+        return a.annotationType().hashCode();
     }
 
     /**
@@ -277,17 +198,6 @@ public final class BeanCacheKey
         return ANNOTATION_COMPARATOR.compare(qualifier1, qualifier2) == 0;
     }
 
-    private static Class getAnnotationClass(Class a)
-    {
-        for (Class i : a.getInterfaces())
-        {
-            if (i.isAnnotation())
-            {
-                return i;
-            }
-        }
-        return null;
-    }
 
     /**
      * Helper method for calculating the hashCode of an annotation.
@@ -338,6 +248,13 @@ public final class BeanCacheKey
             {
                 return temp;
             }
+            if (annotation1 instanceof EmptyAnnotationLiteral || annotation2 instanceof EmptyAnnotationLiteral)
+            {
+                // if any of those 2 annotations are known to have no members
+                // then we can immediately return as we know the 2 annotations mean the same
+                return 0;
+            }
+
             final Method[] member1 = type1.getDeclaredMethods();
             final Method[] member2 = type2.getDeclaredMethods();
 

Modified: openwebbeans/branches/cdi-2.0/webbeans-impl/src/main/java/org/apache/webbeans/container/BeanManagerImpl.java
URL: http://svn.apache.org/viewvc/openwebbeans/branches/cdi-2.0/webbeans-impl/src/main/java/org/apache/webbeans/container/BeanManagerImpl.java?rev=1728163&r1=1728162&r2=1728163&view=diff
==============================================================================
--- openwebbeans/branches/cdi-2.0/webbeans-impl/src/main/java/org/apache/webbeans/container/BeanManagerImpl.java (original)
+++ openwebbeans/branches/cdi-2.0/webbeans-impl/src/main/java/org/apache/webbeans/container/BeanManagerImpl.java Tue Feb  2 17:48:14 2016
@@ -1413,6 +1413,12 @@ public class BeanManagerImpl implements
         passivationBeans.clear();
         webBeansContext.getInterceptorsManager().clear();
         webBeansContext.getDecoratorsManager().clear();
+        webBeansContext.getAnnotatedElementFactory().clear();
+
+        injectionResolver.clearCaches();
+
+        // finally destroy all SPI services
+        webBeansContext.clear();
     }
 
     public void clearCacheProxies()

Modified: openwebbeans/branches/cdi-2.0/webbeans-impl/src/main/java/org/apache/webbeans/corespi/scanner/AbstractMetaDataDiscovery.java
URL: http://svn.apache.org/viewvc/openwebbeans/branches/cdi-2.0/webbeans-impl/src/main/java/org/apache/webbeans/corespi/scanner/AbstractMetaDataDiscovery.java?rev=1728163&r1=1728162&r2=1728163&view=diff
==============================================================================
--- openwebbeans/branches/cdi-2.0/webbeans-impl/src/main/java/org/apache/webbeans/corespi/scanner/AbstractMetaDataDiscovery.java (original)
+++ openwebbeans/branches/cdi-2.0/webbeans-impl/src/main/java/org/apache/webbeans/corespi/scanner/AbstractMetaDataDiscovery.java Tue Feb  2 17:48:14 2016
@@ -27,9 +27,9 @@ import org.apache.webbeans.corespi.scann
 import org.apache.webbeans.exception.WebBeansDeploymentException;
 import org.apache.webbeans.logger.WebBeansLoggerFacade;
 import org.apache.webbeans.spi.BDABeansXmlScanner;
+import org.apache.webbeans.spi.BdaScannerService;
 import org.apache.webbeans.spi.BeanArchiveService;
 import org.apache.webbeans.spi.BeanArchiveService.BeanDiscoveryMode;
-import org.apache.webbeans.spi.ScannerService;
 import org.apache.webbeans.util.ClassUtil;
 import org.apache.webbeans.util.UrlSet;
 import org.apache.webbeans.util.WebBeansUtil;
@@ -39,12 +39,12 @@ import org.apache.xbean.finder.ClassLoad
 import java.io.IOException;
 import java.lang.annotation.Annotation;
 import java.net.URL;
-import java.util.ArrayList;
 import java.util.Collections;
 import java.util.Enumeration;
 import java.util.HashMap;
 import java.util.HashSet;
 import java.util.Iterator;
+import java.util.List;
 import java.util.Map;
 import java.util.Set;
 import java.util.logging.Level;
@@ -52,7 +52,7 @@ import java.util.logging.Logger;
 
 
 
-public abstract class AbstractMetaDataDiscovery implements ScannerService
+public abstract class AbstractMetaDataDiscovery implements BdaScannerService
 {
     protected static final Logger logger = WebBeansLoggerFacade.getLogger(AbstractMetaDataDiscovery.class);
 
@@ -78,6 +78,12 @@ public abstract class AbstractMetaDataDi
      */
     private final Map<String, URL> beanDeploymentUrls = new HashMap<String, URL>();
 
+    /**
+     * for having proper scan mode 'SCOPED' support we need to know which bean class
+     * has which beans.xml.
+     */
+    private Map<BeanArchiveService.BeanArchiveInformation, Set<Class<?>>> beanClassesPerBda;
+
     protected String[] scanningExcludes;
 
     protected ClassLoader loader;
@@ -113,6 +119,7 @@ public abstract class AbstractMetaDataDi
 
     /**
      * @return list of beans.xml locations or implicit bean archives
+     * @deprecated just here for backward compat reasons
      */
     protected Iterable<URL> getBeanArchiveUrls()
     {
@@ -315,21 +322,10 @@ public abstract class AbstractMetaDataDi
     {
         if (scanningExcludes == null)
         {
-            String scanningExcludesProperty =
-                    WebBeansContext.currentInstance().getOpenWebBeansConfiguration().getProperty(OpenWebBeansConfiguration.SCAN_EXCLUSION_PATHS);
-            ArrayList<String> scanningExcludesList = new ArrayList<String>();
-            if (scanningExcludesProperty != null)
-            {
-                for (String scanningExclude : scanningExcludesProperty.split(","))
-                {
-                    scanningExclude = scanningExclude.trim();
-                    if (!scanningExclude.isEmpty())
-                    {
-                        scanningExcludesList.add(scanningExclude);
-                    }
-                }
-            }
-            scanningExcludes = scanningExcludesList.toArray(new String[scanningExcludesList.size()]);
+            OpenWebBeansConfiguration owbConfiguration = WebBeansContext.currentInstance().getOpenWebBeansConfiguration();
+            String scanningExcludesProperty = owbConfiguration.getProperty(OpenWebBeansConfiguration.SCAN_EXCLUSION_PATHS);
+            List<String> excludes = owbConfiguration.splitValues(scanningExcludesProperty);
+            scanningExcludes = excludes.toArray(new String[excludes.size()]);
         }
     }
 
@@ -352,59 +348,74 @@ public abstract class AbstractMetaDataDi
             beanArchiveService = webBeansContext.getBeanArchiveService();
         }
 
+        // just to trigger the creation
         beanArchiveService.getBeanArchiveInformation(beanArchiveUrl);
     }
 
-    /* (non-Javadoc)
-     * @see org.apache.webbeans.corespi.ScannerService#getBeanClasses()
+
+    /**
+     * This method only gets called if the initialisation is done already.
+     * It will collect all the classes from all the BDAs it can find.
      */
-    @Override
-    public Set<Class<?>> getBeanClasses()
+    public Map<BeanArchiveService.BeanArchiveInformation, Set<Class<?>>> getBeanClassesPerBda()
     {
-        final Set<Class<?>> classSet = new HashSet<Class<?>>();
-        for (CdiArchive.FoundClasses foundClasses : archive.classesByUrl().values())
+        if (beanClassesPerBda == null)
         {
-            boolean scanModeAnnotated = BeanDiscoveryMode.ANNOTATED.equals(foundClasses.getBeanArchiveInfo().getBeanDiscoveryMode());
-            for(String className : foundClasses.getClassNames())
+            beanClassesPerBda = new HashMap<BeanArchiveService.BeanArchiveInformation, Set<Class<?>>>();
+
+            for (CdiArchive.FoundClasses foundClasses : archive.classesByUrl().values())
             {
-                try
+                Set<Class<?>> classSet = new HashSet<Class<?>>();
+                boolean scanModeAnnotated = BeanDiscoveryMode.ANNOTATED.equals(foundClasses.getBeanArchiveInfo().getBeanDiscoveryMode());
+                for (String className : foundClasses.getClassNames())
                 {
-                    if (scanModeAnnotated)
+                    try
                     {
-                        // in this case we need to find out whether we should keep this class in the Archive
-                        AnnotationFinder.ClassInfo classInfo = finder.getClassInfo(className);
-                        if (classInfo == null || !isBeanAnnotatedClass(classInfo))
+                        if (scanModeAnnotated)
                         {
-                            continue;
+                            // in this case we need to find out whether we should keep this class in the Archive
+                            AnnotationFinder.ClassInfo classInfo = finder.getClassInfo(className);
+                            if (classInfo == null || !isBeanAnnotatedClass(classInfo))
+                            {
+                                continue;
+                            }
                         }
-                    }
 
-                    Class<?> clazz = ClassUtil.getClassFromName(className);
-                    if (clazz != null)
-                    {
-
-                        // try to provoke a NoClassDefFoundError exception which is thrown
-                        // if some dependencies of the class are missing
-                        clazz.getDeclaredFields();
-                        clazz.getDeclaredMethods();
-
-                        // we can add this class cause it has been loaded completely
-                        classSet.add(clazz);
+                        Class<?> clazz = ClassUtil.getClassFromName(className);
+                        if (clazz != null)
+                        {
+                            // try to provoke a NoClassDefFoundError exception which is thrown
+                            // if some dependencies of the class are missing
+                            clazz.getDeclaredFields();
 
+                            // we can add this class cause it has been loaded completely
+                            classSet.add(clazz);
+                        }
                     }
-                }
-                catch (NoClassDefFoundError e)
-                {
-                    if (logger.isLoggable(Level.WARNING))
+                    catch (NoClassDefFoundError e)
                     {
-                        logger.log(Level.WARNING, OWBLogConst.WARN_0018, new Object[] { className, e.toString() });
+                        if (logger.isLoggable(Level.WARNING))
+                        {
+                            logger.log(Level.WARNING, OWBLogConst.WARN_0018, new Object[]{className, e.toString()});
+                        }
                     }
                 }
+
+                beanClassesPerBda.put(foundClasses.getBeanArchiveInfo(), classSet);
             }
 
         }
+        return beanClassesPerBda;
+    }
 
-        return classSet;
+    /* (non-Javadoc)
+     * @see org.apache.webbeans.corespi.ScannerService#getBeanClasses()
+     */
+    @Override
+    public Set<Class<?>> getBeanClasses()
+    {
+        // do nothing, getBeanClasses() should not get invoked anymore
+        return Collections.EMPTY_SET;
     }
 
     /**