java ee 8 finally final! now what? - jfokus · copyright © 2018, oracle and/or its affiliates....
TRANSCRIPT
Copyright©2018,Oracleand/oritsaffiliates.Allrightsreserved.|
JavaEE8finallyfinal!Nowwhat?
February2018DavidDelabassee-@delabasseeOracle
Copyright©2018,Oracleand/oritsaffiliates.Allrightsreserved.| 2
Copyright©2018,Oracleand/oritsaffiliates.Allrightsreserved.|
SafeHarborStatementThefollowingisintendedtooutlineourgeneralproductdirecJon.ItisintendedforinformaJonpurposesonly,andmaynotbeincorporatedintoanycontract.Itisnotacommitmenttodeliveranymaterial,code,orfuncJonality,andshouldnotberelieduponinmakingpurchasingdecisions.Thedevelopment,release,andJmingofanyfeaturesorfuncJonalitydescribedforOracle’sproductsremainsatthesolediscreJonofOracle.
3
Copyright©2017,Oracleand/oritsaffiliates.Allrightsreserved.|
Jfokus2017
4
The reports of my death
aregreatlyexaggerated.JavaEE
“
Copyright©2018,Oracleand/oritsaffiliates.Allrightsreserved.|
Today–JavaEE8• ReleasedSept.212017
• GlassFish5-OpenSourceRI– hYps://javaee.github.io/glassfish/– hYps://hub.docker.com/r/oracle/glassfish/
• Open– hYps:/github.com/javaee/
– hYps://javaee.groups.io/
5
Copyright©2018,Oracleand/oritsaffiliates.Allrightsreserved.|
Tomorrow-EclipseEnterpriseforJavaMovingJavaEEtoEclipseFoundaAon
6
Technology
Communityand
VendorsSponsorship
ü Nimbleü Flexibleü Openü CompaJble
EnterpriseforJava
hYps://projects.eclipse.org/projects/ee4j/
Copyright©2018,Oracleand/oritsaffiliates.Allrightsreserved.|
WhyEclipse?
• JavaandJavaEEfriendly– EclipseYasson– EclipseLink
• MicroProfile.IO• Welldefinedprocesses• Etc.• PSA:EE4Jare2differentprojects!
7
Copyright©2018,Oracleand/oritsaffiliates.Allrightsreserved.|
EE4J
• ShipaJavaEE8-compliantreleaseasquicklyaspossible!• DemonstratethattheEE4JprojectsarefullyfuncJonalasopensourceprojects– Eg.Buildinfrastrcuture
• FosteranecosystemaroundtheEE4Jcode
ObjecAves–ShortTerm
8
Copyright©2018,Oracleand/oritsaffiliates.Allrightsreserved.|
EE4J
• DefineprocessestoevolveEE4Jtechnologies– Inc.GovernanceandIPflows
• DefinecompaJbilityrulesandbrandingprocessforimplementaJonstoensureapplicaJonportability• SeeEE.NextWGdrakcharter– hYps://www.eclipse.org/org/workinggroups/eclipse_ee_next_charter.php
ObjecAves–MidTerm
9
Copyright©2018,Oracleand/oritsaffiliates.Allrightsreserved.|
EE4J
• PMCestablished– IvarGrimstad,IBM,Oracle,Payara,RedHat,Tomitribe&Eclipse
• Brandname– Staytunned
• EE.NextWGdrakcharter• Code?
Reportcard
10
Copyright©2018,Oracleand/oritsaffiliates.Allrightsreserved.|
EE4J
• Done!– EclipseGrizzly– EclipseOpenMQ– EclipseProjectforJAX-RS– EclipseProjectforJMS– EclipseTyrus– EclipseProjectforWebSocket– EclipseProjectforJSONProcessing– EclipseYasson(*)– EclipseLink(*)
Reportcard
11
• Ongoing– EclipseJersey– EclipseMojarra
• Next– JSON-BAPI– Concurrency– Security– JTA– JavaMail
– JAX-B&JAX-WS– JSTL– UEL– JAF– etc.
hYps://github.com/eclipse-ee4j
Copyright©2018,Oracleand/oritsaffiliates.Allrightsreserved.| 12
Copyright©2018,Oracleand/oritsaffiliates.Allrightsreserved.|
JAX-RS
13
Copyright©2018,Oracleand/oritsaffiliates.Allrightsreserved.|
JAX-RSClientAPI
• FluentAPI– ClientBuilderèClientèWebTargetèRequestbuildingèResponse
javax.ws.rs.client.Clientinterface
14
List<Forecast>forecast=ClientBuilder.newClient().target("http://weath.er/cities").request().accept("application/json").header("foo","bar").get(newGenericType<List<Forecast>>(){});
Copyright©2018,Oracleand/oritsaffiliates.Allrightsreserved.|
JAX-RSClientAPIAsynchronousinvocaAon
15
Future<String>fCity=client.target("http://locati.on/api").queryParam("city","Paris").request().async().get(String.class);
Stringcity=fCity.get();
Copyright©2018,Oracleand/oritsaffiliates.Allrightsreserved.|
JAX-RSClientAPI
WebTargetmyResource=client.target("http://examp.le/api/read");Future<Customer>future=myResource.request(MediaType.TEXT_PLAIN)
.async().get(newInvocationCallback<Customer>(){ @Override publicvoidcompleted(Customercustomer){ //dosomethingwiththecustomer } @Override publicvoidfailed(Throwablethrowable){ //Oops! }});
…
InvocaAonCallback
16
Copyright©2018,Oracleand/oritsaffiliates.Allrightsreserved.|
JAX-RSClientAPI
NewJAX-RSReacAveInvoker
17
//JAX-RS2.0Responseresponse=client.target(recommandationService).request().get();
Future<Response>futureResponse=client.target(recommandationService).request().async().get();//JAX-RS2.1CompletionStage<Response>completionStageResp=client.target(recommandationService).request().rx().get();
Copyright©2018,Oracleand/oritsaffiliates.Allrightsreserved.| 18
JAX-RS2.1
CompletionStage<JsonObject>cfIp=client.target("http://api.ipify.org/") .queryParam("format","json").request() .rx() .get(JsonObject.class);
Function<JsonObject,CompletionStage<JsonObject>>function=ip
->client.target("https://ipvigilante.com") .path(ip.getString("ip")).request() .rx() .get(JsonObject.class);
cfIp.thenCompose(function).thenAccept(System.out::println);
Copyright©2018,Oracleand/oritsaffiliates.Allrightsreserved.|
JAX-RS2.1–ClientAPI
19
Sync Async RXPerformanceandscalability ✗✗ ✔ ✔Easytodevelopandmaintain ✔ ✗ ✔
…complexworkflow ✗ ✗ ✔…errorhandling ✗ ✗ ✔
LeveragenewJavaSEfeature ✗ ✗ ✔
Copyright©2018,Oracleand/oritsaffiliates.Allrightsreserved.|
JAX-RS2.1–RXInvoker• ImplementaJonsMUSTsupportaninvokerforCompleAonStage• ImplementaJonsMAYsupportotherreacJveAPIs• Jersey– CompleJonStageRxInvoker(Default)– RxListenableFutureInvoker–Guava
20
hYps://github.com/jersey/jersey/tree/master/ext/rx
client.register(RxFlowableInvokerProvider.class);client.target(...)....rx(RxFlowableInvoker.class).get();
– RxObservableInvoker–RxJava– RxFlowableInvoker–RxJava2
Copyright©2018,Oracleand/oritsaffiliates.Allrightsreserved.|
Server-SentEvents• WHATWGstandard• Supportedinallmodernbrowsers• Persistent,one-waycommunicaJonchannel• Textprotocol,specialmediatype"text/event-stream"• ServercansendmulJplemessages(events)toaclient• Cancontainid,name,comment,retryinterval
21
Copyright©2018,Oracleand/oritsaffiliates.Allrightsreserved.|
Server-SentEvents• javax.ws.rs.sse.SseEventinterface• OutboundSseEvent– Server-siderepresentaJonofaServer-Sentevent– OutboundSseEvent.Builder()
• InboundSseEvent– Client-siderepresentaJonofaServer-Sentevent
22
Copyright©2018,Oracleand/oritsaffiliates.Allrightsreserved.|
Server-SentEvents
23
• SseEventSink– OutboundServer-SentEventsstream
@GET@Path("sse")@Produces(MediaType.SERVER_SENT_EVENTS)publicvoideventStream(@ContextSseEventSinkeventSink,@ContextSSEsse){...eventSink.send(sse.newEvent("anevent"));eventSink.send(sse.newEvent("anotherevent"));...eventSink.close();}
Server-side
Copyright©2018,Oracleand/oritsaffiliates.Allrightsreserved.|
Server-SentEvents
24
Clientside
• SseEventSource– ClientforprocessingincomingServer-SentEvents
WebTargettarget=client.target("http://…");try(SseEventSourcesource=SseEventSource.target(target).reconnectingEvery(5,SECONDS).build()){source.register(System.out::println);//InboundSSEventconsumer...source.open();}catch(InterruptedExceptione){//Ooops}
Copyright©2018,Oracleand/oritsaffiliates.Allrightsreserved.|
JAX-RS2.1• ResourcemethodcanreturnaCompleJonStage• @PATCH• JSON-P&JSON-Bsupport• NewClientBuildermethods– #connectTimeout(long,TimeUnit);– #scheduledExecutorService(ScheduledExecutorService);
• ApplicaJonprovidedproviderspriority…
25
Copyright©2018,Oracleand/oritsaffiliates.Allrightsreserved.|
JSON
26
Copyright©2018,Oracleand/oritsaffiliates.Allrightsreserved.|
JSON-P1.1• StandardAPItoparse,generate,transform,queryJSON• UpdateJSON-Pspectostaycurrentwithemergingstandards(RFC7159)– JSONPointer(RFC6901)– JSONPatch(RFC6902)– JSONMergePatch(RFC7396)
• AddediJng/transformaJonoperaJonstoJSONobjectsandarrays• SupportJSONCollectors• SupportforprocessingbigJSON
27
Copyright©2018,Oracleand/oritsaffiliates.Allrightsreserved.|
JSONPointer• IETFRFC6901• StringsyntaxforidenJfyingaspecificvalue– Token(s)separatedby"/"• specifykeyinobject• orindexintoarray
– Ex."/event/locaJon","/conferences/0"• Specialcases– Escape"/"with"~1"and"~"with"~0"– "/"pointstothe""keyintheroot– "-"referstotheendofanarray
28
Copyright©2018,Oracleand/oritsaffiliates.Allrightsreserved.|
JSONPointerJsonStructurejsonEvents=…
JsonPointerpt=Json.createPointer("/1/venue");
JsonValuepreEvt=pt.getValue(jsonEvents);//"Hilton"
JsonStructurenewEvt=pt.replace(jsonEvents,Json.createValue("MosconeWest"));//+add,remove&containsValue
29
[{"event":"OpenWorld","venue":"MosconeNorth"},{"event":"JavaOne","venue":"Hilton"}][{"event":"OpenWorld","venue":"MosconeNorth"},{"event":"JavaOne","venue":"MosconeWest"}]
Copyright©2018,Oracleand/oritsaffiliates.Allrightsreserved.|
JSONPatch• IETFRFC6902• ModifyPartsofJSONdocument• PatchisaJSONdocumentitself• OperaJons– Add,replace,remove,move,copy&test
• HTTPPATCHmethod(applicaJon/json-patch+json)
30
Copyright©2018,Oracleand/oritsaffiliates.Allrightsreserved.| 31
JSONPatch[{"op":"replace","path":"/0/venue","value":"MosconeWest"},{"op":"add","path":"/0/previousVenue","value":"Hilton"}]
[{"event":"JavaOne","venue":"Hilton"}]
Copyright©2018,Oracleand/oritsaffiliates.Allrightsreserved.| 32
JSONPatch[{"op":"replace","path":"/0/venue","value":"MosconeWest"},{"op":"add","path":"/0/previousVenue","value":"Hilton"}]
[{"event":"JavaOne","venue":"MosconeWest"}]
Copyright©2018,Oracleand/oritsaffiliates.Allrightsreserved.| 33
JSONPatch[{"op":"replace","path":"/0/venue","value":"MosconeWest"},{"op":"add","path":"/0/previousVenue","value":"Hilton"}]
[{"event":"JavaOne","venue":"MosconeWest","previousVenue":"Hilton"}]
Copyright©2018,Oracleand/oritsaffiliates.Allrightsreserved.|
JSONPatch
34
JsonArraypreviousJ1=…JsonArraypatch=…
JsonPatchjpVenue=Json.createPatch(patch);
JsonArraycurrentJ1=jpVenue.apply(previousJ1);
JsonPatchpatch2018=Json.createPatchBuilder().copy("/0/previousVenue","/0/venue").replace("/0/venue","MosconeNorth&South").add("/0/days",6).build();
JsonArraynextJ1=patch2018.apply(previousJ1);
Copyright©2018,Oracleand/oritsaffiliates.Allrightsreserved.|
JSON-P1.1
• JSONMergePatch• Merge&MergePatchDiff• JSON-Pcollectors• SupportforprocessingbigJSON– FilterstoJSONparsing:skipArray(),skipObject()
• …
35
Misc.
Copyright©2018,Oracleand/oritsaffiliates.Allrightsreserved.|
JSONBinding• APItoserialize/deserializeJavaobjectsto/fromJSONdocuments– SimilartoJAX-B– StandardAPIforexisJngframework(ex.Genson,Gson)
• DefaultmappingbetweenclassesandJSON• CustomizaJonAPIs– AnnotaJons(@JsonbProperty,@JsonbNillable)– RunJmeconfiguraJonbuilder
• NaturalfollowontoJSON-P– ClosestheJSONsupportgap– Allowstochangeproviders
36
Copyright©2018,Oracleand/oritsaffiliates.Allrightsreserved.|
JSON-B
37
//publicEvent(Stringname,intedition,Stringvenue)
List<Event>events=newArrayList<>();h2.add(newEvent("JavaOne",2017,"SFO"));h2.add(newEvent("OpenWorld",2017,"SFO"));h2.add(newEvent("Devoxx",2017,"Antwerp"));Jsonbjsonb=JsonbBuilder.create();StringnextUp=jsonb.toJson(events);
[{"edition":2017,"name":"JavaOne","venue":"SFO"},{"edition":2017,"name":"OpenWorld","venue":"SFO"},{"edition":2017,"name":"Devoxx","venue":"Antwerp"}]
Copyright©2018,Oracleand/oritsaffiliates.Allrightsreserved.|
JSON-B
38
Stringq1Confs="…";
Jsonbjsonb=JsonbBuilder.create();
Eventevent=jsonb.fromJson(q1Confs,Event.class);
{"edition":2018,"name":"OracleCode","venue":"Global","cost":0}
Copyright©2018,Oracleand/oritsaffiliates.Allrightsreserved.|
• AnnotaJon– @JsonbProperty
• Scope– Field– GeYer/SeYer– Parameter
39
JSON-BCustomizaJonspublicclassEvent{privateintedition;@JsonbProperty("conference")privateStringeventName;}publicclassCustomer{publicintedition;publicStringvenue;@JsonbProperty("conference")publicStringgetEventName(){returneventName;}}
Copyright©2018,Oracleand/oritsaffiliates.Allrightsreserved.|
JSON-BCustomizaJons• Namingstrategies– IDENTITY:myProp– LOWER_CASE_WITH_DASHES:my-prop
– LOWER_CASE_WITH_UNDERSCORES:my_prop– UPPER_CAMEL_CASE:MyProp– UPPER_CAMEL_CASE_WITH_SPACES:MyProp
– CASE_INSENSITIVE:myprop– Oracustomstrategy
40
• Propertyordering– Any,Lexicographical,Reverse
• BinaryDataStrategies– Base64,Base64URL,Byte
Copyright©2018,Oracleand/oritsaffiliates.Allrightsreserved.|
JSON-BCustomizaJons• Propertytoignore• Nullhandling• CustominstanJaJon• Fieldsvisibility• Date/NumberFormats• ...
41
Copyright©2018,Oracleand/oritsaffiliates.Allrightsreserved.| 42
JSON-BCustomizaJons
//Ordering,namingstrategy,encoding,Locale,…
JsonbConfigconfig=newJsonbConfig().withFormatting(true).withAdapters(newCarAdapter());
Jsonbjsonb=JsonbBuilder.create(config);Jsonbjsonb=JsonBuilder.newBuilder("anotherProvider");
Copyright©2018,Oracleand/oritsaffiliates.Allrightsreserved.|
Web
43
Copyright©2018,Oracleand/oritsaffiliates.Allrightsreserved.|
Servlet4.0• SupportforHTTP/2– Request/responsemulJplexing– Serverpush– UpgradefromHTTP1.1
• Smallercommunity-requestedimprovements– Allowse}ngthedefaultcontext-pathwithoutresorJngtocontainerspecificconfig– Allowse}ngthejsp-fileprogrammaJcally– Allowencodingtobesetfromdeploymentdescriptor– ServletMappingAPI
44
Copyright©2018,Oracleand/oritsaffiliates.Allrightsreserved.|
HTTP/2• BinaryFramingoversingleTCPconnecJon• Request/ResponsemulJplexing• StreamPrioriJzaJon• ServerPush• UpgradefromHTTP1.1• HeaderCompression• PreserveHTTPsemanJc• FlowControl
45
Copyright©2018,Oracleand/oritsaffiliates.Allrightsreserved.|
Servlet4.0
46
PushBuilderbuilder=myRequest.newPushBuilder();builder.addHeader("X-Pusher",…);builder.path("resource").push();
Copyright©2018,Oracleand/oritsaffiliates.Allrightsreserved.|
JSF2.3• HTTP/2ServerPush• BeYerCDIIntegraJon– Waymorethingsareinjectable
• JavaTimesupport• WebSocketIntegraJon• AjaxMethodInvocaJon• ClassLevelBeanValidaJon• UIDataandUIRepeatimprovements
47
Copyright©2018,Oracleand/oritsaffiliates.Allrightsreserved.|
CDI2.0&BV2.0
48
Copyright©2018,Oracleand/oritsaffiliates.Allrightsreserved.|
CDI2.0• DefinebehaviorofCDIoutsideofaJavaEEcontainer– Inc.APItobootstrapaCDIcontainerinJavaSE
• Specsplitinto3parts– CDICore– CDIforJavaSE– CDIforJavaEE
• ApplyInterceptoronProducer• Observersordering• Asynchronousevents• AlignmentwithJavaSE8,…
49
Copyright©2018,Oracleand/oritsaffiliates.Allrightsreserved.|
CDI1.2
50
@InjectEvent<PaymentEvent>debitEvent;//producerdebitEvent.fire(somePayload);
//consumerpublicvoidanObesrver(@ObservesPayloadp){…}
Copyright©2018,Oracleand/oritsaffiliates.Allrightsreserved.|
CDI1.2
51
//consumerApublicvoidanObserver(@ObservesPayloadp){…}//consumerBpublicvoidanotherObesrver(@ObservesPayloadp){…}
Copyright©2018,Oracleand/oritsaffiliates.Allrightsreserved.|
CDI2.0
52
//consumerApublicvoidanObesrver(@Observes@Priority(10)Payloadp){…}//consumerBpublicvoidanotherObesrver(@Observes@Priority(20)Payloadp){…}
Copyright©2018,Oracleand/oritsaffiliates.Allrightsreserved.|
CDI2.0
53
@InjectEvent<PaymentEvent>debitEvent;//asyncproducerCompletionStage<Payload>cs=debitEvent.fireAsync(somePayload);
//asyncconsumerpublicvoidanObesrver(@ObservesAsyncPayloadp){…}
Copyright©2018,Oracleand/oritsaffiliates.Allrightsreserved.|
BeanValidaJon2.0• EmbraceJavaSE8– SupportfornewDate/TimeAPI– ConstraintsappliedtocollecJonelements– OpJonalwrappers– RepeatableannotaJons
• Introducenewconstraints– @NotEmpty,@NotBlank,@Email– @PastOrPresent,@FutureOfPresent– @PosiJve,@PosiJveOrZero,@NegaJve,@NegaJveOrZero
• …
54
Copyright©2018,Oracleand/oritsaffiliates.Allrightsreserved.|
Security
55
Copyright©2018,Oracleand/oritsaffiliates.Allrightsreserved.|
IdenJtyStore• ProvideastoragesystemwherecallercredenJalsanddataarestored– LDAP,DataBase,...
• PerformcallervalidaJonanddetailsretrieval– In:Validcallername&password– Out:(Possiblydifferent)callernameand/orassociatedgroup(s)
• Doesnotinteractwiththecaller!
56
Copyright©2018,Oracleand/oritsaffiliates.Allrightsreserved.|
IdenJtyStore
57
@DatabaseIdentityStoreDefinition(dataSourceLookup="${'java:global/MyDS'}",callerQuery="#{'selectpasswordfromcallerwherename=?'}",groupsQuery="selectgroup_namefromcaller_groupswherecaller_name=?",hashAlgorithm=Pbkdf2PasswordHash.class,priorityExpression="#{100}",hashAlgorithmParameters={"Pbkdf2PasswordHash.Iterations=3072","${applicationConfig.dyna}"})
Copyright©2018,Oracleand/oritsaffiliates.Allrightsreserved.|
AuthenJcaJonMechanism• CDIenabledversionofServerAuthModulethatcompliestotheJASPICServletContainerProfile• EncouragedtouseanIdenAtyStore– CallercredenJalvalidaJon– Callerdetailsretrieval
• Built-in– @BasicAuthenJcaJonMechanismDefiniJon– @FormAuthenJcaJonMechanismDefiniJon– @CustomFormAuthenJcaJonMechanismDefiniJon
58
Copyright©2018,Oracleand/oritsaffiliates.Allrightsreserved.|
AuthenJcaJonMechanism• NewHUpAuthenAcaAonMechanisminterface(javax.security.enterprise.authenJcaJon.mechanism.hYp)– voidcleanSubject(HYpServletRequest,HYpServletResponse,HYpMessageContext)– AuthenJcaJonStatusvalidateRequest(Req,Resp,MCtx)throwsAuthExcepJon; – AuthenJcaJonStatussecureResponse(Req,Resp,MCtx)throwsAuthExcepJon;
59
Copyright©2018,Oracleand/oritsaffiliates.Allrightsreserved.|
SecurityAPIforJavaEE
60
@WebServlet("/protectedServlet")@ServletSecurity(@HttpConstraint(rolesAllowed="foo"))publicclassProtectedServletextendsHttpServlet{...}
@ApplicationScopedpublicclassmyAuthMechimplementsHttpAuthenticationMechanism{
@InjectprivateIdentityStoreHandlermyIdentityStore;
AuthenticationStatusstatusvalidateRequest(HttpServletRequestreq,HttpServletResponseres,HttpMessageContextctx)throwsAuthenticationException{...
Copyright©2018,Oracleand/oritsaffiliates.Allrightsreserved.|
Wrap-up
61
Copyright©2018,Oracleand/oritsaffiliates.Allrightsreserved.|
JavaEE8–ModernizaJon&SimplificaJon
62
CDI2.0
JSON-B1.0(*)
Security1.0(*)
BeanValidaAon2.0
JSF2.3
Servlet4.0
JSON-P1.1
JAX-RS2.1 ReacJveClientAPI,Server-SentEvents,…
HTTP/2,ServerPush,…
Java<->JSONbinding
UpdatestoJSONstandards,JSONCollectors,…
AsyncEvent,Observersordering,SEsupport,…
EmbraceJavaSE8,newconstraints,…
ImprovedCDI,WebSocket,SE8integraJon,…
PortableIdenJtyStore,AuthenJcaJon&SecurityContext
Copyright©2018,Oracleand/oritsaffiliates.Allrightsreserved.|
Tomorrow–EE4J
63
• “EE4J1.0”willbecompaJblewithJavaEE8• Jointhediscussion– hYps://dev.eclipse.org/mhonarc/lists/ee4j-community/
Copyright©2018,Oracleand/oritsaffiliates.Allrightsreserved.|
Tack!
64