scala modules
TRANSCRIPT
ScalaModulesScala and OSGi
OSGi Services
• The key to modularity
• Arguably, the key to OOP itself?
Dr Alan Kay
Dr Alan Kay
“Dude I invented friggin’ OOP. Have you heard of it?”
Dr Alan Kay
“OOP to me means only messaging, local retention and protection and hiding of state-process, and extreme late-binding of all things.”
Late Binding with Services
• Services answer the question:where do I get an implementation of this interface?
• The registry decentralises the architecture.
Consuming Services
Harder than Expected!
Why...?
Slippery
Dynamics
• A service can come and go
• At any time
• On any thread
• Yes... even while you’re using it
Result
•Service usage code can be very complex
Service Consumption in Java
Consuming a Service
public void consumeService(BundleContext context) { ServiceReference ref = context.getServiceReference(Greeting.class.getName()); Greeting greeting = (Greeting) context.getService(ref); System.out.println(greeting.getMessage()); }
Consuming a Service
public void consumeService(BundleContext context) { ServiceReference ref = context.getServiceReference(Greeting.class.getName()); Greeting greeting = (Greeting) context.getService(ref); System.out.println(greeting.getMessage()); }
WRONG
Consuming a Service
public void consumeService(BundleContext context) { ServiceReference ref = context.getServiceReference(Greeting.class.getName()); if(ref != null) { Greeting greeting = (Greeting) context.getService(ref); System.out.println(greeting.getMessage()); } }
Consuming a Service
public void consumeService(BundleContext context) { ServiceReference ref = context.getServiceReference(Greeting.class.getName()); if(ref != null) { Greeting greeting = (Greeting) context.getService(ref); System.out.println(greeting.getMessage()); } }
WRONG
Consuming a Service
public void consumeService(BundleContext context) { ServiceReference ref = context.getServiceReference(Greeting.class.getName()); if(ref != null) { Greeting greeting = (Greeting) context.getService(ref); if(greeting != null) { System.out.println(greeting.getMessage()); } } }
Consuming a Service
public void consumeService(BundleContext context) { ServiceReference ref = context.getServiceReference(Greeting.class.getName()); if(ref != null) { Greeting greeting = (Greeting) context.getService(ref); if(greeting != null) { System.out.println(greeting.getMessage()); } } }
WRONG
Consuming a Service
public void consumeService(BundleContext context) { ServiceReference ref = context.getServiceReference(Greeting.class.getName()); if(ref != null) { Greeting greeting = (Greeting) context.getService(ref); if(greeting != null) { System.out.println(greeting.getMessage()); } context.ungetService(ref); } }
Consuming a Service
public void consumeService(BundleContext context) { ServiceReference ref = context.getServiceReference(Greeting.class.getName()); if(ref != null) { Greeting greeting = (Greeting) context.getService(ref); if(greeting != null) { System.out.println(greeting.getMessage()); } context.ungetService(ref); } }
WRONG
Consuming a Service public void consumeService(BundleContext context) { ServiceReference ref = context.getServiceReference(Greeting.class.getName()); if(ref != null) { try { Greeting greeting = (Greeting) context.getService(ref); if(greeting != null) { System.out.println(greeting.getMessage()); } } finally { context.ungetService(ref); } } }
Consuming a Service public void consumeService(BundleContext context) { ServiceReference ref = context.getServiceReference(Greeting.class.getName()); if(ref != null) { try { Greeting greeting = (Greeting) context.getService(ref); if(greeting != null) { System.out.println(greeting.getMessage()); } } finally { context.ungetService(ref); } } }
NOT TYPE SAFE
Consuming a Service public void consumeService(BundleContext context) { ServiceReference ref = context.getServiceReference(Greeting.class.getName()); if(ref != null) { try { Greeting greeting = (Greeting) context.getService(ref); if(greeting != null) { System.out.println(greeting.getMessage()); } } finally { context.ungetService(ref); } } }
NOT TYPE SAFE
An Answer:Stop Writing Code!
Declarative Services (DS)
@Reference public void setGreeting(Greeting greeting) { this.greeting = greeting; } public void consumeService() { System.out.println(greeting.getMessage()); }
Blueprint public void setGreeting(Greeting greeting) { this.greeting = greeting; } public void consumeService() { System.out.println(greeting.getMessage()); }
<blueprint>
<reference id="greeting" interface="org.example.Greeting"/>
<bean id="foo" class="com.foo.Foo"/> <property name="greeting" ref="greeting"/> </bean>
</blueprint>
Problem
• These frameworks provide abstractions
• Abstraction hide detail
• Sometimes we need the detail
Example: Cardinality?
Component
Service
Service
Service
Service
Single
Component
Service
Service
Service
Service
Multiple
Component
Service
Service
Service
Service
???
Component
Service
Service
Service
Service
Component
Component
Component
Not supported by DS
♥IDeclarative
Services(and Blueprint)
♥IDeclarative
Services(and Blueprint)
The “80%” Solution
“Normal” Users
The “80%” Solution
“Normal” UsersDS support
The “80%” Solution
“Normal” UsersDS support
The “80%” Solution
“Normal” UsersDS support“Power” Users
The “80%” Solution
“Normal” UsersDS support“Power” Users
The “80%” Solution
“Normal” UsersDS support“Power” UsersEasy in Java
The “80%” Solution
“Normal” UsersDS support“Power” UsersEasy in Java
The “80%” Solution
“Normal” UsersDS support“Power” UsersEasy in JavaEasy in Scala
The “80%” Solution
“Normal” UsersDS support“Power” UsersEasy in JavaEasy in Scala
Java ServiceTracker tracker = new ServiceTracker(context, Greeting.class.getName(), new ServiceTrackerCustomizer() {
public Object addingService(ServiceReference reference) { Greeting greeting = (Greeting) context.getService(reference); ServiceRegistration reg = context.registerService(IFoo.class.getName(), new Foo(greeting), null); return reg; }
public void modifiedService(ServiceReference reference, Object service) { }
public void removedService(ServiceReference reference, Object service) { ServiceRegistration reg = (ServiceRegistration) service; reg.unregister(); } });
Java ServiceTracker tracker = new ServiceTracker(context, Greeting.class.getName(), new ServiceTrackerCustomizer() {
public Object addingService(ServiceReference reference) { Greeting greeting = (Greeting) context.getService(reference); ServiceRegistration reg = context.registerService(IFoo.class.getName(), new Foo(greeting), null); return reg; }
public void modifiedService(ServiceReference reference, Object service) { }
public void removedService(ServiceReference reference, Object service) { ServiceRegistration reg = (ServiceRegistration) service; reg.unregister(); } });
Type Safety???
What is ScalaModules?
NOT Another Module System (phew!)
“A Scala internal DSL to ease OSGi development”
• Now:
• Services
• Future:
• Extender Pattern?
• Resources?
An Eclipse Project!
Examples
Java ServiceTracker tracker = new ServiceTracker(context, Greeting.class.getName(), new ServiceTrackerCustomizer() {
public Object addingService(ServiceReference reference) { Greeting greeting = (Greeting) context.getService(reference); ServiceRegistration reg = context.registerService(IFoo.class.getName(), new Foo(greeting), null); return reg; }
public void modifiedService(ServiceReference reference, Object service) { }
public void removedService(ServiceReference reference, Object service) { ServiceRegistration reg = (ServiceRegistration) service; reg.unregister(); } });
ScalaModules
val greetingTrack = context track classOf[Greeting] on { case Adding(greeting) => context createService (classOf[IFoo], new Foo(greeting)) case Removed(_, reg) => reg unregister }
Plan
• Started moving the code & docs to Eclipse
• 19 March: M1
• 7 May: M2
• 28 May: RC1
• 11 June: RC2
• 23 June: ScalaModules 2.0 Release & Graduation
Get Involved
http://www.eclipse.org/forums/eclipse.scalamodules