Hi John,

Thanks for the suggestions. I like “@RegisterableFunction” better than 
“@RegisterFunction".  I think that we don’t want @RegisterableFunction to be 
@Inherited, in order to avoid creating a new variant of the problem we are 
trying to fix.  As you suggest, we should be mindful to document the behavior 
clearly. 

In case you’re interested, here’s 
<https://github.com/lukehutch/fast-classpath-scanner/wiki/3.4.-Finding-classes-with-specific-annotations-or-meta-annotations>
 some documentation of the API for the library we’re using for the annotation 
scanning.  It scans the binary byte code files directly, rather than using a 
Class reference like Spring utilities you pointed out (which AFAIK requires 
having that class loaded in the JVM).

Thanks,
Jared

> On Aug 11, 2017, at 11:00 AM, John Blum <jb...@pivotal.io> wrote:
> 
> Hi Jared-
> 
> In general, I like this idea since Annotations are a great form of
> meta-data and essentially meaningless outside of the intended context and
> therefore do not impose any adverse effects on any existing behavior.
> 
> However, 2 things... 1 suggestion and 1 caution...
> 
> 
> 1. Perhaps "RegisterableFunction" as opposed to "RegisterFunction".
> 
> 
> 2. Annotations can be "inherited" in the same way that your ConcreteFunction
> extends (inherits from) AbstractFunction, so too can a more concrete
> Function possibly inherit from a less-concrete-but-not-abstract Function.
> A developer might expect that they don't have to re-annotated his/her
> function.
> 
> For example...
> 
> @RegisterableFunction
> class ProcessOrder extends FunctionAdapter { ... }
> 
> class CreateAccountAtPointOfSale extends ProcessOrder { ... }
> 
> If these are in separate JAR files, depending on the "application", I may
> only want to "register" the CreateAccountAtPointOfSale Function and not the
> ProcessOrder Function explicitly.  Please forgive my example here since it
> seems like a bad example given it feels like 2 separate actions but is
> often part of the same workflow and so really depends on how application
> developers think about and organize their logic, which usually leads to
> "unexpected" things you never anticipated when introducing something like
> this.
> 
> SIDE NOTE: Of course, from a Java SE standpoint, the "RegisteredFunction"
> Annotation could be (but does not have to be) meta-annotated with @Inherited.,
> such as...
> 
> @Target(ElementType.TYPE)
> @Retention(RetentionPolicy.RUNTIME)
> @Inherited
> ...
> @interface RegisteredFunction { .. }
> 
> 
> *Spring* takes all of these things into account when it processes
> annotations of this nature (e.g. @Enable...).  Especially have a look at
> o.s.core.annotation.AnnotatedElementUtils [1] and even
> o.s.core.annotation.AnnotationUtils [2].  These are very robust and very
> powerful classes underpinning much of *Spring's* Annotation configuration
> and processing.  *Boot* also extends this functionality and *Spring*
> Annotation config in very specific/custom ways.
> 
> I think it is reasonable to set limitations to keep the initial scope
> small, but be sure those are well documented since users will be coming
> from many different frameworks having many different expectations.
> 
> Food for thought/hope this helps.
> 
> Regards,
> -John
> 
> 
> [1]
> http://docs.spring.io/spring/docs/current/javadoc-api/org/springframework/core/annotation/AnnotatedElementUtils.html
> [2]
> http://docs.spring.io/spring/docs/current/javadoc-api/org/springframework/core/annotation/AnnotationUtils.html
> 
> 
> 
> 
> 
> On Fri, Aug 11, 2017 at 10:22 AM, Jared Stewart <jstew...@pivotal.io> wrote:
> 
>> Recent changes introduced to avoid the eager loading of classes have lead
>> to Functions not getting registered correctly if the class hierarchy
>> leading up to Function (or FunctionAdapter) is split up across multiple jar
>> files.  We propose to introduce a new annotation to identify functions in
>> such a case.
>> Consider the following scenario:
>>> Abstract.jar - public abstract class AbstractFunction implements
>> Function {...}
>>> Concrete.jar - public class ConcreteFunction extends AbstractFunction
>> {...}
>> When Concrete.jar is deployed, we only scan the classes inside
>> Concrete.jar.  This means that we have no way of knowing that
>> AbstractFunction eventually leads up to Function.  (We could load
>> ConcreteFunction to see if it implements Function via reflection or
>> Function.class.isAssignableFrom(), but then we would be back to eagerly
>> loading all of the classes to see whether or not they implement Function.)
>> We propose a new annotation (perhaps @RegisterFunction, suggestions are
>> welcome) to designate a class as a Function in such a case.  Since we are
>> able to scan classes for annotations without loading them, this will allow
>> us to identify ConcreteFunction as a Function without eagerly loading all
>> of the classes in Concrete.jar.
>> I should emphasize that ConcreteFunction already is registered as expected
>> if it resides in the same jar file as AbstractFunction.  This annotation
>> would only be relevant when the class hierarchy leading up to Function is
>> spread across multiple jar files.
>> - Jared
> 
> 
> 
> 
> -- 
> -John
> john.blum10101 (skype)

Reply via email to