Whats up with Wicket 8 and Java 8 · Why Java 8 for Wicket 8? • Concise, clear code with Java 8...

108
What's up with Wicket 8 and Java 8 Martijn Dashorst Topicus Education

Transcript of Whats up with Wicket 8 and Java 8 · Why Java 8 for Wicket 8? • Concise, clear code with Java 8...

Page 1: Whats up with Wicket 8 and Java 8 · Why Java 8 for Wicket 8? • Concise, clear code with Java 8 Lambdas, Optional • Support for Java EE 7 and Java 8 in servers • Wish to get

What's up with Wicket 8 and Java 8

Martijn Dashorst Topicus Education

Page 2: Whats up with Wicket 8 and Java 8 · Why Java 8 for Wicket 8? • Concise, clear code with Java 8 Lambdas, Optional • Support for Java EE 7 and Java 8 in servers • Wish to get

APACHE WICKET

Martijn DashorstTopicus Education

What's Up with Wicket 8 and Java 8?

𝛌

Page 3: Whats up with Wicket 8 and Java 8 · Why Java 8 for Wicket 8? • Concise, clear code with Java 8 Lambdas, Optional • Support for Java EE 7 and Java 8 in servers • Wish to get

Martijn DashorstTopicus Education

twitter: @dashorst

Apache: dashorst

Page 4: Whats up with Wicket 8 and Java 8 · Why Java 8 for Wicket 8? • Concise, clear code with Java 8 Lambdas, Optional • Support for Java EE 7 and Java 8 in servers • Wish to get

Why Java 8 for Wicket 8

Wicket 8 Noteworthy Features

Java 8 Date Time

Java 8 Lambda's

Migration towards Wicket 8

Page 5: Whats up with Wicket 8 and Java 8 · Why Java 8 for Wicket 8? • Concise, clear code with Java 8 Lambdas, Optional • Support for Java EE 7 and Java 8 in servers • Wish to get

Why Java 8 for Wicket 8

Wicket 8 Noteworthy Features

Java 8 Date Time

Java 8 Optional

Java 8 Lambda's

Migration towards Wicket 8

Page 6: Whats up with Wicket 8 and Java 8 · Why Java 8 for Wicket 8? • Concise, clear code with Java 8 Lambdas, Optional • Support for Java EE 7 and Java 8 in servers • Wish to get

Why Java 8 for Wicket 8

Wicket 8 Noteworthy Features

Java 8 Date Time

Java 8 Optional

Java 8 Lambda's

Migration towards Wicket 8

Page 7: Whats up with Wicket 8 and Java 8 · Why Java 8 for Wicket 8? • Concise, clear code with Java 8 Lambdas, Optional • Support for Java EE 7 and Java 8 in servers • Wish to get

Why Java 8 for Wicket 8?• Concise, clear code with Java 8

Lambdas, Optional

• Support for Java EE 7 and Java 8 in servers

• Wish to get API right

• Semver

• Versions line up nicely Wicket 5 & Java 5 (wicket 1.5.x & Java 2 1.5.x) Wicket 6 & Java 6Wicket 7 & Java 7Wicket 8 & Java 8

Page 8: Whats up with Wicket 8 and Java 8 · Why Java 8 for Wicket 8? • Concise, clear code with Java 8 Lambdas, Optional • Support for Java EE 7 and Java 8 in servers • Wish to get

Wicket 9 → Java 9

Page 9: Whats up with Wicket 8 and Java 8 · Why Java 8 for Wicket 8? • Concise, clear code with Java 8 Lambdas, Optional • Support for Java EE 7 and Java 8 in servers • Wish to get

Wicket 8.0.0 final release?- won't ship with all bells/whistles

- might take a few months to get right (semver)

Page 10: Whats up with Wicket 8 and Java 8 · Why Java 8 for Wicket 8? • Concise, clear code with Java 8 Lambdas, Optional • Support for Java EE 7 and Java 8 in servers • Wish to get

Why Java 8 for Wicket 8

Wicket 8 Noteworthy Features

Java 8 Date Time

Java 8 Optional

Java 8 Lambda's

Migration towards Wicket 8

Page 11: Whats up with Wicket 8 and Java 8 · Why Java 8 for Wicket 8? • Concise, clear code with Java 8 Lambdas, Optional • Support for Java EE 7 and Java 8 in servers • Wish to get

Everything in 7.x

Page 12: Whats up with Wicket 8 and Java 8 · Why Java 8 for Wicket 8? • Concise, clear code with Java 8 Lambdas, Optional • Support for Java EE 7 and Java 8 in servers • Wish to get

Everything in 7.x

Java Eightyfication Optional<T>, default methods, lambda's everywhere

Page 13: Whats up with Wicket 8 and Java 8 · Why Java 8 for Wicket 8? • Concise, clear code with Java 8 Lambdas, Optional • Support for Java EE 7 and Java 8 in servers • Wish to get

"The ecosystem, stupid!"

"Innovation happens

elsewhere"

Page 14: Whats up with Wicket 8 and Java 8 · Why Java 8 for Wicket 8? • Concise, clear code with Java 8 Lambdas, Optional • Support for Java EE 7 and Java 8 in servers • Wish to get

• Short listhttp://wicket.apache.org/community/

• WicketStuffhttps://github.com/wicketstuff

• Wicket Spring Boothttps://github.com/MarcGiffing/wicket-spring-boot

• Wicket Bootstraphttps://github.com/l0rdn1kk0n/wicket-bootstrap

Page 15: Whats up with Wicket 8 and Java 8 · Why Java 8 for Wicket 8? • Concise, clear code with Java 8 Lambdas, Optional • Support for Java EE 7 and Java 8 in servers • Wish to get

Why Java 8 for Wicket 8

Wicket 8 Noteworthy Features

Java 8 Date Time

Java 8 Optional

Java 8 Lambda's

Migration towards Wicket 8

Page 16: Whats up with Wicket 8 and Java 8 · Why Java 8 for Wicket 8? • Concise, clear code with Java 8 Lambdas, Optional • Support for Java EE 7 and Java 8 in servers • Wish to get

Supported by converters

• LocalDateConverter

• LocalDateTimeConverter

• LocalTimeConverter

• Already registered for your convenience

Page 17: Whats up with Wicket 8 and Java 8 · Why Java 8 for Wicket 8? • Concise, clear code with Java 8 Lambdas, Optional • Support for Java EE 7 and Java 8 in servers • Wish to get

publicinterfaceIConverter<C>extendsIClusterable{CconvertToObject(Stringvalue,Localelocale) throwsConversionException;

StringconvertToString(Cvalue,Localelocale);}

Page 18: Whats up with Wicket 8 and Java 8 · Why Java 8 for Wicket 8? • Concise, clear code with Java 8 Lambdas, Optional • Support for Java EE 7 and Java 8 in servers • Wish to get

Why Java 8 for Wicket 8

Wicket 8 Noteworthy Features

Java 8 Date Time

Java 8 Optional

Java 8 Lambda's

Migration towards Wicket 8

Page 19: Whats up with Wicket 8 and Java 8 · Why Java 8 for Wicket 8? • Concise, clear code with Java 8 Lambdas, Optional • Support for Java EE 7 and Java 8 in servers • Wish to get

I've recently ran into a few cases where while implementing AjaxFallbackLink I forgot to test the passed in request target for null, causing NPEs when the app was accessed from browsers where AJAX failed for whatever reason.

— Igor Vaynberg, 2011

Page 20: Whats up with Wicket 8 and Java 8 · Why Java 8 for Wicket 8? • Concise, clear code with Java 8 Lambdas, Optional • Support for Java EE 7 and Java 8 in servers • Wish to get

AjaxFallbackLink

AjaxFallbackLink<Void>link=newAjaxFallbackLink<Void>("link"){ @Override publicvoidonClick(AjaxRequestTargettarget) { target.add(label); }};

wicket 7

wicket 8

Page 21: Whats up with Wicket 8 and Java 8 · Why Java 8 for Wicket 8? • Concise, clear code with Java 8 Lambdas, Optional • Support for Java EE 7 and Java 8 in servers • Wish to get

AjaxFallbackLink

AjaxFallbackLink<Void>link=newAjaxFallbackLink<Void>("link"){ @Override publicvoidonClick(AjaxRequestTargettarget) { target.add(label); }};

wicket 7

wicket 8NullPointerException

Page 22: Whats up with Wicket 8 and Java 8 · Why Java 8 for Wicket 8? • Concise, clear code with Java 8 Lambdas, Optional • Support for Java EE 7 and Java 8 in servers • Wish to get

AjaxFallbackLink

AjaxFallbackLink<Void>link=newAjaxFallbackLink<Void>("link"){ @Override publicvoidonClick(AjaxRequestTargettarget) { target.add(label); }};

wicket 7

wicket 8AjaxFallbackLink<Void>link=newAjaxFallbackLink<Void>("link"){ @Override publicvoidonClick(Optional<AjaxRequestTarget>target) { target.ifPresent(t->t.add(label)); }};

Page 23: Whats up with Wicket 8 and Java 8 · Why Java 8 for Wicket 8? • Concise, clear code with Java 8 Lambdas, Optional • Support for Java EE 7 and Java 8 in servers • Wish to get

RequestCycle.get().find()

AjaxRequestTargettarget=RequestCycle.get().find(AjaxRequestTarget.class);target.add(studentPanel);

wicket 7

wicket 8Optional<AjaxRequestTarget>target=RequestCycle.get().find(AjaxRequestTarget.class);if(target.isPresent())target.get().add(studentPanel);

Page 24: Whats up with Wicket 8 and Java 8 · Why Java 8 for Wicket 8? • Concise, clear code with Java 8 Lambdas, Optional • Support for Java EE 7 and Java 8 in servers • Wish to get

Why Java 8 for Wicket 8

Wicket 8 Noteworthy Features

Java 8 Date Time

Java 8 Optional

Java 8 Lambda's

Migration towards Wicket 8

Page 25: Whats up with Wicket 8 and Java 8 · Why Java 8 for Wicket 8? • Concise, clear code with Java 8 Lambdas, Optional • Support for Java EE 7 and Java 8 in servers • Wish to get

Models

Components

Behaviors

Difficulties

Critique𝛌

Page 26: Whats up with Wicket 8 and Java 8 · Why Java 8 for Wicket 8? • Concise, clear code with Java 8 Lambdas, Optional • Support for Java EE 7 and Java 8 in servers • Wish to get

add(newLabel("lastname",newPropertyModel(person,"lastname")));

add(newLabel("message","Hello,World!"));

IModel<Account>accountModel=...;add(newTextField("lastname",newPropertyModel(accountModel,"person.lastname")));

Page 27: Whats up with Wicket 8 and Java 8 · Why Java 8 for Wicket 8? • Concise, clear code with Java 8 Lambdas, Optional • Support for Java EE 7 and Java 8 in servers • Wish to get

add(newAttributeAppender("class",newAbstractReadOnlyModel<String>(){privatestaticfinallongserialVersionUID=1L;@OverridepublicStringgetObject(){returnisRequired()?"wysiwyg_required":"";}},""));

Page 28: Whats up with Wicket 8 and Java 8 · Why Java 8 for Wicket 8? • Concise, clear code with Java 8 Lambdas, Optional • Support for Java EE 7 and Java 8 in servers • Wish to get

Nested model examplepublicclassAbsenteePreferenceModelextendsLoadableDetachableModel<AbsenteePreference>{@InjectprivateEmployeeDAOempDao;

@InjectprivateLocationDAOlocDAO;

@OverrideprotectedAbsenteePreferenceload(){IridiumContextctx=IridiumContext.get();

AbsentieInvoerVoorkeurpref=empDao.getAbsenteePref(ctx.getEmployee());

if(pref==null){voorkeur=locDAO.getAbsenteePref(ctx.getDefaultLocation());}returnpref;}}

(1/2)

Page 29: Whats up with Wicket 8 and Java 8 · Why Java 8 for Wicket 8? • Concise, clear code with Java 8 Lambdas, Optional • Support for Java EE 7 and Java 8 in servers • Wish to get

Nested model exampleadd(newCheckBox("showAll",newPropertyModel<>(prefModel,"showAll")));

add(newCheckBox("studentInfo",newPropertyModel<>(prefModel,"showStudentInfo")));

add(newCheckBox("barcode",newPropertyModel<>(prefModel,"showBarCode")));

add(newDropDownChoice("reason",newPropertyModel<>(prefModel,"defaultReason"),absenteeReasonsModel));

(2/2)

Page 30: Whats up with Wicket 8 and Java 8 · Why Java 8 for Wicket 8? • Concise, clear code with Java 8 Lambdas, Optional • Support for Java EE 7 and Java 8 in servers • Wish to get

add(newLabel("lastname",newPropertyModel(person,"lastname")));

add(newLabel("message","Hello,World!"));

IModel<Account>accountModel=...;add(newTextField("lastname",newPropertyModel(accountModel,"person.lastname")));

Page 31: Whats up with Wicket 8 and Java 8 · Why Java 8 for Wicket 8? • Concise, clear code with Java 8 Lambdas, Optional • Support for Java EE 7 and Java 8 in servers • Wish to get

LambdaModel example

add(newLabel("message","Hello,World!"));

wicket 7

wicket 8add(newLabel("message","Hello,World!"));

Page 32: Whats up with Wicket 8 and Java 8 · Why Java 8 for Wicket 8? • Concise, clear code with Java 8 Lambdas, Optional • Support for Java EE 7 and Java 8 in servers • Wish to get

LambdaModel example

add(newLabel("lastname",newPropertyModel(person,"lastname")));

wicket 7

wicket 8add(newLabel("lastname",()->person.getLastName()));

add(newLabel("lastname",person::getLastName));

Page 33: Whats up with Wicket 8 and Java 8 · Why Java 8 for Wicket 8? • Concise, clear code with Java 8 Lambdas, Optional • Support for Java EE 7 and Java 8 in servers • Wish to get

LambdaModel example

add(newLabel("lastName",newPropertyModel<>(personModel,"lastName")));

wicket 7

wicket 8add(newLabel("lastName",LambdaModel.of(personModel,Person::getLastName)));

Page 34: Whats up with Wicket 8 and Java 8 · Why Java 8 for Wicket 8? • Concise, clear code with Java 8 Lambdas, Optional • Support for Java EE 7 and Java 8 in servers • Wish to get

LambdaModel example

add(newLabel("lastName",newPropertyModel<>(accountModel,"person.lastName")));

wicket 7

wicket 8add(newLabel("lastName",LambdaModel.of(accountModel,Account::getPerson).map(Person::getLastName)));

Page 35: Whats up with Wicket 8 and Java 8 · Why Java 8 for Wicket 8? • Concise, clear code with Java 8 Lambdas, Optional • Support for Java EE 7 and Java 8 in servers • Wish to get

LambdaModel example

add(newAttributeAppender("class",newAbstractReadOnlyModel<String>(){privatestaticfinallongserialVersionUID=1L;@OverridepublicStringgetObject(){returnisRequired()?"wysiwyg_required":"";}},""));

wicket 7

wicket 8add(newAttributeAppender("class",()->isRequired()?"wysiwyg_required":""),""));

Page 36: Whats up with Wicket 8 and Java 8 · Why Java 8 for Wicket 8? • Concise, clear code with Java 8 Lambdas, Optional • Support for Java EE 7 and Java 8 in servers • Wish to get

LambdaModel example

add(newCheckBox("showAll",newPropertyModel<>(prefModel,"showAll")));

wicket 7

wicket 8add(newCheckBox("showAll",LambdaModel.of(prefModel,AbsentieInvoerVoorkeur::isShowAll,AbsentieInvoerVoorkeur::setShowAll)));

Page 37: Whats up with Wicket 8 and Java 8 · Why Java 8 for Wicket 8? • Concise, clear code with Java 8 Lambdas, Optional • Support for Java EE 7 and Java 8 in servers • Wish to get

LambdaModel example

add(newDropDownChoice("reason",newPropertyModel<>(prefModel,"defaultReason"),absenteeReasonsModel));

wicket 7

wicket 8add(newDropDownChoice("reason",LambdaModel.of(prefModel,AbsentieInvoerVoorkeur::getDefaultReason,AbsentieInvoerVoorkeur::setDefaultReason)),absenteeReasonsModel));

Page 38: Whats up with Wicket 8 and Java 8 · Why Java 8 for Wicket 8? • Concise, clear code with Java 8 Lambdas, Optional • Support for Java EE 7 and Java 8 in servers • Wish to get

Models

Components

Behaviors

Difficulties

Critique𝛌

Page 39: Whats up with Wicket 8 and Java 8 · Why Java 8 for Wicket 8? • Concise, clear code with Java 8 Lambdas, Optional • Support for Java EE 7 and Java 8 in servers • Wish to get

Models accept lambda's directly

add(newLabel<>("name",PropertyModel.of(person,"name"));

wicket 7

wicket 8

Page 40: Whats up with Wicket 8 and Java 8 · Why Java 8 for Wicket 8? • Concise, clear code with Java 8 Lambdas, Optional • Support for Java EE 7 and Java 8 in servers • Wish to get

IModels accept lambda's directly

add(newLabel<>("name",PropertyModel.of(person,"name"));

wicket 7

wicket 8add(newLabel<>("name",()->person.getName()));add(newLabel<>("name",person::getName));

Page 41: Whats up with Wicket 8 and Java 8 · Why Java 8 for Wicket 8? • Concise, clear code with Java 8 Lambdas, Optional • Support for Java EE 7 and Java 8 in servers • Wish to get

Typical component

add(newLink<Cheese>("addToCart",cheeseModel){@OverridepublicvoidonClick(){Cheesecheese=getModelObject();CheesrSession.get().add(cheese);}});

wicket 7

wicket 8

Page 42: Whats up with Wicket 8 and Java 8 · Why Java 8 for Wicket 8? • Concise, clear code with Java 8 Lambdas, Optional • Support for Java EE 7 and Java 8 in servers • Wish to get

Typical component

add(newLink<Cheese>("addToCart",cheeseModel){@OverridepublicvoidonClick(){Cheesecheese=getModelObject();CheesrSession.get().add(cheese);}});

wicket 7

wicket 8add(Link.onClick("addToCart",()->{Cheesecheese=cheeseModel.getObject();CheesrSession.get().add(cheese);});

Page 43: Whats up with Wicket 8 and Java 8 · Why Java 8 for Wicket 8? • Concise, clear code with Java 8 Lambdas, Optional • Support for Java EE 7 and Java 8 in servers • Wish to get

• Form

• Link

• Button

• SubmitLink

• LambdaColumn (for dataview)

Page 44: Whats up with Wicket 8 and Java 8 · Why Java 8 for Wicket 8? • Concise, clear code with Java 8 Lambdas, Optional • Support for Java EE 7 and Java 8 in servers • Wish to get

Models

Components

Behaviors

Difficulties

Critique𝛌

Page 45: Whats up with Wicket 8 and Java 8 · Why Java 8 for Wicket 8? • Concise, clear code with Java 8 Lambdas, Optional • Support for Java EE 7 and Java 8 in servers • Wish to get

Behavior

newBehavior(){@OverridepublicvoidonComponentTag(Componentc,ComponentTagt){tag.getAttributes().put("style","color:red");}}

wicket 7

wicket 8

Page 46: Whats up with Wicket 8 and Java 8 · Why Java 8 for Wicket 8? • Concise, clear code with Java 8 Lambdas, Optional • Support for Java EE 7 and Java 8 in servers • Wish to get

Behavior

newBehavior(){@OverridepublicvoidonComponentTag(Componentc,ComponentTagt){tag.getAttributes().put("style","color:red");}}

wicket 7

wicket 8Behavior.onComponentTag(t->t.getAttributes().put("style","color:red"));

Behavior.onAttribute("style",s->"color:red");

Page 47: Whats up with Wicket 8 and Java 8 · Why Java 8 for Wicket 8? • Concise, clear code with Java 8 Lambdas, Optional • Support for Java EE 7 and Java 8 in servers • Wish to get

Models

Components

Behaviors

Difficulties

Critique𝛌

Page 48: Whats up with Wicket 8 and Java 8 · Why Java 8 for Wicket 8? • Concise, clear code with Java 8 Lambdas, Optional • Support for Java EE 7 and Java 8 in servers • Wish to get

Make everything serializable

Page 49: Whats up with Wicket 8 and Java 8 · Why Java 8 for Wicket 8? • Concise, clear code with Java 8 Lambdas, Optional • Support for Java EE 7 and Java 8 in servers • Wish to get

A first attempt for Lambda'spublicabstractclassLinkextendsAbstractLink{publicabstractvoidonClick();

publicstatic<T>Link<T>onClick(Stringid,Consumer<T>handler){returnnewLink<T>(id){@OverridepublicvoidonClick(){handler.accept(this);}};}}

Page 50: Whats up with Wicket 8 and Java 8 · Why Java 8 for Wicket 8? • Concise, clear code with Java 8 Lambdas, Optional • Support for Java EE 7 and Java 8 in servers • Wish to get

A first attempt for Lambda'sadd(Link.onClick("link",c->{}));

Caused by: java.io.NotSerializableException: com.martijndashorst.wicketbenchmarks.ClosurePage$$Lambda$18/38997010

at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1184)at java.io.ObjectOutputStream.defaultWriteFields(ObjectOutputStream.java:1548)at java.io.ObjectOutputStream.writeSerialData(ObjectOutputStream.java:1509)at java.io.ObjectOutputStream.writeOrdinaryObject(ObjectOutputStream.java:1432)

Page 51: Whats up with Wicket 8 and Java 8 · Why Java 8 for Wicket 8? • Concise, clear code with Java 8 Lambdas, Optional • Support for Java EE 7 and Java 8 in servers • Wish to get

add(Link.onClick("link",c->{}));

A first attempt for Lambda'spublicabstractclassLinkextendsAbstractLink{publicabstractvoidonClick();

publicstatic<T>Link<T>onClick(Stringid,Consumer<T>handler){}

Not Serializable

Page 52: Whats up with Wicket 8 and Java 8 · Why Java 8 for Wicket 8? • Concise, clear code with Java 8 Lambdas, Optional • Support for Java EE 7 and Java 8 in servers • Wish to get

Attempt 2: Wicket's own Lambda'sinterfaceWicketConsumerextendsSerializable{...}interfaceWicketSupplierextendsSerializable{}

interfaceWicketFunctionextendsSerializable{}

interfaceWicketPredicateextendsSerializable{}

interfaceWicketBiConsumerextendsSerializable{}

interfaceWicketBiSupplierextendsSerializable{}

...

Page 53: Whats up with Wicket 8 and Java 8 · Why Java 8 for Wicket 8? • Concise, clear code with Java 8 Lambdas, Optional • Support for Java EE 7 and Java 8 in servers • Wish to get

• Not reusable outside Wicket

• Conflicts with other Serializable Functional Interfaces

Page 54: Whats up with Wicket 8 and Java 8 · Why Java 8 for Wicket 8? • Concise, clear code with Java 8 Lambdas, Optional • Support for Java EE 7 and Java 8 in servers • Wish to get

Attempt 3

• jdk-serializable-functional Jakub Danekhttps://github.com/danekja/jdk-serializable-functional

• No dependencies

Page 55: Whats up with Wicket 8 and Java 8 · Why Java 8 for Wicket 8? • Concise, clear code with Java 8 Lambdas, Optional • Support for Java EE 7 and Java 8 in servers • Wish to get

Attempt 3: jdk-serializable-functionalinterfaceSerializableConsumerextendsSerializable{...}interfaceSerializableSupplierextendsSerializable{}

interfaceSerializableFunctionextendsSerializable{}

interfaceSerializablePredicateextendsSerializable{}

interfaceSerializableBiConsumerextendsSerializable{}

interfaceSerializableBiSupplierextendsSerializable{}

...

Page 56: Whats up with Wicket 8 and Java 8 · Why Java 8 for Wicket 8? • Concise, clear code with Java 8 Lambdas, Optional • Support for Java EE 7 and Java 8 in servers • Wish to get

add(Link.onClick("link",c->{}));

A first attempt for Lambda'spublicabstractclassLinkextendsAbstractLink{publicabstractvoidonClick();

publicstatic<T>Link<T>onClick(Stringid,SerializableConsumer<T>handler){}

Serializable

Page 57: Whats up with Wicket 8 and Java 8 · Why Java 8 for Wicket 8? • Concise, clear code with Java 8 Lambdas, Optional • Support for Java EE 7 and Java 8 in servers • Wish to get

Closures capture too much

Page 58: Whats up with Wicket 8 and Java 8 · Why Java 8 for Wicket 8? • Concise, clear code with Java 8 Lambdas, Optional • Support for Java EE 7 and Java 8 in servers • Wish to get

Capturing the worldPersonperson=peopleDAO.find(...);

add(SubmitLink.onSubmit("save",c->{peopleDao.save(person);}));

Page 59: Whats up with Wicket 8 and Java 8 · Why Java 8 for Wicket 8? • Concise, clear code with Java 8 Lambdas, Optional • Support for Java EE 7 and Java 8 in servers • Wish to get

Capturing the worldPersonperson=peopleDAO.find(...);

add(SubmitLink.onSubmit("save",c->{peopleDao.save(person);}));

publicMyPage(Objecto){add(Link.onClick("link",l->System.out.println(o)));}

Not Serializable

Page 60: Whats up with Wicket 8 and Java 8 · Why Java 8 for Wicket 8? • Concise, clear code with Java 8 Lambdas, Optional • Support for Java EE 7 and Java 8 in servers • Wish to get

Capturing the worldPersonperson=peopleDAO.find(...);

add(SubmitLink.onSubmit("save",c->{peopleDao.save(person);}));

publicMyPage(Objecto){add(Link.onClick("link",l->System.out.println(o)));

add(newLink("link2"){publicvoidonClick(){System.out.println(o);}}}

Not Serializable

Page 61: Whats up with Wicket 8 and Java 8 · Why Java 8 for Wicket 8? • Concise, clear code with Java 8 Lambdas, Optional • Support for Java EE 7 and Java 8 in servers • Wish to get

Models

Components

Behaviors

Difficulties

Critique𝛌

Page 62: Whats up with Wicket 8 and Java 8 · Why Java 8 for Wicket 8? • Concise, clear code with Java 8 Lambdas, Optional • Support for Java EE 7 and Java 8 in servers • Wish to get

DISCLAIMERThis critique is not about the work of Wicket developers working hard on Wicket 8.

Rather it is a measure of the maturity of the current state of Wicket 8. A lot of work went into it, there's still work to be done.

Page 63: Whats up with Wicket 8 and Java 8 · Why Java 8 for Wicket 8? • Concise, clear code with Java 8 Lambdas, Optional • Support for Java EE 7 and Java 8 in servers • Wish to get

Closure clarity

Page 64: Whats up with Wicket 8 and Java 8 · Why Java 8 for Wicket 8? • Concise, clear code with Java 8 Lambdas, Optional • Support for Java EE 7 and Java 8 in servers • Wish to get

What is the output?

setDefaultModel(Model.of("Pagemodel"));add(Link.onClick("id",s->{ System.out.println("Model:"+getDefaultModelObject());}).setDefaultModel(Model.of("Linkmodel")));

wicket 7

wicket 8

In a page:

Output:

Page 65: Whats up with Wicket 8 and Java 8 · Why Java 8 for Wicket 8? • Concise, clear code with Java 8 Lambdas, Optional • Support for Java EE 7 and Java 8 in servers • Wish to get

What is the output?

setDefaultModel(Model.of("Pagemodel"));add(Link.onClick("id",s->{ System.out.println("Model:"+getDefaultModelObject());}).setDefaultModel(Model.of("Linkmodel")));

wicket 7

wicket 8Model:Pagemodel

In a page:

Output:

Page 66: Whats up with Wicket 8 and Java 8 · Why Java 8 for Wicket 8? • Concise, clear code with Java 8 Lambdas, Optional • Support for Java EE 7 and Java 8 in servers • Wish to get

Combinatorial explosion of factory methods

Page 67: Whats up with Wicket 8 and Java 8 · Why Java 8 for Wicket 8? • Concise, clear code with Java 8 Lambdas, Optional • Support for Java EE 7 and Java 8 in servers • Wish to get

Typical component

add(newLink<Cheese>("addToCart",cheeseModel){privatestaticfinallongserialVersionUID=1L;

@OverridepublicvoidonClick(){Cheesecheese=getModelObject();CheesrSession.get().add(cheese);}});

wicket 7

wicket 8

Page 68: Whats up with Wicket 8 and Java 8 · Why Java 8 for Wicket 8? • Concise, clear code with Java 8 Lambdas, Optional • Support for Java EE 7 and Java 8 in servers • Wish to get

Typical component

add(newLink<Cheese>("addToCart",cheeseModel){privatestaticfinallongserialVersionUID=1L;

@OverridepublicvoidonClick(){Cheesecheese=getModelObject();CheesrSession.get().add(cheese);}});

wicket 7

wicket 8add(Link.onClick("addToCart",cheeseModel,()->{Cheesecheese=cheeseModel.getObject();CheesrSession.get().add(cheese);});

Page 69: Whats up with Wicket 8 and Java 8 · Why Java 8 for Wicket 8? • Concise, clear code with Java 8 Lambdas, Optional • Support for Java EE 7 and Java 8 in servers • Wish to get

Typical componentadd(newLink<Cheese>("addToCart",cheeseModel){privatestaticfinallongserialVersionUID=1L;

@OverridepublicvoidonClick(){Cheesecheese=getModelObject();CheesrSession.get().add(cheese);}@OverridepublicvoidonConfigure(){Cheesecheese=getModelObject();setVisible(cheese.isInStock());}});

Page 70: Whats up with Wicket 8 and Java 8 · Why Java 8 for Wicket 8? • Concise, clear code with Java 8 Lambdas, Optional • Support for Java EE 7 and Java 8 in servers • Wish to get

• onInitialize

• onConfigure

• onBeforeRender

• onRender

• onComponentTag

• onAfterRender

• onClick

• onSubmit

• onError

• isVisible

• isEnabled

• ...

Page 71: Whats up with Wicket 8 and Java 8 · Why Java 8 for Wicket 8? • Concise, clear code with Java 8 Lambdas, Optional • Support for Java EE 7 and Java 8 in servers • Wish to get

Less syntax: less readable

Page 72: Whats up with Wicket 8 and Java 8 · Why Java 8 for Wicket 8? • Concise, clear code with Java 8 Lambdas, Optional • Support for Java EE 7 and Java 8 in servers • Wish to get

Typical componentadd(newAjaxSubmitLink<Void>("register"){privatestaticfinallongserialVersionUID=1L;

@OverridepublicvoidonSubmit(AjaxRequestTargettarget){Personperson=registrationModel.getObject();registrationService.registerNewStudent(person);registrationWizard.next();target.add(registrationWizard);}

@OverridepublicvoidonError(){target.add(feedbackPanel);}});

Page 73: Whats up with Wicket 8 and Java 8 · Why Java 8 for Wicket 8? • Concise, clear code with Java 8 Lambdas, Optional • Support for Java EE 7 and Java 8 in servers • Wish to get

Typical lambdaadd(AjaxSubmitLink.onSubmit("register",(target)->{Personperson=registrationModel.getObject();registrationService.registerNewStudent(person);registrationWizard.next();target.add(registrationWizard);},(target)->{target.add(feedbackPanel);});

Page 74: Whats up with Wicket 8 and Java 8 · Why Java 8 for Wicket 8? • Concise, clear code with Java 8 Lambdas, Optional • Support for Java EE 7 and Java 8 in servers • Wish to get

Typical lambdaadd(AjaxSubmitLink.onSubmit("register",(target)->{Personperson=registrationModel.getObject();registrationService.registerNewStudent(person);registrationWizard.next();target.add(registrationWizard);},(target)->{target.add(feedbackPanel);});

add(AjaxSubmitLink.onSubmit("register",page::onRegister,page::onSubmitError});

Page 75: Whats up with Wicket 8 and Java 8 · Why Java 8 for Wicket 8? • Concise, clear code with Java 8 Lambdas, Optional • Support for Java EE 7 and Java 8 in servers • Wish to get

Where's the Component?

Page 76: Whats up with Wicket 8 and Java 8 · Why Java 8 for Wicket 8? • Concise, clear code with Java 8 Lambdas, Optional • Support for Java EE 7 and Java 8 in servers • Wish to get

Bi-Consuming Behavior

add(newBehavior(){publicvoidonComponentTag(Componentc,ComponentTagt){}}

wicket 7

wicket 8add(Behavior.onComponentTag(t->{//where'sthecomponent?});

Page 77: Whats up with Wicket 8 and Java 8 · Why Java 8 for Wicket 8? • Concise, clear code with Java 8 Lambdas, Optional • Support for Java EE 7 and Java 8 in servers • Wish to get

Model Performance

Page 78: Whats up with Wicket 8 and Java 8 · Why Java 8 for Wicket 8? • Concise, clear code with Java 8 Lambdas, Optional • Support for Java EE 7 and Java 8 in servers • Wish to get

DISCLAIMERThese benchmarks are based on the current version. Newer versions will perform differently (possibly better).

A micro benchmark does not reflect actual application performance.

Page 79: Whats up with Wicket 8 and Java 8 · Why Java 8 for Wicket 8? • Concise, clear code with Java 8 Lambdas, Optional • Support for Java EE 7 and Java 8 in servers • Wish to get

Benchmarks https://github.com/dashorst/wicket-benchmarks

Page 80: Whats up with Wicket 8 and Java 8 · Why Java 8 for Wicket 8? • Concise, clear code with Java 8 Lambdas, Optional • Support for Java EE 7 and Java 8 in servers • Wish to get

Which construct performs better?newAbstractReadOnlyModel<String>(){@OverridepublicStringgetObject(){returnaccountModel.getObject().getPerson().getName();}}

PropertyModel.of(accountModel,"person.name").getObject();

Model.of(accountModel).map(Account::getPerson).map(Person::getName).getObject();

Page 81: Whats up with Wicket 8 and Java 8 · Why Java 8 for Wicket 8? • Concise, clear code with Java 8 Lambdas, Optional • Support for Java EE 7 and Java 8 in servers • Wish to get

0

40

80

120

160

200

PropertyModel

Chained Lambda

Direct LambdaAbstractReadOnlyModel

Direct

164x

120x99x

70x

1x

Page 82: Whats up with Wicket 8 and Java 8 · Why Java 8 for Wicket 8? • Concise, clear code with Java 8 Lambdas, Optional • Support for Java EE 7 and Java 8 in servers • Wish to get

Memory efficiency

Page 83: Whats up with Wicket 8 and Java 8 · Why Java 8 for Wicket 8? • Concise, clear code with Java 8 Lambdas, Optional • Support for Java EE 7 and Java 8 in servers • Wish to get

new Account()

Account Personname: String

1n

96 bytes

am: accountModel A: Account P: Person

Page 84: Whats up with Wicket 8 and Java 8 · Why Java 8 for Wicket 8? • Concise, clear code with Java 8 Lambdas, Optional • Support for Java EE 7 and Java 8 in servers • Wish to get

new Account() Model.of(account)

Account Personname: String

1n

96 112

bytes

am: accountModel A: Account P: Person

Page 85: Whats up with Wicket 8 and Java 8 · Why Java 8 for Wicket 8? • Concise, clear code with Java 8 Lambdas, Optional • Support for Java EE 7 and Java 8 in servers • Wish to get

new Account() Model.of(account) IModel.of(Account::new)

Account Personname: String

1n

96 112 16

bytes

am: accountModel A: Account P: Person

Page 86: Whats up with Wicket 8 and Java 8 · Why Java 8 for Wicket 8? • Concise, clear code with Java 8 Lambdas, Optional • Support for Java EE 7 and Java 8 in servers • Wish to get

new Account() Model.of(account) IModel.of(Account::new) LoadableDetachableModel.of(Account::new)

Account Personname: String

1n

96 112 16 40

bytes

am: accountModel A: Account P: Person

Page 87: Whats up with Wicket 8 and Java 8 · Why Java 8 for Wicket 8? • Concise, clear code with Java 8 Lambdas, Optional • Support for Java EE 7 and Java 8 in servers • Wish to get

new Account() Model.of(account) IModel.of(Account::new) LoadableDetachableModel.of(Account::new) class LDM extends LoadableDetachableModel

Account Personname: String

1n

96 112 16 40 24

bytes

am: accountModel A: Account P: Person

Page 88: Whats up with Wicket 8 and Java 8 · Why Java 8 for Wicket 8? • Concise, clear code with Java 8 Lambdas, Optional • Support for Java EE 7 and Java 8 in servers • Wish to get

new Account() Model.of(account) IModel.of(Account::new) LoadableDetachableModel.of(Account::new) class LDM extends LoadableDetachableModel new IModel<>() { getObject() { return ...} }

Account Personname: String

1n

96 112 16 40 24 56

bytes

am: accountModel A: Account P: Person

Page 89: Whats up with Wicket 8 and Java 8 · Why Java 8 for Wicket 8? • Concise, clear code with Java 8 Lambdas, Optional • Support for Java EE 7 and Java 8 in servers • Wish to get

new Account() Model.of(account) IModel.of(Account::new) LoadableDetachableModel.of(Account::new) class LDM extends LoadableDetachableModel new IModel<>() { getObject() { return ...} } LambdaModel.of(()->am().getPerson().getName())

Account Personname: String

1n

96 112 16 40 24 56 72

bytes

am: accountModel A: Account P: Person

Page 90: Whats up with Wicket 8 and Java 8 · Why Java 8 for Wicket 8? • Concise, clear code with Java 8 Lambdas, Optional • Support for Java EE 7 and Java 8 in servers • Wish to get

new Account() Model.of(account) IModel.of(Account::new) LoadableDetachableModel.of(Account::new) class LDM extends LoadableDetachableModel new IModel<>() { getObject() { return ...} } LambdaModel.of(()->am().getPerson().getName()) model.map(A::getPerson).map(P::getName)

Account Personname: String

1n

96 112 16 40 24 56 72

120

bytes

am: accountModel A: Account P: Person

Page 91: Whats up with Wicket 8 and Java 8 · Why Java 8 for Wicket 8? • Concise, clear code with Java 8 Lambdas, Optional • Support for Java EE 7 and Java 8 in servers • Wish to get

new Account() Model.of(account) IModel.of(Account::new) LoadableDetachableModel.of(Account::new) class LDM extends LoadableDetachableModel new IModel<>() { getObject() { return ...} } LambdaModel.of(()->am().getPerson().getName()) model.map(A::getPerson).map(P::getName) LambdaModel.of(am, A::getPerson).mapP::getNa

Account Personname: String

1n

96 112 16 40 24 56 72

120 160

bytes

am: accountModel A: Account P: Person

Page 92: Whats up with Wicket 8 and Java 8 · Why Java 8 for Wicket 8? • Concise, clear code with Java 8 Lambdas, Optional • Support for Java EE 7 and Java 8 in servers • Wish to get

new Account() Model.of(account) IModel.of(Account::new) LoadableDetachableModel.of(Account::new) class LDM extends LoadableDetachableModel new IModel<>() { getObject() { return ...} } LambdaModel.of(()->am().getPerson().getName()) model.map(A::getPerson).map(P::getName) LambdaModel.of(am, A::getPerson).mapP::getNa PropertyModel.of(am, "person.name")

Account Personname: String

1n

96 112 16 40 24 56 72

120 160 128

bytes

am: accountModel A: Account P: Person

Page 93: Whats up with Wicket 8 and Java 8 · Why Java 8 for Wicket 8? • Concise, clear code with Java 8 Lambdas, Optional • Support for Java EE 7 and Java 8 in servers • Wish to get

Serialization efficiency

Page 94: Whats up with Wicket 8 and Java 8 · Why Java 8 for Wicket 8? • Concise, clear code with Java 8 Lambdas, Optional • Support for Java EE 7 and Java 8 in servers • Wish to get

new Account() Model.of(account) IModel.of(Account::new) LoadableDetachableModel.of(Account::new) class LDM extends LoadableDetachableModel new IModel<>() { getObject() { return ...} } LambdaModel.of(()->am().getPerson().getName()) model.map(A::getPerson).map(P::getName) LambdaModel.of(am, A::getPerson).mapP::getNa PropertyModel.of(am, "person.name")

Account Personname: String

1n

222 302 662 900 123

1025 1343 1691 2271 1128

bytes

am: accountModel A: Account P: Person

Page 95: Whats up with Wicket 8 and Java 8 · Why Java 8 for Wicket 8? • Concise, clear code with Java 8 Lambdas, Optional • Support for Java EE 7 and Java 8 in servers • Wish to get

new Account() Model.of(account) IModel.of(Account::new) LoadableDetachableModel.of(Account::new) class LDM extends LoadableDetachableModel new IModel<>() { getObject() { return ...} } LambdaModel.of(()->am().getPerson().getName()) model.map(A::getPerson).map(P::getName) LambdaModel.of(am, A::getPerson).mapP::getNa PropertyModel.of(am, "person.name")

Account Personname: String

1n

222 302 662 900 123

1025 1343 1691 2271 1128

bytes

am: accountModel A: Account P: Person

Page 96: Whats up with Wicket 8 and Java 8 · Why Java 8 for Wicket 8? • Concise, clear code with Java 8 Lambdas, Optional • Support for Java EE 7 and Java 8 in servers • Wish to get

Component Performance

Page 97: Whats up with Wicket 8 and Java 8 · Why Java 8 for Wicket 8? • Concise, clear code with Java 8 Lambdas, Optional • Support for Java EE 7 and Java 8 in servers • Wish to get

MarkupContainer finding a child

Page 98: Whats up with Wicket 8 and Java 8 · Why Java 8 for Wicket 8? • Concise, clear code with Java 8 Lambdas, Optional • Support for Java EE 7 and Java 8 in servers • Wish to get

Which performs better?

container.stream().filter(c->"id".equals(c.getId())).findFirst().get()

container.get("id")

for(Componentc:container)if("id".equals(c.getId())break;

Page 99: Whats up with Wicket 8 and Java 8 · Why Java 8 for Wicket 8? • Concise, clear code with Java 8 Lambdas, Optional • Support for Java EE 7 and Java 8 in servers • Wish to get

get for streamchildren

1,000

100,000

100

1 104,453,168 105,431,300 13,050,626

10 26,787,973 18,238,850 7,130,824

23,322,255 1,155,958 1,072,664

24,252,999 125,178 117,638

23,867,853 735 705

Page 100: Whats up with Wicket 8 and Java 8 · Why Java 8 for Wicket 8? • Concise, clear code with Java 8 Lambdas, Optional • Support for Java EE 7 and Java 8 in servers • Wish to get

Why Java 8 for Wicket 8

Wicket 8 Noteworthy Features

Java 8 Date Time

Java 8 Optional

Java 8 Lambda's

Migration towards Wicket 8

Page 101: Whats up with Wicket 8 and Java 8 · Why Java 8 for Wicket 8? • Concise, clear code with Java 8 Lambdas, Optional • Support for Java EE 7 and Java 8 in servers • Wish to get

Migration guide7.x → 8.0.0

Page 102: Whats up with Wicket 8 and Java 8 · Why Java 8 for Wicket 8? • Concise, clear code with Java 8 Lambdas, Optional • Support for Java EE 7 and Java 8 in servers • Wish to get
Page 103: Whats up with Wicket 8 and Java 8 · Why Java 8 for Wicket 8? • Concise, clear code with Java 8 Lambdas, Optional • Support for Java EE 7 and Java 8 in servers • Wish to get

In-house framework

• Size: 172k lines of code

• Current Wicket version: 7.5.0

• Compile errors due to 8.0.0-M2: 70

Page 104: Whats up with Wicket 8 and Java 8 · Why Java 8 for Wicket 8? • Concise, clear code with Java 8 Lambdas, Optional • Support for Java EE 7 and Java 8 in servers • Wish to get

In-house web app #1

• Size: 36k lines of code

• Current Wicket version: 7.5.0

• Compile errors due to 8.0.0-M2: 55 most: bare Link anonymous inner classes didn't inherit setDefaultModel from IGenericComponent

Page 105: Whats up with Wicket 8 and Java 8 · Why Java 8 for Wicket 8? • Concise, clear code with Java 8 Lambdas, Optional • Support for Java EE 7 and Java 8 in servers • Wish to get

Deprecations

• IProvider<T> → Supplier<T>

• AbstractReadOnlyModel<T> → IModel<T>

Page 106: Whats up with Wicket 8 and Java 8 · Why Java 8 for Wicket 8? • Concise, clear code with Java 8 Lambdas, Optional • Support for Java EE 7 and Java 8 in servers • Wish to get

In-house web app #2

• Size: 1M lines of code

• Current Wicket version: 7.5.0

• Compile errors due to 8.0.0-M2: 346 most:- AjaxFallback made parameter AjaxRequestTarget Optional- ILinkListener/IChangeListener/* → IRequestListener

Page 107: Whats up with Wicket 8 and Java 8 · Why Java 8 for Wicket 8? • Concise, clear code with Java 8 Lambdas, Optional • Support for Java EE 7 and Java 8 in servers • Wish to get

Conclusions

• Java 8 & Wicket 8 is GR8

• Almost ready for release

• But, still work to be done

Page 108: Whats up with Wicket 8 and Java 8 · Why Java 8 for Wicket 8? • Concise, clear code with Java 8 Lambdas, Optional • Support for Java EE 7 and Java 8 in servers • Wish to get

Questions?