You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@isis.apache.org by da...@apache.org on 2015/07/29 22:27:09 UTC

isis git commit: ISIS-1182: spiking using fast-classpath-scanner.

Repository: isis
Updated Branches:
  refs/heads/ISIS-1182 [created] f311839c2


ISIS-1182: spiking using fast-classpath-scanner.


Project: http://git-wip-us.apache.org/repos/asf/isis/repo
Commit: http://git-wip-us.apache.org/repos/asf/isis/commit/f311839c
Tree: http://git-wip-us.apache.org/repos/asf/isis/tree/f311839c
Diff: http://git-wip-us.apache.org/repos/asf/isis/diff/f311839c

Branch: refs/heads/ISIS-1182
Commit: f311839c2fecef433bfd8dd6e1e3427bc5facf64
Parents: c3d3480
Author: Dan Haywood <da...@haywood-associates.co.uk>
Authored: Wed Jul 29 21:26:38 2015 +0100
Committer: Dan Haywood <da...@haywood-associates.co.uk>
Committed: Wed Jul 29 21:26:38 2015 +0100

----------------------------------------------------------------------
 core/applib/pom.xml                             | 13 ++++
 ...scoveryServiceUsingFastClasspathScanner.java | 68 +++++++++++++++++
 .../ClassDiscoveryServiceUsingReflections.java  | 14 +---
 .../ServicesInstallerFromAnnotation.java        | 77 +++++++++++++++++++-
 4 files changed, 157 insertions(+), 15 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/isis/blob/f311839c/core/applib/pom.xml
----------------------------------------------------------------------
diff --git a/core/applib/pom.xml b/core/applib/pom.xml
index 2e2b100..f101151 100644
--- a/core/applib/pom.xml
+++ b/core/applib/pom.xml
@@ -168,6 +168,19 @@
             <optional>true</optional>
         </dependency>
 
+        <!-- as used by ClassDiscoveryServiceUsingFastClasspathScanner -->
+        <dependency>
+            <groupId>io.github.lukehutch</groupId>
+            <artifactId>fast-classpath-scanner</artifactId>
+            <version>1.4.1</version>
+            <exclusions>
+                <exclusion>
+                    <groupId>junit</groupId>
+                    <artifactId>junit</artifactId>
+                </exclusion>
+            </exclusions>
+        </dependency>
+
     </dependencies>
 
 </project>

http://git-wip-us.apache.org/repos/asf/isis/blob/f311839c/core/applib/src/main/java/org/apache/isis/applib/services/classdiscovery/ClassDiscoveryServiceUsingFastClasspathScanner.java
----------------------------------------------------------------------
diff --git a/core/applib/src/main/java/org/apache/isis/applib/services/classdiscovery/ClassDiscoveryServiceUsingFastClasspathScanner.java b/core/applib/src/main/java/org/apache/isis/applib/services/classdiscovery/ClassDiscoveryServiceUsingFastClasspathScanner.java
new file mode 100644
index 0000000..daa081a
--- /dev/null
+++ b/core/applib/src/main/java/org/apache/isis/applib/services/classdiscovery/ClassDiscoveryServiceUsingFastClasspathScanner.java
@@ -0,0 +1,68 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *        http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+package org.apache.isis.applib.services.classdiscovery;
+
+import java.util.Set;
+
+import com.google.common.collect.Sets;
+
+import org.apache.isis.applib.AbstractService;
+import org.apache.isis.applib.annotation.DomainService;
+import org.apache.isis.applib.annotation.NatureOfService;
+import org.apache.isis.applib.annotation.Programmatic;
+
+import io.github.lukehutch.fastclasspathscanner.FastClasspathScanner;
+import io.github.lukehutch.fastclasspathscanner.matchprocessor.SubclassMatchProcessor;
+
+/**
+ * This utility service supports the dynamic discovery of classes from the classpath.  One service that uses this
+ * is the <tt>FixtureScripts</tt> domain service.
+ *
+ */
+@DomainService(
+        nature = NatureOfService.DOMAIN
+)
+public class ClassDiscoveryServiceUsingFastClasspathScanner
+            extends AbstractService
+            implements ClassDiscoveryService2 {
+
+
+    @Programmatic
+    @Override
+    public <T> Set<Class<? extends T>> findSubTypesOfClasses(Class<T> type) {
+        throw new IllegalStateException("Shouldn't be called as this class implements ClassDiscoveryService2");
+    }
+
+    @Programmatic
+    @Override
+    public <T> Set<Class<? extends T>> findSubTypesOfClasses(Class<T> type, String packagePrefix) {
+        final Set<Class<? extends T>> classes = Sets.newLinkedHashSet();
+        new FastClasspathScanner(packagePrefix)
+                .matchSubclassesOf(type, new SubclassMatchProcessor<T>() {
+                    @Override
+                    public void processMatch(final Class<? extends T> aClass) {
+                        classes.add(aClass);
+                    }
+                })
+                .scan();
+        return classes;
+    }
+
+
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/isis/blob/f311839c/core/applib/src/main/java/org/apache/isis/applib/services/classdiscovery/ClassDiscoveryServiceUsingReflections.java
----------------------------------------------------------------------
diff --git a/core/applib/src/main/java/org/apache/isis/applib/services/classdiscovery/ClassDiscoveryServiceUsingReflections.java b/core/applib/src/main/java/org/apache/isis/applib/services/classdiscovery/ClassDiscoveryServiceUsingReflections.java
index e23a48d..c9a12ba 100644
--- a/core/applib/src/main/java/org/apache/isis/applib/services/classdiscovery/ClassDiscoveryServiceUsingReflections.java
+++ b/core/applib/src/main/java/org/apache/isis/applib/services/classdiscovery/ClassDiscoveryServiceUsingReflections.java
@@ -26,30 +26,22 @@ import java.util.Arrays;
 import java.util.Collections;
 import java.util.List;
 import java.util.Set;
+
 import com.google.common.collect.Lists;
+
 import org.reflections.Reflections;
 import org.reflections.scanners.SubTypesScanner;
 import org.reflections.util.ClasspathHelper;
 import org.reflections.vfs.SystemDir;
 import org.reflections.vfs.Vfs;
+
 import org.apache.isis.applib.AbstractService;
-import org.apache.isis.applib.annotation.DomainService;
-import org.apache.isis.applib.annotation.NatureOfService;
 import org.apache.isis.applib.annotation.Programmatic;
 
 /**
  * This utility service supports the dynamic discovery of classes from the classpath.  One service that uses this
  * is the <tt>FixtureScripts</tt> domain service.
- *
- * <p>
- * This service has no UI and there is only one implementation (this class) in applib, so it is annotated with
- * {@link org.apache.isis.applib.annotation.DomainService}.  This means that it is automatically registered and
- * available for use; no further configuration is required.
- * </p>
  */
-@DomainService(
-        nature = NatureOfService.DOMAIN
-)
 public class ClassDiscoveryServiceUsingReflections
             extends AbstractService 
             implements ClassDiscoveryService2 {

http://git-wip-us.apache.org/repos/asf/isis/blob/f311839c/core/runtime/src/main/java/org/apache/isis/core/runtime/services/ServicesInstallerFromAnnotation.java
----------------------------------------------------------------------
diff --git a/core/runtime/src/main/java/org/apache/isis/core/runtime/services/ServicesInstallerFromAnnotation.java b/core/runtime/src/main/java/org/apache/isis/core/runtime/services/ServicesInstallerFromAnnotation.java
index b4434d4..5bf95e0 100644
--- a/core/runtime/src/main/java/org/apache/isis/core/runtime/services/ServicesInstallerFromAnnotation.java
+++ b/core/runtime/src/main/java/org/apache/isis/core/runtime/services/ServicesInstallerFromAnnotation.java
@@ -25,7 +25,10 @@ import java.util.Map;
 import java.util.Set;
 import java.util.SortedMap;
 import java.util.SortedSet;
+
+import javax.annotation.Nullable;
 import javax.annotation.PreDestroy;
+
 import com.google.common.base.Function;
 import com.google.common.base.Joiner;
 import com.google.common.base.Predicate;
@@ -34,10 +37,14 @@ import com.google.common.base.Strings;
 import com.google.common.collect.Iterables;
 import com.google.common.collect.Lists;
 import com.google.common.collect.Maps;
+import com.google.common.collect.Ordering;
+import com.google.common.collect.Sets;
+
 import org.reflections.Reflections;
 import org.reflections.vfs.Vfs;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
+
 import org.apache.isis.applib.annotation.DomainService;
 import org.apache.isis.applib.annotation.DomainServiceLayout;
 import org.apache.isis.applib.services.classdiscovery.ClassDiscoveryServiceUsingReflections;
@@ -46,6 +53,8 @@ import org.apache.isis.core.runtime.system.DeploymentType;
 
 import static com.google.common.base.Predicates.and;
 import static com.google.common.base.Predicates.not;
+import io.github.lukehutch.fastclasspathscanner.FastClasspathScanner;
+import io.github.lukehutch.fastclasspathscanner.matchprocessor.ClassAnnotationMatchProcessor;
 
 public class ServicesInstallerFromAnnotation extends InstallerAbstract implements ServicesInstaller {
 
@@ -209,11 +218,30 @@ public class ServicesInstallerFromAnnotation extends InstallerAbstract implement
 
         final List<String> packagePrefixList = asList(packagePrefixes);
 
-        Vfs.setDefaultURLTypes(ClassDiscoveryServiceUsingReflections.getUrlTypes());
-        final Reflections reflections = new Reflections(packagePrefixList);
+        final List<Class<?>> domainServiceClassesR = Lists.newArrayList(findClassesUsingReflections(packagePrefixList));
+        final List<Class<?>> domainServiceClassesFCS = Lists.newArrayList(findClassesUsingFastClasspathScanner(packagePrefixList));
+
+        final List<Class<?>> domainServiceClasses = Lists.newArrayList(domainServiceClassesFCS);
+
+        final List<String> sortedR_orig = sortedClassNames(domainServiceClassesR);
+        final List<String> sortedR = sortedClassNames(domainServiceClassesR);
+        final List<String> sortedFCS_orig = sortedClassNames(domainServiceClassesFCS);
+        final List<String> sortedFCS = sortedClassNames(domainServiceClassesFCS);
+
+        sortedR.removeAll(sortedFCS_orig);
+        sortedFCS.removeAll(sortedR_orig);
+
+        System.out.println("in R, not in FCS:");
+        for (String s : sortedR) {
+            System.out.println("  " + s);
+        }
+
+        System.out.println("in FCS, not in R:");
+        for (String s : sortedFCS) {
+            System.out.println("  " + s);
+        }
+
 
-        final Set<Class<?>> typesAnnotatedWith = reflections.getTypesAnnotatedWith(DomainService.class);
-        final List<Class<?>> domainServiceClasses = Lists.newArrayList(Iterables.filter(typesAnnotatedWith, instantiatable()));
         for (final Class<?> cls : domainServiceClasses) {
 
             final String order = orderOf(cls);
@@ -226,6 +254,47 @@ public class ServicesInstallerFromAnnotation extends InstallerAbstract implement
         }
     }
 
+    public List<String> sortedClassNames(final List<Class<?>> classes) {
+        final Iterable<String> transform = Iterables.transform(classes, new Function<Class<?>, String>() {
+            @Nullable @Override public String apply(@Nullable final Class<?> input) {
+                return input.getName();
+            }
+        });
+        return Ordering.natural().sortedCopy(transform);
+    }
+
+    protected Iterable<Class<?>> findClassesUsingFastClasspathScanner(final List<String> packagePrefixList) {
+        final Set<Class<?>> classes = Sets.newLinkedHashSet();
+        new FastClasspathScanner(packagePrefixList.toArray(new String[]{}))
+                .matchClassesWithAnnotation(DomainService.class, new ClassAnnotationMatchProcessor() {
+                    @Override
+                    public void processMatch(final Class<?> aClass) {
+                        if(instantiatable().apply(aClass)) {
+                            classes.add(aClass);
+                        }
+                    }
+                })
+                .scan();
+        return classes;
+    }
+
+    protected Iterable<Class<?>> findClassesUsingFastClasspathScanner2(final List<String> packagePrefixList) {
+        final Set<Class<?>> classes = Sets.newLinkedHashSet();
+        final FastClasspathScanner scan = new FastClasspathScanner(packagePrefixList.toArray(new String[] {}))
+                .scan();
+        final List<String> namesOfClassesWithAnnotation = scan.getNamesOfClassesWithAnnotation(DomainService.class);
+
+        return classes;
+    }
+
+    protected Iterable<Class<?>> findClassesUsingReflections(final List<String> packagePrefixList) {
+        Vfs.setDefaultURLTypes(ClassDiscoveryServiceUsingReflections.getUrlTypes());
+        final Reflections reflections = new Reflections(packagePrefixList);
+
+        final Set<Class<?>> classes = reflections.getTypesAnnotatedWith(DomainService.class);
+        return Iterables.filter(classes, instantiatable());
+    }
+
     private static String orderOf(final Class<?> cls) {
         final DomainServiceLayout domainServiceLayout = cls.getAnnotation(DomainServiceLayout.class);
         String order = domainServiceLayout != null ? domainServiceLayout.menuOrder(): null;


Re: isis git commit: ISIS-1182: spiking using fast-classpath-scanner.

Posted by Martin Grigorov <mg...@apache.org>.
On Jul 29, 2015 11:27 PM, <da...@apache.org> wrote:
>
> Repository: isis
> Updated Branches:
>   refs/heads/ISIS-1182 [created] f311839c2
>
>
> ISIS-1182: spiking using fast-classpath-scanner.
>
>
> Project: http://git-wip-us.apache.org/repos/asf/isis/repo
> Commit: http://git-wip-us.apache.org/repos/asf/isis/commit/f311839c
> Tree: http://git-wip-us.apache.org/repos/asf/isis/tree/f311839c
> Diff: http://git-wip-us.apache.org/repos/asf/isis/diff/f311839c
>
> Branch: refs/heads/ISIS-1182
> Commit: f311839c2fecef433bfd8dd6e1e3427bc5facf64
> Parents: c3d3480
> Author: Dan Haywood <da...@haywood-associates.co.uk>
> Authored: Wed Jul 29 21:26:38 2015 +0100
> Committer: Dan Haywood <da...@haywood-associates.co.uk>
> Committed: Wed Jul 29 21:26:38 2015 +0100
>
> ----------------------------------------------------------------------
>  core/applib/pom.xml                             | 13 ++++
>  ...scoveryServiceUsingFastClasspathScanner.java | 68 +++++++++++++++++
>  .../ClassDiscoveryServiceUsingReflections.java  | 14 +---
>  .../ServicesInstallerFromAnnotation.java        | 77 +++++++++++++++++++-
>  4 files changed, 157 insertions(+), 15 deletions(-)
> ----------------------------------------------------------------------
>
>
>
http://git-wip-us.apache.org/repos/asf/isis/blob/f311839c/core/applib/pom.xml
> ----------------------------------------------------------------------
> diff --git a/core/applib/pom.xml b/core/applib/pom.xml
> index 2e2b100..f101151 100644
> --- a/core/applib/pom.xml
> +++ b/core/applib/pom.xml
> @@ -168,6 +168,19 @@
>              <optional>true</optional>
>          </dependency>
>
> +        <!-- as used by ClassDiscoveryServiceUsingFastClasspathScanner
-->
> +        <dependency>
> +            <groupId>io.github.lukehutch</groupId>
> +            <artifactId>fast-classpath-scanner</artifactId>
> +            <version>1.4.1</version>
> +            <exclusions>
> +                <exclusion>
> +                    <groupId>junit</groupId>
> +                    <artifactId>junit</artifactId>
> +                </exclusion>
> +            </exclusions>
> +        </dependency>
> +
>      </dependencies>
>
>  </project>
>
>
http://git-wip-us.apache.org/repos/asf/isis/blob/f311839c/core/applib/src/main/java/org/apache/isis/applib/services/classdiscovery/ClassDiscoveryServiceUsingFastClasspathScanner.java
> ----------------------------------------------------------------------
> diff --git
a/core/applib/src/main/java/org/apache/isis/applib/services/classdiscovery/ClassDiscoveryServiceUsingFastClasspathScanner.java
b/core/applib/src/main/java/org/apache/isis/applib/services/classdiscovery/ClassDiscoveryServiceUsingFastClasspathScanner.java
> new file mode 100644
> index 0000000..daa081a
> --- /dev/null
> +++
b/core/applib/src/main/java/org/apache/isis/applib/services/classdiscovery/ClassDiscoveryServiceUsingFastClasspathScanner.java
> @@ -0,0 +1,68 @@
> +/*
> + *  Licensed to the Apache Software Foundation (ASF) under one
> + *  or more contributor license agreements.  See the NOTICE file
> + *  distributed with this work for additional information
> + *  regarding copyright ownership.  The ASF licenses this file
> + *  to you under the Apache License, Version 2.0 (the
> + *  "License"); you may not use this file except in compliance
> + *  with the License.  You may obtain a copy of the License at
> + *
> + *        http://www.apache.org/licenses/LICENSE-2.0
> + *
> + *  Unless required by applicable law or agreed to in writing,
> + *  software distributed under the License is distributed on an
> + *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
> + *  KIND, either express or implied.  See the License for the
> + *  specific language governing permissions and limitations
> + *  under the License.
> + */
> +package org.apache.isis.applib.services.classdiscovery;
> +
> +import java.util.Set;
> +
> +import com.google.common.collect.Sets;
> +
> +import org.apache.isis.applib.AbstractService;
> +import org.apache.isis.applib.annotation.DomainService;
> +import org.apache.isis.applib.annotation.NatureOfService;
> +import org.apache.isis.applib.annotation.Programmatic;
> +
> +import io.github.lukehutch.fastclasspathscanner.FastClasspathScanner;
> +import
io.github.lukehutch.fastclasspathscanner.matchprocessor.SubclassMatchProcessor;
> +
> +/**
> + * This utility service supports the dynamic discovery of classes from
the classpath.  One service that uses this
> + * is the <tt>FixtureScripts</tt> domain service.
> + *
> + */
> +@DomainService(
> +        nature = NatureOfService.DOMAIN
> +)
> +public class ClassDiscoveryServiceUsingFastClasspathScanner
> +            extends AbstractService
> +            implements ClassDiscoveryService2 {
> +
> +
> +    @Programmatic
> +    @Override
> +    public <T> Set<Class<? extends T>> findSubTypesOfClasses(Class<T>
type) {
> +        throw new IllegalStateException("Shouldn't be called as this
class implements ClassDiscoveryService2");
> +    }
> +
> +    @Programmatic
> +    @Override
> +    public <T> Set<Class<? extends T>> findSubTypesOfClasses(Class<T>
type, String packagePrefix) {
> +        final Set<Class<? extends T>> classes = Sets.newLinkedHashSet();
> +        new FastClasspathScanner(packagePrefix)
> +                .matchSubclassesOf(type, new SubclassMatchProcessor<T>()
{
> +                    @Override
> +                    public void processMatch(final Class<? extends T>
aClass) {
> +                        classes.add(aClass);
> +                    }
> +                })
> +                .scan();
> +        return classes;
> +    }
> +
> +
> +}
> \ No newline at end of file
>
>
http://git-wip-us.apache.org/repos/asf/isis/blob/f311839c/core/applib/src/main/java/org/apache/isis/applib/services/classdiscovery/ClassDiscoveryServiceUsingReflections.java
> ----------------------------------------------------------------------
> diff --git
a/core/applib/src/main/java/org/apache/isis/applib/services/classdiscovery/ClassDiscoveryServiceUsingReflections.java
b/core/applib/src/main/java/org/apache/isis/applib/services/classdiscovery/ClassDiscoveryServiceUsingReflections.java
> index e23a48d..c9a12ba 100644
> ---
a/core/applib/src/main/java/org/apache/isis/applib/services/classdiscovery/ClassDiscoveryServiceUsingReflections.java
> +++
b/core/applib/src/main/java/org/apache/isis/applib/services/classdiscovery/ClassDiscoveryServiceUsingReflections.java
> @@ -26,30 +26,22 @@ import java.util.Arrays;
>  import java.util.Collections;
>  import java.util.List;
>  import java.util.Set;
> +
>  import com.google.common.collect.Lists;
> +
>  import org.reflections.Reflections;
>  import org.reflections.scanners.SubTypesScanner;
>  import org.reflections.util.ClasspathHelper;
>  import org.reflections.vfs.SystemDir;
>  import org.reflections.vfs.Vfs;
> +
>  import org.apache.isis.applib.AbstractService;
> -import org.apache.isis.applib.annotation.DomainService;
> -import org.apache.isis.applib.annotation.NatureOfService;
>  import org.apache.isis.applib.annotation.Programmatic;
>
>  /**
>   * This utility service supports the dynamic discovery of classes from
the classpath.  One service that uses this
>   * is the <tt>FixtureScripts</tt> domain service.
> - *
> - * <p>
> - * This service has no UI and there is only one implementation (this
class) in applib, so it is annotated with
> - * {@link org.apache.isis.applib.annotation.DomainService}.  This means
that it is automatically registered and
> - * available for use; no further configuration is required.
> - * </p>
>   */
> -@DomainService(
> -        nature = NatureOfService.DOMAIN
> -)
>  public class ClassDiscoveryServiceUsingReflections
>              extends AbstractService
>              implements ClassDiscoveryService2 {
>
>
http://git-wip-us.apache.org/repos/asf/isis/blob/f311839c/core/runtime/src/main/java/org/apache/isis/core/runtime/services/ServicesInstallerFromAnnotation.java
> ----------------------------------------------------------------------
> diff --git
a/core/runtime/src/main/java/org/apache/isis/core/runtime/services/ServicesInstallerFromAnnotation.java
b/core/runtime/src/main/java/org/apache/isis/core/runtime/services/ServicesInstallerFromAnnotation.java
> index b4434d4..5bf95e0 100644
> ---
a/core/runtime/src/main/java/org/apache/isis/core/runtime/services/ServicesInstallerFromAnnotation.java
> +++
b/core/runtime/src/main/java/org/apache/isis/core/runtime/services/ServicesInstallerFromAnnotation.java
> @@ -25,7 +25,10 @@ import java.util.Map;
>  import java.util.Set;
>  import java.util.SortedMap;
>  import java.util.SortedSet;
> +
> +import javax.annotation.Nullable;
>  import javax.annotation.PreDestroy;
> +
>  import com.google.common.base.Function;
>  import com.google.common.base.Joiner;
>  import com.google.common.base.Predicate;
> @@ -34,10 +37,14 @@ import com.google.common.base.Strings;
>  import com.google.common.collect.Iterables;
>  import com.google.common.collect.Lists;
>  import com.google.common.collect.Maps;
> +import com.google.common.collect.Ordering;
> +import com.google.common.collect.Sets;
> +
>  import org.reflections.Reflections;
>  import org.reflections.vfs.Vfs;
>  import org.slf4j.Logger;
>  import org.slf4j.LoggerFactory;
> +
>  import org.apache.isis.applib.annotation.DomainService;
>  import org.apache.isis.applib.annotation.DomainServiceLayout;
>  import
org.apache.isis.applib.services.classdiscovery.ClassDiscoveryServiceUsingReflections;
> @@ -46,6 +53,8 @@ import
org.apache.isis.core.runtime.system.DeploymentType;
>
>  import static com.google.common.base.Predicates.and;
>  import static com.google.common.base.Predicates.not;
> +import io.github.lukehutch.fastclasspathscanner.FastClasspathScanner;
> +import
io.github.lukehutch.fastclasspathscanner.matchprocessor.ClassAnnotationMatchProcessor;
>
>  public class ServicesInstallerFromAnnotation extends InstallerAbstract
implements ServicesInstaller {
>
> @@ -209,11 +218,30 @@ public class ServicesInstallerFromAnnotation
extends InstallerAbstract implement
>
>          final List<String> packagePrefixList = asList(packagePrefixes);
>
> -
Vfs.setDefaultURLTypes(ClassDiscoveryServiceUsingReflections.getUrlTypes());
> -        final Reflections reflections = new
Reflections(packagePrefixList);
> +        final List<Class<?>> domainServiceClassesR =
Lists.newArrayList(findClassesUsingReflections(packagePrefixList));
> +        final List<Class<?>> domainServiceClassesFCS =
Lists.newArrayList(findClassesUsingFastClasspathScanner(packagePrefixList));
> +
> +        final List<Class<?>> domainServiceClasses =
Lists.newArrayList(domainServiceClassesFCS);
> +
> +        final List<String> sortedR_orig =
sortedClassNames(domainServiceClassesR);
> +        final List<String> sortedR =
sortedClassNames(domainServiceClassesR);
> +        final List<String> sortedFCS_orig =
sortedClassNames(domainServiceClassesFCS);
> +        final List<String> sortedFCS =
sortedClassNames(domainServiceClassesFCS);
> +
> +        sortedR.removeAll(sortedFCS_orig);
> +        sortedFCS.removeAll(sortedR_orig);
> +
> +        System.out.println("in R, not in FCS:");

> +        for (String s : sortedR) {
> +            System.out.println("  " + s);

Debug?

> +        }
> +
> +        System.out.println("in FCS, not in R:");
> +        for (String s : sortedFCS) {
> +            System.out.println("  " + s);

Same

> +        }
> +
>
> -        final Set<Class<?>> typesAnnotatedWith =
reflections.getTypesAnnotatedWith(DomainService.class);
> -        final List<Class<?>> domainServiceClasses =
Lists.newArrayList(Iterables.filter(typesAnnotatedWith, instantiatable()));
>          for (final Class<?> cls : domainServiceClasses) {
>
>              final String order = orderOf(cls);
> @@ -226,6 +254,47 @@ public class ServicesInstallerFromAnnotation extends
InstallerAbstract implement
>          }
>      }
>
> +    public List<String> sortedClassNames(final List<Class<?>> classes) {
> +        final Iterable<String> transform = Iterables.transform(classes,
new Function<Class<?>, String>() {
> +            @Nullable @Override public String apply(@Nullable final
Class<?> input) {
> +                return input.getName();
> +            }
> +        });
> +        return Ordering.natural().sortedCopy(transform);
> +    }
> +
> +    protected Iterable<Class<?>>
findClassesUsingFastClasspathScanner(final List<String> packagePrefixList) {
> +        final Set<Class<?>> classes = Sets.newLinkedHashSet();
> +        new FastClasspathScanner(packagePrefixList.toArray(new
String[]{}))
> +                .matchClassesWithAnnotation(DomainService.class, new
ClassAnnotationMatchProcessor() {
> +                    @Override
> +                    public void processMatch(final Class<?> aClass) {
> +                        if(instantiatable().apply(aClass)) {
> +                            classes.add(aClass);
> +                        }
> +                    }
> +                })
> +                .scan();
> +        return classes;
> +    }
> +
> +    protected Iterable<Class<?>>
findClassesUsingFastClasspathScanner2(final List<String> packagePrefixList)
{
> +        final Set<Class<?>> classes = Sets.newLinkedHashSet();
> +        final FastClasspathScanner scan = new
FastClasspathScanner(packagePrefixList.toArray(new String[] {}))
> +                .scan();
> +        final List<String> namesOfClassesWithAnnotation =
scan.getNamesOfClassesWithAnnotation(DomainService.class);
> +
> +        return classes;
> +    }
> +
> +    protected Iterable<Class<?>> findClassesUsingReflections(final
List<String> packagePrefixList) {
> +
Vfs.setDefaultURLTypes(ClassDiscoveryServiceUsingReflections.getUrlTypes());
> +        final Reflections reflections = new
Reflections(packagePrefixList);
> +
> +        final Set<Class<?>> classes =
reflections.getTypesAnnotatedWith(DomainService.class);
> +        return Iterables.filter(classes, instantiatable());
> +    }
> +
>      private static String orderOf(final Class<?> cls) {
>          final DomainServiceLayout domainServiceLayout =
cls.getAnnotation(DomainServiceLayout.class);
>          String order = domainServiceLayout != null ?
domainServiceLayout.menuOrder(): null;
>