softshake 2014 - java ee
DESCRIPTION
Le temps est révolu où Java EE ne serait qu’à développer des applications de mise à jour de données, avec JSF / EJB / JPA. Aujourd’hui Java EE s’est assoupli et s’est ouvert sur le monde, avec CDI comme clé de voûte et a repoussé nos limites grâce à des capacités d’extension puissantes et faciles d’utilisation comme JCA. Dans un premier temps, nous reviendrons rapidement sur la place de CDI dans JavaEE 7 et sur ses mécanismes d’extension. Dans un deuxième temps, nous verrons les techniques de connecteurs JCA et comment ils peuvent aussi constituer une possibilité d’ouverture simple à mettre en œuvre. JCA fournit des techniques pour gérer des connexions sortantes ou entrantes, sur des formats ou protocoles variés.TRANSCRIPT
Avec JavaEE, fais ce que tu veux…
Alexis Hassler
Alexis Hassler• Développeur, formateur Java
• Indépendant
• Co-leader du
• @AlexisHassler
Java EE1° partie
http://www.public-domain-image.com/
CDI
Java EEJSF
EJB 3
JPA
JAX-RSWebSocket
CDI
JCA
MQTT
Broker
Consumer
Consumer
Consumer
Producer
Producer
Producer
Topic
Topic
Topic
Topic
SubscribePublish
MQTT
http://commons.wikimedia.org/wiki/File:St_Jude_Medical_pacemaker_with_ruler.jpg
MQTT
JCA2° partie
http://www.public-domain-image.com/
Java Connector
Architecture
Java EE
EISApp
Con
nect
or
Java EE
Outbound
Java EE
EISApp
Con
nect
or
Java EE
App
Dat
aSou
rce
Resourcepublic class SomeNiceBean { @Resource(name="jdbc/SomeDS") DataSource dataSource; public void doTheJob() { Connection connection = dataSource.getConnection(); ... }}
MQTT Connection Factory
public class SomeNiceBean { @Resource(name="mqtt/QuestionCF") ConnectionFactory connectionFactory; public void doTheJob() { connectionFactory.getConnection() .publish(message); }}
ImplementationAPI
ManagedConnection Factory
ConnectionFactory
ManagedConnectionConnection
Resource Adapter
ManagedConnection Factory
ConnectionFactorynew
ManagedConnection
new
ConnectionManager
Connection
ResourceAdapter
new
ConnectionEventListener XAResource
LocalTransaction
ManagedConnectionMetaData
Inbound
Java EE
App
Con
nect
or
EIS
Message Driven Bean
Java EE
MDBJMS
Destination
Con
nect
or
JMS Message Driven Bean
@MessageDriven(activationConfig = { @ActivationConfigProperty(propertyName="destinationLookup", propertyValue="swt/Question"), @ActivationConfigProperty(propertyName="destinationType", propertyValue="javax.jms.Queue"), }) public class MyJmsBean implements MessageListener { @Override public void onMessage(Message message) { ... } }
MQTT Message Driven Bean
@MessageDriven( activationConfig = { @ActivationConfigProperty(propertyName = "topicName", propertyValue = "swt/Question") } ) public class MyMqttBean implements MqttListener { @Override public void onMessage(Message message) { ... } }
ImplementationAPI
ResourceAdapterListener
ActivationSpecMessage
XAResource
WorkerManager
BootstrapContext
Connector APIpublic interface MqttListener { void onMessage(Message message); }
public class Message { private byte[] payload; public Message(byte[] payload) { this.payload = payload; } // + Getter}
Message Driven Bean ++@MessageDrivenpublic class MyMqttBean implements MqttListener { @TopicName("swt/Question") public void onQuestion(Message message) { ... }
@TopicName("swt/Answer") public void onAnswer(Message message) { ... }
}
Connector
mqtt-ra.rar
Application(w. MDB)
mqtt-ra-example.war
WildFly
MQTTBroker
(mosquitto)
MQTT Clientmosquitto pub/sub
C D I3° partie
http://www.picturesdepot.com/
Context & Dependency Injection
• IoC pour Java EE et Java SE
• Gestion des contextes
• Liant pour la plupart des spec Java EE
• Moteur d’extensions pour Java EE
@Inject
Dependency Injection
public class MessageService { @Override public String message() { return "Bonjour le monde !"; } }
Dependency Injectionpublic class HelloBean { @Inject MessageService service; public void displayHello() { display( frService.message() ); } }
Qualifiers
public class EnglishMessageService implements MessageService { public String message() { return "Hello World!"; } }
public class FrenchMessageService implements MessageService { public String message() { return "Bonjour le monde !"; } }
Qualifiers
@Qualifier@Retention(RUNTIME) @Target({FIELD, TYPE, METHOD, PARAMETER})public @interface English {}
@Qualifier@Retention(RUNTIME) @Target({FIELD, TYPE, METHOD, PARAMETER})public @interface French {}
Qualifiers
@English public class EnglishMessageService implements MessageService { public String message() { return "Hello World!"; } }
@French public class FrenchMessageService implements MessageService { public String message() { return "Bonjour le monde !"; } }
Qualifiers
public class HelloBean { @Inject @French MessageService service; public void displayHello() { display(service.message()); } }
Programmatic lookuppublic class HelloBean { @Inject Instance<MessageService> service; public void displayHello() { if (! service.isUnsatisfied()) { display(service.get().message()); } } }
Programmatic lookuppublic class HelloBean { @Inject @Any Instance<MessageService> services; public void displayHello() { for (MessageService service : services) { display(service.message()); } } }
Contexts
@ApplicationScopedpublic class MessageService { ... }
@RequestScoped@ConversationScoped@SessionScoped
@Dependent
Decorators@Decorator@Priority(Interceptor.Priority.APPLICATION) public class MessageDecorator implements MessageService { @Inject @Delegate @Any MessageService service; public String message() { return service.message() + " -decorated"; } }
http://pixabay.com/
Interceptors
http://commons.wikimedia.org/
Interceptors
@InterceptorBinding@Target({METHOD, TYPE}) @Retention(RUNTIME) public @interface Loggable {}
Interceptors@Interceptor @Loggablepublic class LogInterceptor { @AroundInvoke public Object log(InvocationContext ic) throws Exception { System.out.println("Entering " + ic.getMethod().getName()); try { return ic.proceed(); } finally { System.out.println("Exiting " + ic.getMethod().getName()); } }}
Interceptors
@Loggablepublic class HelloBean { @Inject MessageService service; public void displayHello() { display(service.message()); } }
Producers
http://commons.wikimedia.org/
Producers
public class FacesProducer { @Produces @RequestScoped public FacesContext produceFacesContext() { return FacesContext.getCurrentInstance(); } }
Producers
@Produces public Logger produceLogger( InjectionPoint injectionPoint) { String loggerName = injectionPoint .getMember() .getDeclaringClass() .getName(); return Logger.getLogger(loggerName); }
public class HelloBean { @Inject MessageService service; @Inject Event<Message> messageEvent; public void displayHello() { display(service.message()); messageEvent.fire( new Message(frService.message())); } }
Events
Events
public class MessageReceiver { public void receive(@Observes Message message) { System.out.println("Received: " + message.text); } }
Synthèse
ContextInjection
Decoration Interception Event JavaEE Integration
Portable Extension
CDI Portable Extensions
Bean Manager• Interagir avec le conteneur CDI• Lecture seule
• Injectable
• JNDI• java:comp/BeanManager
public class HelloBean { @Inject BeanManager beanManager; ...}
Extension•Manipuler les métadonnées du container• AnnotatedType
• InjectionPoint / InjectionTarget
• BeanAttributes / Beans
• Producer, Observer
• Pendant le démarrage
Comment ?En observant les
événements déclenchés par le
conteneur CDI
Exemple (-)• Exclure les entités JPA
public class VetoEntityExtension implements Extension { public void vetoEntity( @Observes @WithAnnotations({Entity.class}) ProcessAnnotatedType<?> pat) { pat.veto(); }
}
Exemple (+)• Ajouter un bean
public class HashMapAsBeanExtension implements Extension { public void addHashMapAsAnnotatedType( @Observes BeforeBeanDiscovery bbd, BeanManager beanManager) { bbd.addAnnotatedType( beanManager.createAnnotatedType(HashMap.class) ); } }
CDI 1.1 LifecycleBefore Bean Discovery
Process BeanProcess
Annotated Type
ScanArchive
ApplicationRunning
After Deployment Validation
Before Shutdown
Undeploy Application
Process Producer
After Bean Discovery
ProcessInjection Target
Process Observer Method
ProcessInjection
Point
Process Bean Attributes
After Type Discovery
événement unique
événements multiples
étape interne
Deployment starts
Bean eligibility
check
Application
mqtt-cdi-example.war
WildFly
MQTTBroker
(mosquitto)
MQTT Clientmosquitto pub/sub
http://pixabay.com/
4° partieJCA // CDI
CDI
JCA
Managed Connection Factory
@ConnectionDefinition (connectionFactory = MqttConnectionFactoryImpl.class, connectionFactoryImpl = MqttConnectionFactoryImpl.class, connection = BlockingConnection.class, connectionImpl = BlockingConnection.class) public class MqttManagedConnectionFactory implements ManagedConnectionFactory, ResourceAdapterAssociation, Serializable { @Inject ResourceAdapter ra;
}
JCA
CDI
public class SomeNiceBean { @Inject MqttConnectionFactory connectionFactory; public void doTheJob() { Connection connection = connectionFactory.getConnection(); ... }}
javax.enterprise.inject. UnsatisfiedResolutionException
Java EE 8• Implicit Producers ?
• Ambiguities ?
• Qualifiers ?
JCA // CDI
JCA
ManagedConnection Factory
ConnectionFactorynew
ManagedConnection
new
ConnectionManager
Connection
ResourceAdapter
new
ConnectionEventListener
XAResource
LocalTransaction
ManagedConnectionMetaData
WorkerManager
CDIUserTransaction
ManagedExecutorService
ConnectionFactory Producer
ConnectionFactorynew
ConnectionLocalTransaction
Outbound Connector
JCA < CDI
Message Driven Bean@MqttDrivenpublic class MyMqttBean { @TopicName("swt/Question") public void onQuestion(Message message) { ... }
@TopicName("swt/Answer") public void onAnswer(Message message) { ... }
}
Message Observer@ApplicationScopedpublic class MyMqttBean { public void onQuestion( @Observes @TopicName(value = "swt/Question") Message message) { ... } public void onAnswer( @Observes @TopicName("swt/QuestionBis") Message message) { ... }
}
Threads
https://www.flickr.com/photos/mckaysavage/6491930649/
Inbound Connector
JCA > CDI
Java EE Application Server
App
CDI
App
CDI
App
CDI
JCA
?http://pixabay.com/fr/point-d-interrogation-boule-demande-65833/
Exemples• https://github.com/antoinesd/cdi-demo
• https://github.com/sewatech/mqtt-ra/
• https://github.com/hasalex/mqtt-cdi
• http://fr.slideshare.net/sewatech/
Version longue• Part 1 : Intro + CDI• https://parleys.com/play/536749d1e4b04bb59f502706
• Part 2 : JCA + Synthèse• https://parleys.com/play/5369f1f9e4b04bb59f502725