Skip to content

Latest commit

 

History

History
117 lines (84 loc) · 4.07 KB

File metadata and controls

117 lines (84 loc) · 4.07 KB

Pixie Changelog

2.14

Interface Observers

@Observes methods may now declare an interface parameter, not just a concrete class. When an event is fired, Pixie selects the most-specific matching observer across the full type graph — classes and interfaces — using the same "most specific wins" rule the JVM applies to overloaded method calls.

public interface Auditable {}

public class Listener {
    public void onAuditable(@Observes Auditable event) {
        // receives any event whose type implements Auditable
    }
}

When an event matches two unrelated observed interfaces on the same component and no common subtype breaks the tie, there is no most-specific match. Rather than guess, Pixie throws AmbiguousObserverException when the event is fired — the same stance the Java compiler takes on an ambiguous overloaded call. Resolve it by observing a shared subtype or removing one of the observers.

Declaring two @Observes methods for the same type on a single component is now rejected when the component is registered, instead of silently dropping one.

2.13

Collections and Maps in @Param

A single configuration property can now be injected as a List, Set, or Map when the parameter declares a generic element type. Each element passes through the normal @Param conversion chain, so any type usable as a scalar @Param also works as a collection element.

public class FeedReader {
    public FeedReader(@Param("uris") final List<URI> uris) {
        // ...
    }
}
reader = new://org.example.FeedReader
reader.uris = http://one, http://two/dos

Lists and sets split on commas (surrounding whitespace is tolerated). Maps use the standard Java properties format — one key=value pair per line — and both keys and values are converted.

Supported declared types:

  • List, Collection, ArrayList → ArrayList

  • Set, HashSet → HashSet

  • SortedSet, TreeSet → TreeSet

  • Map, HashMap → HashMap

  • SortedMap, TreeMap → TreeMap

Backwards Compatibility

Scalar @Param injection is unchanged. Raw List/Map declarations (no generic element type) fall back to String elements.

2.12

Generics Support in Component Injection

Component references (@Component) now use generic type arguments when resolving which components are eligible for injection. Previously, only the raw type was considered — a parameter of type RequestHandler<String, Integer> would match any RequestHandler implementation. Now, only implementations with matching type arguments are injected.

This applies to:

  • Single @Component refs resolved by type or by name

  • Collection injection (List<RequestHandler<String, Integer>>) — only matching implementations are collected

  • All producer types — constructor-based, @Factory methods, @Builder patterns, and pre-built instances via system.add()

Wildcard Support

Injection points can use Java wildcards:

  • ? extends Number — matches any subtype of Number

  • ? super Integer — matches any supertype of Integer

  • ? — matches any type argument (unbounded)

  • Nested parameterized bounds such as ? extends Comparable<String>

Mixed Generic Resolution

Type arguments can come from multiple sources and are correctly stitched together:

  • Some from the factory/builder method declaration

  • Others from the class hierarchy of the produced type

For example, a factory returning BooleanHandler<String> where BooleanHandler<I> implements RequestHandler<I, Boolean> correctly resolves to RequestHandler<String, Boolean>.

Backwards Compatibility

Raw type injection points (no generics) continue to match any implementation, preserving full backwards compatibility with existing code.

Builder Generic Return Types

Builders.resolveBuiltType() now returns Type instead of Class<?>, preserving generic type information from the builder pattern. This allows builders with generic build() methods (returning T or RequestHandler<I, O>) to participate in generics-aware component matching.