Upload
others
View
22
Download
0
Embed Size (px)
Citation preview
What’s next for e4
Tom Schindl <[email protected]> Twitter: @tomsontom
Website: http://www.bestsolution.at
(c) BestSolution.at - Licensed under Creative Commons Attribution-NonCommerical-ShareAlike 3.0
About Tom‣ CTO BestSolution.at Systemhaus GmbH
‣ Eclipse Committer
‣ e4
‣ Platform
‣ EMF
‣ Project lead
‣ e(fx)clipse
‣ Twitter: @tomsontom
‣ Blog: tomsondev.bestsolution.at
‣ Corporate: http://bestsolution.at
Q: Tom can you reflect a bit on the Eclipse 4?
The compat layer
The combat layer
e4 spec’ed world
Application ModelThe Brain
(OSGi) Service Components &
DI-ContainerNervous system
UI (SWT/FX/…)Sense organ
combat world
Application ModelThe (split) Brain
Nervous system
UI (SWT/FX/…)
Sense organ
$n - Registries
Legacy
Compat-Layer
DI & Service
Q:Tom what’s your take on e4 core and DI components?
How OSGi spec’ed the world
Service-API (requires NOTHING)
Service-Impl 1 (requires Equinox, …)
Service-Impl $N (requires Felix, …)
Consumer (requires Service-API)
How e4 core implemented it
Service-API (requires Equinox)
Service-Impl 1
Consumer (requires Service-API & transitive Equinox)
Manifest-Version: 1.0 Bundle-ManifestVersion: 2 Bundle-SymbolicName: org.eclipse.e4.core.di … Import-Package: javax.annotation, javax.inject;version=„1.0.0"
Wanna see an example
Manifest-Version: 1.0 Bundle-ManifestVersion: 2 Bundle-SymbolicName: org.eclipse.e4.core.di … Import-Package: javax.annotation, javax.inject;version=„1.0.0"
Wanna see an example
Manifest-Version: 1.0Bundle-ManifestVersion: 2Bundle-SymbolicName: org.eclipse.e4.core.di…Import-Package: javax.annotation,javax.inject;version="1.0.0",org.eclipse.osgi.framework.log;version="1.1.0",org.eclipse.osgi.service.debug;version="1.2.0",org.osgi.framework;version="1.8.0",org.osgi.util.tracker;version="1.5.1"
Manifest-Version: 1.0 Bundle-ManifestVersion: 2 Bundle-SymbolicName: org.eclipse.e4.core.di … Import-Package: javax.annotation, javax.inject;version=„1.0.0"
Wanna see an example
Manifest-Version: 1.0Bundle-ManifestVersion: 2Bundle-SymbolicName: org.eclipse.e4.core.di…Import-Package: javax.annotation,javax.inject;version="1.0.0",org.eclipse.osgi.framework.log;version="1.1.0",org.eclipse.osgi.service.debug;version="1.2.0",org.osgi.framework;version="1.8.0",org.osgi.util.tracker;version="1.5.1"
ONLY NEEDED BY IMPL
Q: Tom what’s your take on OSGi in e4 APIs?
Ideal OSGi App world
Ideal OSGi App world
A-API-Bundle (requires NOTHING)
Ideal OSGi App world
A-API-Bundle (requires NOTHING)
A Impl-Bundle (requires NOTHING)
Ideal OSGi App world
A-API-Bundle (requires NOTHING)
A Impl-Bundle (requires NOTHING)
B Impl-Bundle (requires Comp A-API-Bundle)
Ideal OSGi App world
A-API-Bundle (requires NOTHING)
A Impl-Bundle (requires NOTHING)
B Impl-Bundle (requires Comp A-API-Bundle)
public interface A {
}
Ideal OSGi App world
A-API-Bundle (requires NOTHING)
A Impl-Bundle (requires NOTHING)
B Impl-Bundle (requires Comp A-API-Bundle)
public interface A {
}
@Componentpublic class ImplA implements A {}
Ideal OSGi App world
A-API-Bundle (requires NOTHING)
A Impl-Bundle (requires NOTHING)
B Impl-Bundle (requires Comp A-API-Bundle)
public interface A {
}
@Componentpublic class ImplA implements A {}
@Componentpublic class ImplB {
@Reference(cardinality=ReferenceCardinality.MANDATORY)
public void setCompA(A a) {}public void unsetCompA(A a) {}
}
e4 OSGi usage
A Impl-Bundle (requires NOTHING)
B Impl-Bundle (requires Comp A-API-Bundle)
A-API-Bundle (requires NOTHING)
e4 OSGi usage
A Impl-Bundle (requires NOTHING)
B Impl-Bundle (requires Comp A-API-Bundle)
A-API-Bundle (requires NOTHING)
public interface A {
}
@Componentpublic class ImplA implements A {}
e4 OSGi usage
A Impl-Bundle (requires NOTHING)
B Impl-Bundle (requires Comp A-API-Bundle)
A-API-Bundle (requires NOTHING)
public interface A {
}
@Componentpublic class ImplA implements A {}
public class ImplB {@Injectpublic void setCompA(A a) {}
}
e4 OSGi usage
IEclipseContext serviceContext = …
B a = ContextInjectionFactory.make(B.class, serviceContext);
e4 OSGi usage
Bundle bundle = FrameworkUtil.getBundle(BlaBla.class)BundleContext btx = bundle.getBundleContext();
IEclipseContext serviceContext = EclipseContextFactory.getServiceContext(btx);
B a = ContextInjectionFactory.make(B.class, serviceContext);
Q: What API does e4 use from OSGi?
e4 OSGi API useage
e4 OSGi API useage
Pattern 1 - Debug/Logimport org.eclipse.osgi.framework.log.FrameworkLog;import org.eclipse.osgi.framework.log.FrameworkLogEntry;
FrameworkLog log = …FrameworkLogEntry logEntry = new FrameworkLogEntry("org.eclipse.core.e4.di", FrameworkLogEntry.ERROR, 0, "I’m an error", 0, e, null);
e4 OSGi API useage
Pattern 1 - Debug/Logimport org.eclipse.osgi.framework.log.FrameworkLog;import org.eclipse.osgi.framework.log.FrameworkLogEntry;
FrameworkLog log = …FrameworkLogEntry logEntry = new FrameworkLogEntry("org.eclipse.core.e4.di", FrameworkLogEntry.ERROR, 0, "I’m an error", 0, e, null);
Pattern 2 - Accessing OSGi-ServiceBundleContext bundleContext = FrameworkUtil.getBundle(BlaBla.class).getBundleContext();ServiceReference<ComponentA> serviceReference = bundleContext.getServiceReference(GreetService.class);if( serviceReference != null ) { bundleContext.getService(serviceReference).greet("Hello Tom");}
Q: Ok. Got you. But can anything be done against that
Logging the efxclipse wayAccess Patterns
Logging the efxclipse wayAccess Patternspublic class ComponentEarly2000 {private static Logger logger = LoggerCreator.createLogger(getClass());
}
Logging the efxclipse wayAccess Patterns
public class OSGiComponent2016 {private Logger logger;
@Reference(cardinality=ReferenceCardinality.MANDATORY)public void setLoggerFactory(LoggerFactory f) {
f.createLogger(getClass().getName());}
}
public class ComponentEarly2000 {private static Logger logger = LoggerCreator.createLogger(getClass());
}
Logging the efxclipse wayAccess Patterns
public class DiComponent2016 {@Inject@Logprivate Logger logger;
}
public class OSGiComponent2016 {private Logger logger;
@Reference(cardinality=ReferenceCardinality.MANDATORY)public void setLoggerFactory(LoggerFactory f) {
f.createLogger(getClass().getName());}
}
public class ComponentEarly2000 {private static Logger logger = LoggerCreator.createLogger(getClass());
}
Logging the efxclipse wayprivate void processJPAResultList(List<Person> list) {// slf4j/log4j/efxclipse for( int i = 0; i < list.size(); i++ ) { Person p = list.get(i);
logger.debug("Processing " + p.getName() + " - " + p.getAddress().getStreet());
} }
Logging the efxclipse wayprivate void processJPAResultList(List<Person> list) {// slf4j/log4j/efxclipse for( int i = 0; i < list.size(); i++ ) { Person p = list.get(i);
logger.debug("Processing " + p.getName() + " - " + p.getAddress().getStreet());
} }
BAD IDEA
Logging the efxclipse wayprivate void processJPAResultList(List<Person> list) {// slf4j/log4j/efxclipse for( int i = 0; i < list.size(); i++ ) { Person p = list.get(i);
logger.debug("Processing " + p.getName() + " - " + p.getAddress().getStreet());
} }
private void processJPAResultList(List<Person> list) {// slf4j/log4j/efxclipsefor( int i = 0; i < list.size(); i++ ) {
Person p = list.get(i);if( logger.isEnabled(Level.DEBUG) ) {
logger.debug("Processing " + p.getName() + " - " + p.getAddress().getStreet());}
}}
Logging the efxclipse wayprivate void processJPAResultList(List<Person> list) {// slf4j/log4j/efxclipse for( int i = 0; i < list.size(); i++ ) { Person p = list.get(i);
logger.debug("Processing " + p.getName() + " - " + p.getAddress().getStreet());
} }
private void processJPAResultList(List<Person> list) {// log4j-2.x/efxclipsefor( int i = 0; i < list.size(); i++ ) {
Person p = list.get(i);// Logger#debug(Supplier<String>): voidlogger.debug(() -> "Processing " + p.getName() + " - " + p.getAddress().getStreet());
}}
private void processJPAResultList(List<Person> list) {// slf4j/log4j/efxclipsefor( int i = 0; i < list.size(); i++ ) {
Person p = list.get(i);if( logger.isEnabled(Level.DEBUG) ) {
logger.debug("Processing " + p.getName() + " - " + p.getAddress().getStreet());}
}}
Logging the efxclipse wayprivate void processJPAResultList(List<Person> list) {// slf4j/log4j/efxclipse for( int i = 0; i < list.size(); i++ ) { Person p = list.get(i);
logger.debug("Processing " + p.getName() + " - " + p.getAddress().getStreet());
} }
private void processJPAResultList(List<Person> list) {// log4j-2.x/efxclipsefor( int i = 0; i < list.size(); i++ ) {
Person p = list.get(i);// Logger#debug(Supplier<String>): voidlogger.debug(() -> "Processing " + p.getName() + " - " + p.getAddress().getStreet());
}}
private void processJPAResultList(List<Person> list) {// slf4j/log4j/efxclipsefor( int i = 0; i < list.size(); i++ ) {
Person p = list.get(i);if( logger.isEnabled(Level.DEBUG) ) {
logger.debug("Processing " + p.getName() + " - " + p.getAddress().getStreet());}
}}
private void processJPAResultList(List<Person> list) {// efxclipsefor( int i = 0; i < list.size(); i++ ) {
// Logger#<T>debug(T value Function<T,String>): Tlogger.debug(list.get(i), (p)
-> "Processing " + p.getName() + " - " + p.getAddress().getStreet());}
}
Logging the efxclipse wayprivate void processJPAResultList(List<Person> list) {// slf4j/log4j/efxclipse for( int i = 0; i < list.size(); i++ ) { Person p = list.get(i);
logger.debug("Processing " + p.getName() + " - " + p.getAddress().getStreet());
} }
private void processJPAResultList(List<Person> list) {// log4j-2.x/efxclipsefor( int i = 0; i < list.size(); i++ ) {
Person p = list.get(i);// Logger#debug(Supplier<String>): voidlogger.debug(() -> "Processing " + p.getName() + " - " + p.getAddress().getStreet());
}}
private void processJPAResultList(List<Person> list) {// slf4j/log4j/efxclipsefor( int i = 0; i < list.size(); i++ ) {
Person p = list.get(i);if( logger.isEnabled(Level.DEBUG) ) {
logger.debug("Processing " + p.getName() + " - " + p.getAddress().getStreet());}
}}
private void processJPAResultList(List<Person> list) {// efxclipsefor( int i = 0; i < list.size(); i++ ) {
// Logger#<T>debug(T value Function<T,String>): Tlogger.debug(list.get(i), (p)
-> "Processing " + p.getName() + " - " + p.getAddress().getStreet());}
}
BAD IDEA
Logging the efxclipse wayprivate void processJPAResultList(List<Person> list) {// log4j-2.x/efxclipse for( int i = 0; i < list.size(); i++ ) { Person p = list.get(i); logger.debug(() -> "Processing " + p.getName() + " - " + p.getAddress().getStreet()); } }
Logging the efxclipse wayprivate void processJPAResultList(List<Person> list) {// log4j-2.x/efxclipse for( int i = 0; i < list.size(); i++ ) { Person p = list.get(i); logger.debug(() -> "Processing " + p.getName() + " - " + p.getAddress().getStreet()); } }
static class Supplier1234 implements Supplier<String> {private Person p;
Supplier1234(Person p) {this.p = p;
}
public void String get() {return "Processing " + p.getName() + " - " + p.getAddress().getStreet());
}}
private void processJPAResultList(List<Person> list) {// log4j-2.x/efxclipsefor( int i = 0; i < list.size(); i++ ) {
Person p = list.get(i);logger.debug(new Supplier(p));
}}
Logging the efxclipse wayprivate void processJPAResultList(List<Person> list) {// efxclipse for( int i = 0; i < list.size(); i++ ) { logger.debug(list.get(i), (p) -> "Processing " + p.getName() + " - " + p.getAddress().getStreet()); } }
Logging the efxclipse wayprivate void processJPAResultList(List<Person> list) {// efxclipse for( int i = 0; i < list.size(); i++ ) { logger.debug(list.get(i), (p) -> "Processing " + p.getName() + " - " + p.getAddress().getStreet()); } }
static class Function1234 implements Function<Person,String> {public void String apply(Person p) {
return "Processing " + p.getName() + " - " + p.getAddress().getStreet());}
}
private static Function1234 INSTANCE = new Function1234();
private void processJPAResultList(List<Person> list) {// efxclipsefor( int i = 0; i < list.size(); i++ ) {
logger.debug(list.get(i), INSTANCE);}
list.stream().map( p -> logger.debug(list.get(i), INSTANCE) ).filter(…)
}
Servicelookup the efx way
Servicelookup the efx waye4 built-in - single value
Servicelookup the efx waye4 built-in - single valuepublic class DiComponent {
@Inject
GreetService greetService;}
Servicelookup the efx waye4 built-in - single valuepublic class DiComponent {
@Inject
GreetService greetService;}
NO e4 built-in - multi value
Servicelookup the efx waye4 built-in - single value
public class DiComponent {@Inject
List<GreetService> greetService;}
public class DiComponent {@Inject
GreetService greetService;}
NO e4 built-in - multi value
Servicelookup the efx waye4 built-in - single value
public class DiComponent {@Inject
List<GreetService> greetService;}
public class DiComponent {@Inject
GreetService greetService;}
public class DiComponent {@Inject@ServiceGreetService greetService;
}
NO e4 built-in - multi value
Servicelookup the efx waye4 built-in - single value
public class DiComponent {@Inject
List<GreetService> greetService;}
public class DiComponent {@Inject
GreetService greetService;}
public class DiComponent {@Inject@ServiceGreetService greetService;
}
NO e4 built-in - multi valuepublic class DiComponent {
@Inject@ServiceList<GreetService> greetService;
}
Servicelookup the efx way
Servicelookup the efx waye4 static lookup single value
Servicelookup the efx waye4 static lookup single value
public class Component {public void m(IEclipseContext c) {
A g = c.get(A.class);}
}
Servicelookup the efx waye4 static lookup single value
public class Component {public void m(IEclipseContext c) {
A g = c.get(A.class);}
}
NO e4 static lookup multi value
Servicelookup the efx waye4 static lookup single value
public class Component {public void m(IEclipseContext c) {
A g = c.get(A.class);}
}
NO e4 static lookup multi value
public class Component {public void m(IEclipseContext c) {
List<A> s =c.get(/*NO EXPRESSION*/);
}}
Servicelookup the efx waye4 static lookup single value
public class Component {public void m(IEclipseContext c) {
A g = c.get(A.class);}
}
NO e4 static lookup multi value
public class Component {public void m(IEclipseContext c) {
List<A> s =c.get(/*NO EXPRESSION*/);
}}
import static o.e.f.c.ServiceUtils.*;
public class Component {public void m() {
Optional<A> g = getService(A.class);}
}
Servicelookup the efx waye4 static lookup single value
public class Component {public void m(IEclipseContext c) {
A g = c.get(A.class);}
}
NO e4 static lookup multi value
public class Component {public void m(IEclipseContext c) {
List<A> s =c.get(/*NO EXPRESSION*/);
}}
import static o.e.f.c.ServiceUtils.*;
public class Component {public void m() {
Optional<A> g = getService(A.class);}
}
import static o.e.f.c.ServiceUtils.*;
public class Component {public void m() {
List<A> g =getServiceList(A.class);
}}
Q: Dude. You showed IEclipseContext usage?
Really?
IEclipseContextretrieving & publishing to information in e4
IEclipseContextretrieving & publishing to information in e4EclipseContext@1
IEclipseContextretrieving & publishing to information in e4
EclipseContext@2
EclipseContext@1
IEclipseContextretrieving & publishing to information in e4
EclipseContext@2
[email protected]: Person@1MWindow: MWindowImpl@1…
IEclipseContextretrieving & publishing to information in e4
EclipseContext@2
[email protected]: Person@1MWindow: MWindowImpl@1…
MPart: MPartImpl@1…
IEclipseContextretrieving & publishing to information in e4
public class A {@InjectPerson p;
}
EclipseContext@2
[email protected]: Person@1MWindow: MWindowImpl@1…
MPart: MPartImpl@1…
IEclipseContextretrieving & publishing to information in e4
public class A {@InjectPerson p;
}
public class B {@Injectprivate IEclipseContext c;
public void m() {c.getParent().set(Person.class,p);
}}
EclipseContext@2
[email protected]: Person@1MWindow: MWindowImpl@1…
MPart: MPartImpl@1…
IEclipseContextretrieving & publishing to information in e4
public class A {@InjectPerson p;
}
public class B {@Injectprivate IEclipseContext c;
public void m() {c.getParent().set(Person.class,p);
}}
EclipseContext@2
[email protected]: Person@1MWindow: MWindowImpl@1…
MPart: MPartImpl@1…
IEclipseContextretrieving & publishing to information in e4
public class A { @Inject Person p; }
public class B { @Inject private IEclipseContext c;
public void m() { c.getParent().set(Person.class,p); } }
EclipseContext@2
[email protected]: Person@1 MWindow: MWindowImpl@1…
MPart: MPartImpl@1…
IEclipseContextretrieving & publishing to information in efxclipse
public class A { @Inject Person p; }
public class B { @Inject @ContextValue("my.Person") private Consumer<Person> c;
public void m() { c.accept(p); } }
EclipseContext@2
[email protected]: Person@1 MWindow: MWindowImpl@1…
MPart: MPartImpl@1…
Q:So you have your JavaFX renderer is it production ready?
Success story‣ forumSTAR (new)
‣ Expected development time: 5 years
‣ Number of users: > 100,000
‣ Number of developers: > 100
‣ Total volume: > 100 Million €
Source: http://modernisierung.site/summary/
Q: Let’s talk about the future? What’s cooking?
e4 editor story
There is NONE
e4 editor story
efxclipse-editor story
efxclipse-editor story
Eclipse 4 Application Platform
efxclipse-editor story
Eclipse 4 Application Platform
Core-API (eg resource-abstraction, auto-complete,…)
efxclipse-editor story
Eclipse 4 Application Platform
Core-API (eg resource-abstraction, auto-complete,…)
Presentation API
efxclipse-editor story
Eclipse 4 Application Platform
Core-API (eg resource-abstraction, auto-complete,…)
Core-EFS (use IProject, IFile,..)
Core-NIO (use java.nio.file.Path, …)
Presentation API
efxclipse-editor story
Eclipse 4 Application Platform
Core-API (eg resource-abstraction, auto-complete,…)
Core-EFS (use IProject, IFile,..)
Core-NIO (use java.nio.file.Path, …)
Presentation API
JavaFX SWT*
* does not exist
Q: Tom. Do I really need to use OSGi (and the Eclipse IDE) in
future?
NO!
NO!(at least not for e4 on JavaFX)
Platform of the future
Platform of the future
JVM
Platform of the future
JVM
OSGi
Platform of the future
JVM
efx-coreEclipse 4 App Platform
OSGi
Platform of the future
JVM
efx-coreEclipse 4 App Platform
OSGi
efx-platform
Platform of the future
JVM
efx-coreEclipse 4 App Platform
OSGi
efx-platform
Platform of the future
JVM
efx-coreEclipse 4
App Platform
efx-platform
Q:So you create a fork?
Thanks for listening