SlideShare a Scribd company logo
Apache Wicket

10 years and beyond
Martijn Dashorst

topicus onderwijs
@dashorst
APACHE WICKET
a brief history

of Wicket
the current state

of Wicket
the future

of Wicket
co-author
10 year contributor to Wicket
started in 2004 at topicus
without any knowledge of web programming
before Wicket
at topicus
2004
using maverick velocity
hibernate jasperreports
lots of XML configuration
1 change requires N files to be
modified
(for large values of N)
<command name="admin.tabelbeheer.edittoetsonderdeel">

<controller class="nl.topicus.bao.web.ctrl.lab.toetsen.

<view name="success" path="/admin/tabelbeheer/toetsen/e

<transform path="/mlayout/mainlayout.vm">

<param name="_pagetitle" value="Beheer Tabellen

</transform>

</view>

<view name="error" path="/admin/tabelbeheer/toetsen/edi

<transform path="/mlayout/mainlayout.vm">

<param name="_pagetitle" value="Beheer Tabellen

</transform>

</view>

<view name="list" path="admin.tabelbeheer.edittoets.m" 

</command>
high learning curve
no back button support
no multi-tab support
HTTP Session dumping
ground
little to no reuse
</tr>

#if($model.bean.absentieRegels.empty)

<tr>

<td colspan="19" class="border-r">#formname('groep.absent'

</tr>

#else

#set($columnIndexes=[1,2,3,4,5,6,7,8,9,10])

#foreach($row in $model.bean.absentieRegels)

<tr>

<td class="columnvalue">$arrayTool.elementAt($row, 0)</td

#foreach($index in $columnIndexes)

#set($melding=$arrayTool.elementAt($row, $index))
complex UI neigh impossible
a framework that makes
reuse possible, minimises
configuration, server side
state management easy
and is as type safe as
possible
Action Framework Anvil Apache Click Apache MyFaces Apache
Shale Apache Sling Apache Struts Apache Struts 2 Apache
Tapestry Apache Turbine Apache Wicket AppFuse Aranea Web
Framework AribaWeb Aurora Baritus Barracuda Bento Bishop Brill
Calyxo Cameleon Canyamo Caramba Cassandra Chiba Chrysalis
Dinamica Dovetail DWR Echo Eclipse RAP Expresso fleXive Flower
framework Folium FormEngine Genie Grails GWT Hamlets Helma
Induction ItsNat Jacquard Jaffa Japple JAT JATO JBanana JBoss
Seam Jeenius JFormular JOSSO JPublish JSPWidget Jspx-bay
jStatemachine Jucas JVx JWAA JWarp jWic jZeno jZonic Macaw
Makumba Maverick Melati Mentawai Millstone Nacho Niggle
OpenEmcee OpenLaszlo OpenXava Oracle ADF OXF Pandora
Playframework Pustefix Restlet RIFE Roma Meta Framework RSF
Scope SerfJ Shocks Smile SOFIA Sombrero Spark Spring MVC
Strecks Stripes Swinglets SwingWeb Tapestry TeaServlet ThinWire
Trimpath Junction Turbine Vaadin Verge VRaptor Vroom Warfare
Wavemaker WebObjects WebOnSwing WebWork wingS Xoplon Ze
Framework ZK ztemplates
120+ java web frameworks
18 August 2004
public class EditPage extends WebPage {

private Person person;



public EditPage(Person person) {

this.person = person;



add(new Button("save") {

@Override

public void onSubmit() {

Entities.save(person);

setResponsePage(new ShowPage(person));

}

});

}

}
a framework that makes
reuse possible, minimises
configuration, server side
state management easy
and is as type safe as
possible
✓ ✓
✓
✓
Action Framework Anvil Apache Click Apache MyFaces Apache
Shale Apache Sling Apache Struts Apache Struts 2 Apache
Tapestry Apache Turbine Apache Wicket AppFuse Aranea Web
Framework AribaWeb Aurora Baritus Barracuda Bento Bishop Brill
Calyxo Cameleon Canyamo Caramba Cassandra Chiba Chrysalis
Dinamica Dovetail DWR Echo Eclipse RAP Expresso fleXive Flower
framework Folium FormEngine Genie Grails GWT Hamlets Helma
Induction ItsNat Jacquard Jaffa Japple JAT JATO JBanana JBoss
Seam Jeenius JFormular JOSSO JPublish JSPWidget Jspx-bay
jStatemachine Jucas JVx JWAA JWarp jWic jZeno jZonic Macaw
Makumba Maverick Melati Mentawai Millstone Nacho Niggle
OpenEmcee OpenLaszlo OpenXava Oracle ADF OXF Pandora
Playframework Pustefix Restlet RIFE Roma Meta Framework RSF
Scope SerfJ Shocks Smile SOFIA Sombrero Spark Spring MVC
Strecks Stripes Swinglets SwingWeb Tapestry TeaServlet ThinWire
Trimpath Junction Turbine Vaadin Verge VRaptor Vroom Warfare
Wavemaker WebObjects WebOnSwing WebWork wingS Xoplon Ze
Framework ZK ztemplates
Action Framework Anvil Apache Click Apache MyFaces Apache
Shale Apache Sling Apache Struts Apache Struts 2 Apache
Tapestry Apache Turbine Apache Wicket AppFuse Aranea Web
Framework AribaWeb Aurora Baritus Barracuda Bento Bishop Brill
Calyxo Cameleon Canyamo Caramba Cassandra Chiba Chrysalis
Dinamica Dovetail DWR Echo Eclipse RAP Expresso fleXive Flower
framework Folium FormEngine Genie Grails GWT Hamlets Helma
Induction ItsNat Jacquard Jaffa Japple JAT JATO JBanana JBoss
Seam Jeenius JFormular JOSSO JPublish JSPWidget Jspx-bay
jStatemachine Jucas JVx JWAA JWarp jWic jZeno jZonic Macaw
Makumba Maverick Melati Mentawai Millstone Nacho Niggle
OpenEmcee OpenLaszlo OpenXava Oracle ADF OXF Pandora
Playframework Pustefix Restlet RIFE Roma Meta Framework RSF
Scope SerfJ Shocks Smile SOFIA Sombrero Spark Spring MVC
Strecks Stripes Swinglets SwingWeb Tapestry TeaServlet ThinWire
Trimpath Junction Turbine Vaadin Verge VRaptor Vroom Warfare
Wavemaker WebObjects WebOnSwing WebWork wingS Xoplon Ze
Framework ZK ztemplates
15 java web frameworks alive
i.e. made any release in the last year
including Wicket!
What is Wicket?
Apache Wicket
From Wikipedia, the free encyclopedia
Apache Wicket, commonly referred to as
Wicket, is a lightweight component-based web
application framework for the Java programming
language conceptually similar to JavaServer
Faces and Tapestry. It was originally written by
Jonathan Locke in April 2004. Version 1.0 was
released in June 2005. It graduated into an
Apache top-level project in June 2007.[2]
A brief history of
Wicket
2004
2004
The Server Side
20052004
codehaus.org
The Server Side
20052004
codehaus.org
The Server Side
codehaus.org
2004
The Server Side JavaOne
1.0
1.1
2006
1.2
2005
AJAX
2007
2007
1.3
2008
2007
1.3
2008 2009
1.4
2010 2011
1.5
2007
1.3
2008 2009
1.4
2010 2011
1.5
2012
6.0
2013 2014
6.12
6.2
6.4
6.6
6.8
6.10
6.1 6.5 6.9
6.11
6.13
7.0.0-M2
6.16
6.14
6.15
7.0.0-M1
6.3 6.7
6.17
7.0.0-M3
7.0.0-M4
6.18
That's
of Apache Wicket!
10 years
The state of
Wicket
1. core
2. extensions
3. spring
4. datetime
5. auth-roles
Mailinglist traffic
Commit activity
Meanwhile
at devoxx...
0%
25%
50%
75%
100%
REST+JavaScript
SpringMVC
JavaScriptlibrary
JSF+JavaEE
GWT
Wicket
Play
Vaadin
Strutsv1orv2
Grails
ApacheSling
WebSockets+JavaScript
Spray+AkkaHTTP
ZKframework
Other
User Manual
195
25 Wicket Internals
25.1 Page storing
During request handling, Wicket manages page instances through interface
. This interface creates a new page instance ororg.apache.wicket.request.handler.IPageProvider
loads a previously serialized page instance if we provide the corrisponding page id. delegatesIPageProvider
page creation and retrieval to interface . When pageorg.apache.wicket.request.mapper.IPageSource
class is provided delegates page creation to interface ,IPageSource org.apache.wicket.IPageFactory
while when page id is provided it uses interface to load theorg.apache.wicket.page.IPageManager
previously serialized page.
The following workflow diagram summarizes the mechanism seen so far:
IPageManager
's task is to manage which pages have been used in a requestorg.apache.wicket.page.IPageManager
and store their last state in the backing stores, namely . The default implementationIPageStore
collects all stateful pages which have been used in theorg.apache.wicket.page.PageStoreManager
request cycle (more than one page can be used in a single request if for example orsetResponsePage()
is used). At the end of the request all collected page instances are being storedRestartResponseException
in the first level cache - http session. They are stored in http session attribute named
and passed to the underlying"wicket:persistentPageManagerData-APPLICATION_NAME" IPageStore
. When the next http request comes will ask for page with specific id andIPageProvider PageStoreManager
will look first in the http session and if no match is found then it will delegate to the IPageStore. At the end of the
second request the http session based cache is being overwritten completely with the newly used page
instances.
To setup another implementation useIPageManager
. Theorg.apache.wicket.Application.setPageManagerProvider(IPageManagerProvider)
custom implementation may or may not use .IPageManager IPageStore/IDataStore
IPageStore
's role is to mediate the storing and loading of pages done byorg.apache.wicket.pageStore.IPageStore
the underlying . The default implementationIDataStore
pre-processes the pages before passing them toorg.apache.wicket.pageStore.DefaultPageStore
183
As you can see above, the Exception gets raised during the initialization of the instance evenWicketTester
before the actual test method gets executed. Even though we have applied rather cool and simple annotation
based test configuration already described and passed in perfectly well prepared ApplicationContext instance to
the WicketTester instance in the constructor, somewhere down the rabbit hole someone complained that no
WebApplicationContext instance could have been found which seems to be required in order to initialize the
WicketTester properly.
The problem that we run against here is due to the fact that SpringComponentInjector during its own initialization
is trying to get hold of an according Spring's ApplicationContext instance that would normally be there in a
runtime environment but does not find any since we are running in a test environment currently.
SpringComponentInjector delegates to Spring's own WebApplicationContextUtils class to retrieve the instance of
ApplicationContext out of the ServletContext which is perfectly fine for a runtime environment but is unfortunately
failing in a test environment:
public WebApplicationContext getRequiredWebApplicationContext(ServletContext sc)static
IllegalStateException {throws
WebApplicationContext wac = getWebApplicationContext(sc);
(wac == ) {if null
IllegalStateException(throw new "No WebApplicationContext found: no
);ContextLoaderListener registered?"
}
wac;return
}
If you still remember we defined a ContextLoaderListener in our web.xml file as part of the configuration of our
runtime environment that makes sure an according WebApplicationContext instance gets initialized and
registered against the ServletContext properly. Luckily, this problem can easily be solved if we slightly change
the way we initialize SpringComponentInjector in our main MyWebApplication class. Apart from the constructor
that we have used so far, there is another constructor in the SpringComponentInjector class that expects the
caller to provide it with an according ApplicationContext instance rather than trying to resolve one on its own:
public SpringComponentInjector(WebApplication webapp, ApplicationContext ctx,
wrapInProxies)boolean
{
(webapp == )if null
{
IllegalArgumentException( );throw new "Argument [[webapp]] cannot be "null
}
(ctx == )if null
{
IllegalArgumentException( );throw new "Argument [[ctx]] cannot be "null
}
// store context in application's metadata …
webapp.setMetaData(CONTEXT_KEY, ApplicationContextHolder(ctx));new
// … and create and register the annotation aware injector
InjectorHolder.setInjector( AnnotSpringInjector( ContextLocator(),new new
In a Nutshell, Wicket...
… has had 18,255 commits made by 62 contributors
representing 318,037 lines of code
… is mostly written in Java with

a well-commented source code
… has a well established, mature codebase maintained
by a large development team with stable Y-O-Y
commits
… took an estimated 84 years of effort (COCOMO model)

starting with its first commit in September, 2004

ending with its most recent commit 1 days ago
– openhub.net report for Wicket
The future of
Wicket
?
Wicket 1.4
security releases only
Wicket 1.5
security releases only
Wicket 6
java 6
semantic
versioning
semi-monthly releases
mainly bug fixes
some new minor features
Wicket 7
Java 7
Servlet 3
Minor API breaks
Component queuing
public class HomePage extends WebPage {
public HomePage() {
add(new Label("title", "Hello!"));
}
}
public class HomePage extends WebPage {
public HomePage() {
add(new Label("title", "Hello!"));
}
} <html>
<body>
<h1 wicket:id="title"></h1>
</body>
</html>
public class HomePage extends WebPage {
public HomePage() {
add(new Label("title", "Hello!"));
}
} <html>
<body>
<h1 wicket:id="title"></h1>
</body>
</html>
Add a <div> around content...
<html>
<body>
<div wicket:id="container">
<h1 wicket:id="title"></h1>
</div>
</body>
</html>
<html>
<body>
<div wicket:id="container">
<h1 wicket:id="title"></h1>
</div>
</body>
</html>
public class HomePage extends WebPage {public HomePage() {
add(new WebMarkupContainer("container"));add(new Label("title", "Hello!"));}
}
<html>
<body>
<div wicket:id="container">
<h1 wicket:id="title"></h1>
</div>
</body>
</html>
public class HomePage extends WebPage {public HomePage() {
add(new WebMarkupContainer("container"));add(new Label("title", "Hello!"));}
}
code always follows markup
in Wicket
<html>
<body>
<div wicket:id="container">
<h1 wicket:id="title"></h1>
</div>
</body>
</html>
public class HomePage extends WebPage {
public HomePage() {
WebMarkupContainer container =
new WebMarkupContainer("container");
add(container);
add(new Label("title", "Hello!"));
}
}
<html>
<body>
<div wicket:id="container">
<h1 wicket:id="title"></h1>
</div>
</body>
</html>
public class HomePage extends WebPage {
public HomePage() {
WebMarkupContainer container =
new WebMarkupContainer("container");
add(container);
add(new Label("title", "Hello!"));
}
}
<html>
<body>
<div wicket:id="container">
<h1 wicket:id="title"></h1>
</div>
</body>
</html>
public class HomePage extends WebPage {
public HomePage() {
WebMarkupContainer container =
new WebMarkupContainer("container");
add(container);
container.add(new Label("title", "Hello!"));
}
}
<html>
<body>
<div wicket:id="container">
<h1 wicket:id="title"></h1>
</div>
</body>
</html>
code always follows markup
in Wicket
or does it?
Enter Component Queuing
(coming to you in wicket 7)
What if we delay adding
components?
Queue components until their location
in the markup hierarchy is know
markupContainer.add(new Label(...));
markupContainer.queue(new Label(...));
public class HomePage extends WebPage {

public HomePage() {

WebMarkupContainer container = 

new WebMarkupContainer("container");

add(container);

container.add(new Label("title", "Hello!"));

}

}
public class HomePage extends WebPage {

public HomePage() {

queue(new WebMarkupContainer("container"));

queue(new Label("title", "Hello!"));

}

}
<html>
<body>
<header><h1 wicket:id="title"></h1></header>
<div wicket:id="container">
...
</div>
</body>
</html>
<html>
<body>
<div wicket:id="container">
<h1 wicket:id="title"></h1>
</div>
</body>
</html>
Limitations of

Component Queuing
queue(new Label("label", "Some text"));

queue(new Label("label", "Other text"));
queue(new Label("label", "Some text"));

queue(new Label("label", "Other text"));
queue(new Label("first"));

queue(new Label("last"));



WebMarkupContainer secure=new
WebMarkupContainer("secure") {

public void onConfigure() {

super.onConfigure();

setVisible(isViewingOwnProfile());

}

};



queue(secure);

secure.queue(new Label("creditCardNumber"));

secure.queue(new Label("creditCardExpiry"));
Restrictions of Queuing: Ancestors
<h3>

Welcome,

<span wicket:id="first"></span>

<span wicket:id="last"></span>!

</h3>

<fieldset wicket:id="secure">

<legend>Secure</legend>

<dt>Card expiry: <i wicket:id="creditCardExpiry">

<dt>Card number: <i wicket:id="creditCardNumber">

</fieldset>
<h3>

Welcome,

<span wicket:id="first"></span>

<span wicket:id="last"></span>!

</h3>

<fieldset wicket:id="secure">

<legend>Secure</legend>

<dt>Card expiry: <i wicket:id="creditCardExpiry">

<dt>Card number: <i wicket:id="creditCardNumber">

</fieldset>
<h3>

Welcome,

<span wicket:id="first"></span>

<span wicket:id="last"></span>!

</h3>

<fieldset wicket:id="secure">

<legend>Secure</legend>

<dt>Card expiry: <i wicket:id="creditCardExpiry">

</fieldset>
<dt>Card number: <i wicket:id="creditCardNumber">
<h3>

Welcome,

<span wicket:id="first"></span>

<span wicket:id="last"></span>!

</h3>

<fieldset wicket:id="secure">

<legend>Secure</legend>

<dt>Card expiry: <i wicket:id="creditCardExpiry">

</fieldset>
<dt>Card number: <i wicket:id="creditCardNumber">
<fieldset wicket:id="secure">

<h3>

Welcome,

<span wicket:id="first"></span>

<span wicket:id="last"></span>!

</h3>

<legend>Secure</legend>

<dt>Card expiry: <i wicket:id="creditCardExpiry">

<dt>Card number: <i wicket:id="creditCardNumber">

</fieldset>
<fieldset wicket:id="secure">

<h3>

Welcome,

<span wicket:id="first"></span>

<span wicket:id="last"></span>!

</h3>

<legend>Secure</legend>

<dt>Card expiry: <i wicket:id="creditCardExpiry">

<dt>Card number: <i wicket:id="creditCardNumber">

</fieldset>
Component Queuing
• Wicket 7 feature
• Prefer queue() when markup hierarchy can be altered
• Uniqueness of Wicket IDs still requirement at same
level of queuing
• Can move down into child markup hierarchy
• Can't move up the markup hierarchy
Wicket 8
Java 8
PROJECT LAMBDA
“functional” programming in
Java
public interface ILinkListener {

void onLickClicked();

}
ILinkListener l = new ILinkListener(){

@Override

public void onLinkClicked() {

System.out.println("Klik");

}

}
public interface ILinkListener {

void onLickClicked();

}
ILinkListener l = () -> {

System.out.println("Klik");

}
ILinkListener l = () -> {

System.out.println("Klik");

}
ILinkListener l = new ILinkListener(){

@Override

public void onLinkClicked() {

System.out.println("Klik");

}

}
or
add(new Link<Void>("save") {

@Override

public void onClick() {

dao.save(object);

getSession().info("Saved.");

setResponsePage(new OtherPage())

}

});
add(new Link<Void>("save") {

@Override

public void onClick() {

dao.save(object);

getSession().info("Saved.");

setResponsePage(new OtherPage())

}

});
add(new Link<>("save").onClick(()-> {

dao.save(object);

getSession().info("Saved.");

setResponsePage(new OtherPage())

});
no more type
information
private void onSave() {

dao.save(object);

getSession().info("Saved.");

setResponsePage(new OtherPage())

}

private void onSave() {

dao.save(object);

getSession().info("Saved.");

setResponsePage(new OtherPage())

}

add(new Link<Void>("save")

.onClick(this::onSave));

A link with onclick, visibility and
body
add(new Link<Void>("like"));



add(new Link<Void>("like") {

});
add(new Link<Void>("like") {

@Override

public void onClick() {

person.likedBy(me);

}

});
add(new Link<Void>("like") {

@Override

public void onClick() {

person.likedBy(me);

}



@Override

public boolean isVisible() {

return person.isNotLiked();

}

});
add(new Link<Void>("like") {

@Override

public void onClick() {

person.likedBy(me);

}



@Override

public boolean isVisible() {

return person.isNotLiked();

}

}.setBody());
add(new Link<Void>("like") {

@Override

public void onClick() {

person.likedBy(me);

}



@Override

public boolean isVisible() {

return person.isNotLiked();

}

}.setBody(new AbstractReadOnlyModel<String>() { 

}));
add(new Link<Void>("like") {

@Override

public void onClick() {

person.likedBy(me);

}



@Override

public boolean isVisible() {

return person.isNotLiked();

}

}.setBody(new AbstractReadOnlyModel<String>() { 

@Override

public String getObject() {

}
}));
add(new Link<Void>("like") {

@Override

public void onClick() {

person.likedBy(me);

}



@Override

public boolean isVisible() {

return person.isNotLiked();

}

}.setBody(new AbstractReadOnlyModel<String>() { 

@Override

public String getObject() {

StringBuilder sb = new StringBuilder("Like ");

sb.append(person.getFirstName());

return sb.toString();

}
}));
A link with onclick, visibility and
body
add(new Link<>("like"));

add(new Link<>("like")

);

add(new Link<>("like")

.visible(() -> person.isNotLiked())

);

add(new Link<>("like")

.visible(() -> person.isNotLiked())

.onClick(() -> person.likedBy(me))

);

add(new Link<>("like")

.visible(() -> person.isNotLiked())

.onClick(() -> person.likedBy(me))

.body(() -> {

})

);

add(new Link<>("like")

.visible(() -> person.isNotLiked())

.onClick(() -> person.likedBy(me))

.body(() -> {

StringBuilder sb = new StringBuilder("Like ");

sb.append(person.getFirstName());

return sb.toString();

})

);

add(new Link<>("like")

.visible(() -> person.isNotLiked())

.onClick(() -> person.likedBy(me))

.body(() -> {

StringBuilder sb = new StringBuilder("Like ");

sb.append(person.getFirstName());

return sb.toString();

})

);

add(new Link<Void>("like") {

@Override

public void onClick() {

person.likedBy(me);

}



@Override

public boolean isVisible() {

return person.isNotLiked();

}

}.setBody(new AbstractReadOnlyModel<String>() { 

@Override

public String getObject() {

StringBuilder sb = new StringBuilder("Like ");

sb.append(person.getFirstName());

return sb.toString();

}
}));
Anon inner classes: 17 lines
Java 8 lambdas: 9 lines
nashorn
JavaScript validation
ScriptEngineManager m
= new ScriptEngineManager();
ScriptEngine nashorn
= m.getEngineByName("nashorn");
nashorn.put("age", validatable.getValue());
String js = "age >= 18";
try {
Object result = nashorn.eval(js);
if(!((Boolean)result) {
ValidationError e = new ValidationError();
validatable.error(e);
}
} catch(Exception e) {
}
ScriptEngineManager m
= new ScriptEngineManager();
ScriptEngine nashorn
= m.getEngineByName("nashorn");
nashorn.put("age", validatable.getValue());
String js = "age >= 18";
try {
Object result = nashorn.eval(js);
if(!((Boolean)result) {
ValidationError e = new ValidationError();
validatable.error(e);
}
} catch(Exception e) {
}
ScriptEngineManager m
= new ScriptEngineManager();
ScriptEngine nashorn
= m.getEngineByName("nashorn");
nashorn.put("age", validatable.getValue());
String js = "age >= 18";
try {
Object result = nashorn.eval(js);
if(!((Boolean)result) {
ValidationError e = new ValidationError();
validatable.error(e);
}
} catch(Exception e) {
}
ScriptEngineManager m
= new ScriptEngineManager();
ScriptEngine nashorn
= m.getEngineByName("nashorn");
nashorn.put("age", validatable.getValue());
String js = "age >= 18";
try {
Object result = nashorn.eval(js);
if(!((Boolean)result) {
ValidationError e = new ValidationError();
validatable.error(e);
}
} catch(Exception e) {
}
ScriptEngineManager m
= new ScriptEngineManager();
ScriptEngine nashorn
= m.getEngineByName("nashorn");
nashorn.put("age", validatable.getValue());
String js = "age >= 18";
Object result = nashorn.eval(js);
try {
if(!((Boolean)result) {
ValidationError e = new ValidationError();
validatable.error(e);
}
} catch(Exception e) {
}
ScriptEngineManager m
= new ScriptEngineManager();
ScriptEngine nashorn
= m.getEngineByName("nashorn");
nashorn.put("age", validatable.getValue());
String js = "age >= 18";
Object result = nashorn.eval(js);
if(!((Boolean)result) {
ValidationError e = new ValidationError();
validatable.error(e);
}
try {
} catch(Exception e) {
}
ScriptEngineManager m
= new ScriptEngineManager();
ScriptEngine nashorn
= m.getEngineByName("nashorn");
nashorn.put("age", validatable.getValue());
String js = "age >= 18";
try {
Object result = nashorn.eval(js);
if(!((Boolean)result) {
ValidationError e = new ValidationError();
validatable.error(e);
}
} catch (Exception e) {
}
java.time
Schedule
6.14
6.15
7.0-M1
7.0-M2
7.0-M4
6.18
feb mar nov
2014
7.0-RC
6.19
jan
7.0?
7.1?
8.0-M1?
7.5?
feb mar may
2015
8.0-M2?
7.6?
jun
Is there a future for 

server-side frameworks?
0%
25%
50%
75%
100%
REST+JavaScript
SpringMVC
JavaScriptlibrary
JSF+JavaEE
GWT
Wicket
Play
Vaadin
Strutsv1orv2
Grails
ApacheSling
WebSockets+JavaScript
Spray+AkkaHTTP
ZKframework
Other
JavaScript Frameworks War
JQuery AngularJS Ember.js React
Backbone.js Meteor KnockoutJS Dojo
Agility.js CanJS Polymer Mithril
Maria Flight Knockback.jsAmpersand
What is the Future for web
development?
What is the Future for web
development?
Web Components
What is the Future for web
development?
Web Components
PolymerAngularJS
(2.0)
What is the Future of Wicket?
No Revolution but Evolution
a brief history

of Wicket
the current state

of Wicket
the future

of Wicket
Summary
thank you
Questions?
contact
@dashorst
topicus stand

More Related Content

What's hot

REST APIs with Spring
REST APIs with SpringREST APIs with Spring
REST APIs with Spring
Joshua Long
 
JAX-RS JavaOne Hyderabad, India 2011
JAX-RS JavaOne Hyderabad, India 2011JAX-RS JavaOne Hyderabad, India 2011
JAX-RS JavaOne Hyderabad, India 2011
Shreedhar Ganapathy
 
Modules in Java? Finally! (OpenJDK 9 Jigsaw, JSR376)
Modules in Java? Finally! (OpenJDK 9 Jigsaw, JSR376)Modules in Java? Finally! (OpenJDK 9 Jigsaw, JSR376)
Modules in Java? Finally! (OpenJDK 9 Jigsaw, JSR376)
Mihail Stoynov
 
Spark IT 2011 - Developing RESTful Web services with JAX-RS
Spark IT 2011 - Developing RESTful Web services with JAX-RSSpark IT 2011 - Developing RESTful Web services with JAX-RS
Spark IT 2011 - Developing RESTful Web services with JAX-RS
Arun Gupta
 
Using React with Grails 3
Using React with Grails 3Using React with Grails 3
Using React with Grails 3
Zachary Klein
 
Better Front-end Development in Atlassian Plugins
Better Front-end Development in Atlassian PluginsBetter Front-end Development in Atlassian Plugins
Better Front-end Development in Atlassian Plugins
Wojciech Seliga
 
Node.js vs Play Framework
Node.js vs Play FrameworkNode.js vs Play Framework
Node.js vs Play Framework
Yevgeniy Brikman
 
Microservices - java ee vs spring boot and spring cloud
Microservices - java ee vs spring boot and spring cloudMicroservices - java ee vs spring boot and spring cloud
Microservices - java ee vs spring boot and spring cloud
Ben Wilcock
 
Apache DeltaSpike the CDI toolbox
Apache DeltaSpike the CDI toolboxApache DeltaSpike the CDI toolbox
Apache DeltaSpike the CDI toolbox
Antoine Sabot-Durand
 
DataFX - JavaOne 2013
DataFX - JavaOne 2013DataFX - JavaOne 2013
DataFX - JavaOne 2013
Hendrik Ebbers
 
In The Trenches With Tomster, Upgrading Ember.js & Ember Data
In The Trenches With Tomster, Upgrading Ember.js & Ember DataIn The Trenches With Tomster, Upgrading Ember.js & Ember Data
In The Trenches With Tomster, Upgrading Ember.js & Ember Data
Stacy London
 
Apache Lucene for Java EE Developers
Apache Lucene for Java EE DevelopersApache Lucene for Java EE Developers
Apache Lucene for Java EE Developers
Virtual JBoss User Group
 
AtlasCamp 2012 - Testing JIRA plugins smarter with TestKit
AtlasCamp 2012 - Testing JIRA plugins smarter with TestKitAtlasCamp 2012 - Testing JIRA plugins smarter with TestKit
AtlasCamp 2012 - Testing JIRA plugins smarter with TestKit
Wojciech Seliga
 
Composable and streamable Play apps
Composable and streamable Play appsComposable and streamable Play apps
Composable and streamable Play apps
Yevgeniy Brikman
 
The Making of the Oracle R2DBC Driver and How to Take Your Code from Synchron...
The Making of the Oracle R2DBC Driver and How to Take Your Code from Synchron...The Making of the Oracle R2DBC Driver and How to Take Your Code from Synchron...
The Making of the Oracle R2DBC Driver and How to Take Your Code from Synchron...
VMware Tanzu
 
Migrating to Java 9 Modules
Migrating to Java 9 ModulesMigrating to Java 9 Modules
Migrating to Java 9 Modules
Sander Mak (@Sander_Mak)
 
Angular beans
Angular beansAngular beans
Angular beans
Bessem Hmidi
 
Coding Your Way to Java 12
Coding Your Way to Java 12Coding Your Way to Java 12
Coding Your Way to Java 12
Sander Mak (@Sander_Mak)
 
From CakePHP to Laravel
From CakePHP to LaravelFrom CakePHP to Laravel
From CakePHP to Laravel
Jason McCreary
 
Spring Boot in Action
Spring Boot in Action Spring Boot in Action
Spring Boot in Action
Alex Movila
 

What's hot (20)

REST APIs with Spring
REST APIs with SpringREST APIs with Spring
REST APIs with Spring
 
JAX-RS JavaOne Hyderabad, India 2011
JAX-RS JavaOne Hyderabad, India 2011JAX-RS JavaOne Hyderabad, India 2011
JAX-RS JavaOne Hyderabad, India 2011
 
Modules in Java? Finally! (OpenJDK 9 Jigsaw, JSR376)
Modules in Java? Finally! (OpenJDK 9 Jigsaw, JSR376)Modules in Java? Finally! (OpenJDK 9 Jigsaw, JSR376)
Modules in Java? Finally! (OpenJDK 9 Jigsaw, JSR376)
 
Spark IT 2011 - Developing RESTful Web services with JAX-RS
Spark IT 2011 - Developing RESTful Web services with JAX-RSSpark IT 2011 - Developing RESTful Web services with JAX-RS
Spark IT 2011 - Developing RESTful Web services with JAX-RS
 
Using React with Grails 3
Using React with Grails 3Using React with Grails 3
Using React with Grails 3
 
Better Front-end Development in Atlassian Plugins
Better Front-end Development in Atlassian PluginsBetter Front-end Development in Atlassian Plugins
Better Front-end Development in Atlassian Plugins
 
Node.js vs Play Framework
Node.js vs Play FrameworkNode.js vs Play Framework
Node.js vs Play Framework
 
Microservices - java ee vs spring boot and spring cloud
Microservices - java ee vs spring boot and spring cloudMicroservices - java ee vs spring boot and spring cloud
Microservices - java ee vs spring boot and spring cloud
 
Apache DeltaSpike the CDI toolbox
Apache DeltaSpike the CDI toolboxApache DeltaSpike the CDI toolbox
Apache DeltaSpike the CDI toolbox
 
DataFX - JavaOne 2013
DataFX - JavaOne 2013DataFX - JavaOne 2013
DataFX - JavaOne 2013
 
In The Trenches With Tomster, Upgrading Ember.js & Ember Data
In The Trenches With Tomster, Upgrading Ember.js & Ember DataIn The Trenches With Tomster, Upgrading Ember.js & Ember Data
In The Trenches With Tomster, Upgrading Ember.js & Ember Data
 
Apache Lucene for Java EE Developers
Apache Lucene for Java EE DevelopersApache Lucene for Java EE Developers
Apache Lucene for Java EE Developers
 
AtlasCamp 2012 - Testing JIRA plugins smarter with TestKit
AtlasCamp 2012 - Testing JIRA plugins smarter with TestKitAtlasCamp 2012 - Testing JIRA plugins smarter with TestKit
AtlasCamp 2012 - Testing JIRA plugins smarter with TestKit
 
Composable and streamable Play apps
Composable and streamable Play appsComposable and streamable Play apps
Composable and streamable Play apps
 
The Making of the Oracle R2DBC Driver and How to Take Your Code from Synchron...
The Making of the Oracle R2DBC Driver and How to Take Your Code from Synchron...The Making of the Oracle R2DBC Driver and How to Take Your Code from Synchron...
The Making of the Oracle R2DBC Driver and How to Take Your Code from Synchron...
 
Migrating to Java 9 Modules
Migrating to Java 9 ModulesMigrating to Java 9 Modules
Migrating to Java 9 Modules
 
Angular beans
Angular beansAngular beans
Angular beans
 
Coding Your Way to Java 12
Coding Your Way to Java 12Coding Your Way to Java 12
Coding Your Way to Java 12
 
From CakePHP to Laravel
From CakePHP to LaravelFrom CakePHP to Laravel
From CakePHP to Laravel
 
Spring Boot in Action
Spring Boot in Action Spring Boot in Action
Spring Boot in Action
 

Viewers also liked

Wicket In Action - oredev2008
Wicket In Action - oredev2008Wicket In Action - oredev2008
Wicket In Action - oredev2008
Martijn Dashorst
 
Développement d'un site web de E-Commerce avec PHP (Première Partie)
Développement d'un site web de E-Commerce avec PHP (Première Partie)Développement d'un site web de E-Commerce avec PHP (Première Partie)
Développement d'un site web de E-Commerce avec PHP (Première Partie)
ENSET, Université Hassan II Casablanca
 
Cours design pattern m youssfi partie 6 proxy
Cours design pattern m youssfi partie 6 proxyCours design pattern m youssfi partie 6 proxy
Cours design pattern m youssfi partie 6 proxy
ENSET, Université Hassan II Casablanca
 
Support POO Java première partie
Support POO Java première partieSupport POO Java première partie
Support POO Java première partie
ENSET, Université Hassan II Casablanca
 
Développement d'un site web jee de e commerce basé sur spring (m.youssfi)
Développement d'un site web jee de e commerce basé sur spring (m.youssfi)Développement d'un site web jee de e commerce basé sur spring (m.youssfi)
Développement d'un site web jee de e commerce basé sur spring (m.youssfi)
ENSET, Université Hassan II Casablanca
 
Support de cours Spring M.youssfi
Support de cours Spring  M.youssfiSupport de cours Spring  M.youssfi
Support de cours Spring M.youssfi
ENSET, Université Hassan II Casablanca
 
Support de cours technologie et application m.youssfi
Support de cours technologie et application m.youssfiSupport de cours technologie et application m.youssfi
Support de cours technologie et application m.youssfi
ENSET, Université Hassan II Casablanca
 
Mohamed youssfi support architectures logicielles distribuées basées sue les ...
Mohamed youssfi support architectures logicielles distribuées basées sue les ...Mohamed youssfi support architectures logicielles distribuées basées sue les ...
Mohamed youssfi support architectures logicielles distribuées basées sue les ...
ENSET, Université Hassan II Casablanca
 
Support programmation orientée objet c# .net version f8
Support programmation orientée objet c#  .net version f8Support programmation orientée objet c#  .net version f8
Support programmation orientée objet c# .net version f8
ENSET, Université Hassan II Casablanca
 
Support Web Services SOAP et RESTful Mr YOUSSFI
Support Web Services SOAP et RESTful Mr YOUSSFISupport Web Services SOAP et RESTful Mr YOUSSFI
Support Web Services SOAP et RESTful Mr YOUSSFI
ENSET, Université Hassan II Casablanca
 

Viewers also liked (10)

Wicket In Action - oredev2008
Wicket In Action - oredev2008Wicket In Action - oredev2008
Wicket In Action - oredev2008
 
Développement d'un site web de E-Commerce avec PHP (Première Partie)
Développement d'un site web de E-Commerce avec PHP (Première Partie)Développement d'un site web de E-Commerce avec PHP (Première Partie)
Développement d'un site web de E-Commerce avec PHP (Première Partie)
 
Cours design pattern m youssfi partie 6 proxy
Cours design pattern m youssfi partie 6 proxyCours design pattern m youssfi partie 6 proxy
Cours design pattern m youssfi partie 6 proxy
 
Support POO Java première partie
Support POO Java première partieSupport POO Java première partie
Support POO Java première partie
 
Développement d'un site web jee de e commerce basé sur spring (m.youssfi)
Développement d'un site web jee de e commerce basé sur spring (m.youssfi)Développement d'un site web jee de e commerce basé sur spring (m.youssfi)
Développement d'un site web jee de e commerce basé sur spring (m.youssfi)
 
Support de cours Spring M.youssfi
Support de cours Spring  M.youssfiSupport de cours Spring  M.youssfi
Support de cours Spring M.youssfi
 
Support de cours technologie et application m.youssfi
Support de cours technologie et application m.youssfiSupport de cours technologie et application m.youssfi
Support de cours technologie et application m.youssfi
 
Mohamed youssfi support architectures logicielles distribuées basées sue les ...
Mohamed youssfi support architectures logicielles distribuées basées sue les ...Mohamed youssfi support architectures logicielles distribuées basées sue les ...
Mohamed youssfi support architectures logicielles distribuées basées sue les ...
 
Support programmation orientée objet c# .net version f8
Support programmation orientée objet c#  .net version f8Support programmation orientée objet c#  .net version f8
Support programmation orientée objet c# .net version f8
 
Support Web Services SOAP et RESTful Mr YOUSSFI
Support Web Services SOAP et RESTful Mr YOUSSFISupport Web Services SOAP et RESTful Mr YOUSSFI
Support Web Services SOAP et RESTful Mr YOUSSFI
 

Similar to Wicket 10 years and beyond

Developing Java Web Applications
Developing Java Web ApplicationsDeveloping Java Web Applications
Developing Java Web Applications
hchen1
 
Introduction to the Servlet / JSP course
Introduction to the Servlet / JSP course Introduction to the Servlet / JSP course
Introduction to the Servlet / JSP course
JavaEE Trainers
 
자바 웹 개발 시작하기 (1주차 : 웹 어플리케이션 체험 실습)
자바 웹 개발 시작하기 (1주차 : 웹 어플리케이션 체험 실습)자바 웹 개발 시작하기 (1주차 : 웹 어플리케이션 체험 실습)
자바 웹 개발 시작하기 (1주차 : 웹 어플리케이션 체험 실습)
DK Lee
 
Web container and Apache Tomcat
Web container and Apache TomcatWeb container and Apache Tomcat
Web container and Apache Tomcat
Auwal Amshi
 
Knowledge Sharing : Java Servlet
Knowledge Sharing : Java ServletKnowledge Sharing : Java Servlet
Knowledge Sharing : Java Servlet
Fahmi Jafar
 
Html5 and beyond the next generation of mobile web applications - Touch Tou...
Html5 and beyond   the next generation of mobile web applications - Touch Tou...Html5 and beyond   the next generation of mobile web applications - Touch Tou...
Html5 and beyond the next generation of mobile web applications - Touch Tou...
RIA RUI Society
 
Beginning In J2EE
Beginning In J2EEBeginning In J2EE
Beginning In J2EE
Suthat Rongraung
 
Servlet and jsp development with eclipse wtp
Servlet and jsp development with eclipse wtpServlet and jsp development with eclipse wtp
Servlet and jsp development with eclipse wtp
odilodif
 
Introduction To J Boss Seam
Introduction To J Boss SeamIntroduction To J Boss Seam
Introduction To J Boss Seam
ashishkulkarni
 
Ajax Frameworks in the J(2)EE Environment
Ajax Frameworks in the J(2)EE EnvironmentAjax Frameworks in the J(2)EE Environment
Ajax Frameworks in the J(2)EE Environment
starchaser
 
Writing highly scalable WebSocket using the Atmosphere Framework and Scala
Writing highly scalable WebSocket using the Atmosphere Framework and ScalaWriting highly scalable WebSocket using the Atmosphere Framework and Scala
Writing highly scalable WebSocket using the Atmosphere Framework and Scala
jfarcand
 
AJppt.pptx
AJppt.pptxAJppt.pptx
AJppt.pptx
SachinSingh217687
 
No Va Taig April 7 2010
No Va Taig April 7 2010No Va Taig April 7 2010
No Va Taig April 7 2010
rudy regner
 
JSR 168 Portal - Overview
JSR 168 Portal - OverviewJSR 168 Portal - Overview
JSR 168 Portal - Overview
Vinay Kumar
 
Java Servlets
Java ServletsJava Servlets
Java Servlets
Nitin Pai
 
Introduction to JQuery, ASP.NET MVC and Silverlight
Introduction to JQuery, ASP.NET MVC and SilverlightIntroduction to JQuery, ASP.NET MVC and Silverlight
Introduction to JQuery, ASP.NET MVC and Silverlight
Peter Gfader
 
JavaEE6 my way
JavaEE6 my wayJavaEE6 my way
JavaEE6 my way
Nicola Pedot
 
Full Stack Reactive with React and Spring WebFlux - Dublin JUG 2019
Full Stack Reactive with React and Spring WebFlux - Dublin JUG 2019Full Stack Reactive with React and Spring WebFlux - Dublin JUG 2019
Full Stack Reactive with React and Spring WebFlux - Dublin JUG 2019
Matt Raible
 
GWT Web Socket and data serialization
GWT Web Socket and data serializationGWT Web Socket and data serialization
GWT Web Socket and data serialization
GWTcon
 
Web Applications and Deployment
Web Applications and DeploymentWeb Applications and Deployment
Web Applications and Deployment
BG Java EE Course
 

Similar to Wicket 10 years and beyond (20)

Developing Java Web Applications
Developing Java Web ApplicationsDeveloping Java Web Applications
Developing Java Web Applications
 
Introduction to the Servlet / JSP course
Introduction to the Servlet / JSP course Introduction to the Servlet / JSP course
Introduction to the Servlet / JSP course
 
자바 웹 개발 시작하기 (1주차 : 웹 어플리케이션 체험 실습)
자바 웹 개발 시작하기 (1주차 : 웹 어플리케이션 체험 실습)자바 웹 개발 시작하기 (1주차 : 웹 어플리케이션 체험 실습)
자바 웹 개발 시작하기 (1주차 : 웹 어플리케이션 체험 실습)
 
Web container and Apache Tomcat
Web container and Apache TomcatWeb container and Apache Tomcat
Web container and Apache Tomcat
 
Knowledge Sharing : Java Servlet
Knowledge Sharing : Java ServletKnowledge Sharing : Java Servlet
Knowledge Sharing : Java Servlet
 
Html5 and beyond the next generation of mobile web applications - Touch Tou...
Html5 and beyond   the next generation of mobile web applications - Touch Tou...Html5 and beyond   the next generation of mobile web applications - Touch Tou...
Html5 and beyond the next generation of mobile web applications - Touch Tou...
 
Beginning In J2EE
Beginning In J2EEBeginning In J2EE
Beginning In J2EE
 
Servlet and jsp development with eclipse wtp
Servlet and jsp development with eclipse wtpServlet and jsp development with eclipse wtp
Servlet and jsp development with eclipse wtp
 
Introduction To J Boss Seam
Introduction To J Boss SeamIntroduction To J Boss Seam
Introduction To J Boss Seam
 
Ajax Frameworks in the J(2)EE Environment
Ajax Frameworks in the J(2)EE EnvironmentAjax Frameworks in the J(2)EE Environment
Ajax Frameworks in the J(2)EE Environment
 
Writing highly scalable WebSocket using the Atmosphere Framework and Scala
Writing highly scalable WebSocket using the Atmosphere Framework and ScalaWriting highly scalable WebSocket using the Atmosphere Framework and Scala
Writing highly scalable WebSocket using the Atmosphere Framework and Scala
 
AJppt.pptx
AJppt.pptxAJppt.pptx
AJppt.pptx
 
No Va Taig April 7 2010
No Va Taig April 7 2010No Va Taig April 7 2010
No Va Taig April 7 2010
 
JSR 168 Portal - Overview
JSR 168 Portal - OverviewJSR 168 Portal - Overview
JSR 168 Portal - Overview
 
Java Servlets
Java ServletsJava Servlets
Java Servlets
 
Introduction to JQuery, ASP.NET MVC and Silverlight
Introduction to JQuery, ASP.NET MVC and SilverlightIntroduction to JQuery, ASP.NET MVC and Silverlight
Introduction to JQuery, ASP.NET MVC and Silverlight
 
JavaEE6 my way
JavaEE6 my wayJavaEE6 my way
JavaEE6 my way
 
Full Stack Reactive with React and Spring WebFlux - Dublin JUG 2019
Full Stack Reactive with React and Spring WebFlux - Dublin JUG 2019Full Stack Reactive with React and Spring WebFlux - Dublin JUG 2019
Full Stack Reactive with React and Spring WebFlux - Dublin JUG 2019
 
GWT Web Socket and data serialization
GWT Web Socket and data serializationGWT Web Socket and data serialization
GWT Web Socket and data serialization
 
Web Applications and Deployment
Web Applications and DeploymentWeb Applications and Deployment
Web Applications and Deployment
 

More from Martijn Dashorst

HTMX: Web 1.0 with the benefits of Web 2.0 without the grift of Web 3.0
HTMX: Web 1.0 with the benefits of Web 2.0 without the grift of Web 3.0HTMX: Web 1.0 with the benefits of Web 2.0 without the grift of Web 3.0
HTMX: Web 1.0 with the benefits of Web 2.0 without the grift of Web 3.0
Martijn Dashorst
 
From Floppy Disks to Cloud Deployments
From Floppy Disks to Cloud DeploymentsFrom Floppy Disks to Cloud Deployments
From Floppy Disks to Cloud Deployments
Martijn Dashorst
 
SOLID principles
SOLID principlesSOLID principles
SOLID principles
Martijn Dashorst
 
Converting 85% of Dutch Primary Schools from Oracle to PostgreSQL
Converting 85% of Dutch Primary Schools from Oracle to PostgreSQLConverting 85% of Dutch Primary Schools from Oracle to PostgreSQL
Converting 85% of Dutch Primary Schools from Oracle to PostgreSQL
Martijn Dashorst
 
Solutions for when documentation fails
Solutions for when documentation fails Solutions for when documentation fails
Solutions for when documentation fails
Martijn Dashorst
 
Code review drinking game
Code review drinking gameCode review drinking game
Code review drinking game
Martijn Dashorst
 
Java Serialization Deep Dive
Java Serialization Deep DiveJava Serialization Deep Dive
Java Serialization Deep Dive
Martijn Dashorst
 
Code review drinking game
Code review drinking gameCode review drinking game
Code review drinking game
Martijn Dashorst
 
Scrum: van praktijk naar onderwijs
Scrum: van praktijk naar onderwijsScrum: van praktijk naar onderwijs
Scrum: van praktijk naar onderwijs
Martijn Dashorst
 
Who Automates the Automators? (Quis Automatiet Ipsos Automates?)
Who Automates the Automators? (Quis Automatiet Ipsos Automates?)Who Automates the Automators? (Quis Automatiet Ipsos Automates?)
Who Automates the Automators? (Quis Automatiet Ipsos Automates?)
Martijn Dashorst
 
De schone coder
De schone coderDe schone coder
De schone coder
Martijn Dashorst
 
Apache Wicket and Java EE sitting in a tree
Apache Wicket and Java EE sitting in a treeApache Wicket and Java EE sitting in a tree
Apache Wicket and Java EE sitting in a tree
Martijn Dashorst
 
Wicket 2010
Wicket 2010Wicket 2010
Wicket 2010
Martijn Dashorst
 
Vakmanschap is meesterschap
Vakmanschap is meesterschapVakmanschap is meesterschap
Vakmanschap is meesterschap
Martijn Dashorst
 
Guide To Successful Graduation at Apache
Guide To Successful Graduation at ApacheGuide To Successful Graduation at Apache
Guide To Successful Graduation at Apache
Martijn Dashorst
 
Wicket In Action
Wicket In ActionWicket In Action
Wicket In Action
Martijn Dashorst
 
Apache Wicket: Web Applications With Just Java
Apache Wicket: Web Applications With Just JavaApache Wicket: Web Applications With Just Java
Apache Wicket: Web Applications With Just Java
Martijn Dashorst
 
Wicket Live on Stage
Wicket Live on StageWicket Live on Stage
Wicket Live on Stage
Martijn Dashorst
 

More from Martijn Dashorst (18)

HTMX: Web 1.0 with the benefits of Web 2.0 without the grift of Web 3.0
HTMX: Web 1.0 with the benefits of Web 2.0 without the grift of Web 3.0HTMX: Web 1.0 with the benefits of Web 2.0 without the grift of Web 3.0
HTMX: Web 1.0 with the benefits of Web 2.0 without the grift of Web 3.0
 
From Floppy Disks to Cloud Deployments
From Floppy Disks to Cloud DeploymentsFrom Floppy Disks to Cloud Deployments
From Floppy Disks to Cloud Deployments
 
SOLID principles
SOLID principlesSOLID principles
SOLID principles
 
Converting 85% of Dutch Primary Schools from Oracle to PostgreSQL
Converting 85% of Dutch Primary Schools from Oracle to PostgreSQLConverting 85% of Dutch Primary Schools from Oracle to PostgreSQL
Converting 85% of Dutch Primary Schools from Oracle to PostgreSQL
 
Solutions for when documentation fails
Solutions for when documentation fails Solutions for when documentation fails
Solutions for when documentation fails
 
Code review drinking game
Code review drinking gameCode review drinking game
Code review drinking game
 
Java Serialization Deep Dive
Java Serialization Deep DiveJava Serialization Deep Dive
Java Serialization Deep Dive
 
Code review drinking game
Code review drinking gameCode review drinking game
Code review drinking game
 
Scrum: van praktijk naar onderwijs
Scrum: van praktijk naar onderwijsScrum: van praktijk naar onderwijs
Scrum: van praktijk naar onderwijs
 
Who Automates the Automators? (Quis Automatiet Ipsos Automates?)
Who Automates the Automators? (Quis Automatiet Ipsos Automates?)Who Automates the Automators? (Quis Automatiet Ipsos Automates?)
Who Automates the Automators? (Quis Automatiet Ipsos Automates?)
 
De schone coder
De schone coderDe schone coder
De schone coder
 
Apache Wicket and Java EE sitting in a tree
Apache Wicket and Java EE sitting in a treeApache Wicket and Java EE sitting in a tree
Apache Wicket and Java EE sitting in a tree
 
Wicket 2010
Wicket 2010Wicket 2010
Wicket 2010
 
Vakmanschap is meesterschap
Vakmanschap is meesterschapVakmanschap is meesterschap
Vakmanschap is meesterschap
 
Guide To Successful Graduation at Apache
Guide To Successful Graduation at ApacheGuide To Successful Graduation at Apache
Guide To Successful Graduation at Apache
 
Wicket In Action
Wicket In ActionWicket In Action
Wicket In Action
 
Apache Wicket: Web Applications With Just Java
Apache Wicket: Web Applications With Just JavaApache Wicket: Web Applications With Just Java
Apache Wicket: Web Applications With Just Java
 
Wicket Live on Stage
Wicket Live on StageWicket Live on Stage
Wicket Live on Stage
 

Recently uploaded

Automated software refactoring with OpenRewrite and Generative AI.pptx.pdf
Automated software refactoring with OpenRewrite and Generative AI.pptx.pdfAutomated software refactoring with OpenRewrite and Generative AI.pptx.pdf
Automated software refactoring with OpenRewrite and Generative AI.pptx.pdf
timtebeek1
 
Why Mobile App Regression Testing is Critical for Sustained Success_ A Detail...
Why Mobile App Regression Testing is Critical for Sustained Success_ A Detail...Why Mobile App Regression Testing is Critical for Sustained Success_ A Detail...
Why Mobile App Regression Testing is Critical for Sustained Success_ A Detail...
kalichargn70th171
 
Empowering Growth with Best Software Development Company in Noida - Deuglo
Empowering Growth with Best Software  Development Company in Noida - DeugloEmpowering Growth with Best Software  Development Company in Noida - Deuglo
Empowering Growth with Best Software Development Company in Noida - Deuglo
Deuglo Infosystem Pvt Ltd
 
Utilocate provides Smarter, Better, Faster, Safer Locate Ticket Management
Utilocate provides Smarter, Better, Faster, Safer Locate Ticket ManagementUtilocate provides Smarter, Better, Faster, Safer Locate Ticket Management
Utilocate provides Smarter, Better, Faster, Safer Locate Ticket Management
Utilocate
 
Orion Context Broker introduction 20240604
Orion Context Broker introduction 20240604Orion Context Broker introduction 20240604
Orion Context Broker introduction 20240604
Fermin Galan
 
GOING AOT WITH GRAALVM FOR SPRING BOOT (SPRING IO)
GOING AOT WITH GRAALVM FOR  SPRING BOOT (SPRING IO)GOING AOT WITH GRAALVM FOR  SPRING BOOT (SPRING IO)
GOING AOT WITH GRAALVM FOR SPRING BOOT (SPRING IO)
Alina Yurenko
 
Enterprise Resource Planning System in Telangana
Enterprise Resource Planning System in TelanganaEnterprise Resource Planning System in Telangana
Enterprise Resource Planning System in Telangana
NYGGS Automation Suite
 
E-commerce Development Services- Hornet Dynamics
E-commerce Development Services- Hornet DynamicsE-commerce Development Services- Hornet Dynamics
E-commerce Development Services- Hornet Dynamics
Hornet Dynamics
 
Top Features to Include in Your Winzo Clone App for Business Growth (4).pptx
Top Features to Include in Your Winzo Clone App for Business Growth (4).pptxTop Features to Include in Your Winzo Clone App for Business Growth (4).pptx
Top Features to Include in Your Winzo Clone App for Business Growth (4).pptx
rickgrimesss22
 
Oracle Database 19c New Features for DBAs and Developers.pptx
Oracle Database 19c New Features for DBAs and Developers.pptxOracle Database 19c New Features for DBAs and Developers.pptx
Oracle Database 19c New Features for DBAs and Developers.pptx
Remote DBA Services
 
Energy consumption of Database Management - Florina Jonuzi
Energy consumption of Database Management - Florina JonuziEnergy consumption of Database Management - Florina Jonuzi
Energy consumption of Database Management - Florina Jonuzi
Green Software Development
 
APIs for Browser Automation (MoT Meetup 2024)
APIs for Browser Automation (MoT Meetup 2024)APIs for Browser Automation (MoT Meetup 2024)
APIs for Browser Automation (MoT Meetup 2024)
Boni García
 
Fundamentals of Programming and Language Processors
Fundamentals of Programming and Language ProcessorsFundamentals of Programming and Language Processors
Fundamentals of Programming and Language Processors
Rakesh Kumar R
 
Artificia Intellicence and XPath Extension Functions
Artificia Intellicence and XPath Extension FunctionsArtificia Intellicence and XPath Extension Functions
Artificia Intellicence and XPath Extension Functions
Octavian Nadolu
 
SWEBOK and Education at FUSE Okinawa 2024
SWEBOK and Education at FUSE Okinawa 2024SWEBOK and Education at FUSE Okinawa 2024
SWEBOK and Education at FUSE Okinawa 2024
Hironori Washizaki
 
OpenMetadata Community Meeting - 5th June 2024
OpenMetadata Community Meeting - 5th June 2024OpenMetadata Community Meeting - 5th June 2024
OpenMetadata Community Meeting - 5th June 2024
OpenMetadata
 
Mobile App Development Company In Noida | Drona Infotech
Mobile App Development Company In Noida | Drona InfotechMobile App Development Company In Noida | Drona Infotech
Mobile App Development Company In Noida | Drona Infotech
Drona Infotech
 
Graspan: A Big Data System for Big Code Analysis
Graspan: A Big Data System for Big Code AnalysisGraspan: A Big Data System for Big Code Analysis
Graspan: A Big Data System for Big Code Analysis
Aftab Hussain
 
socradar-q1-2024-aviation-industry-report.pdf
socradar-q1-2024-aviation-industry-report.pdfsocradar-q1-2024-aviation-industry-report.pdf
socradar-q1-2024-aviation-industry-report.pdf
SOCRadar
 
AI Fusion Buddy Review: Brand New, Groundbreaking Gemini-Powered AI App
AI Fusion Buddy Review: Brand New, Groundbreaking Gemini-Powered AI AppAI Fusion Buddy Review: Brand New, Groundbreaking Gemini-Powered AI App
AI Fusion Buddy Review: Brand New, Groundbreaking Gemini-Powered AI App
Google
 

Recently uploaded (20)

Automated software refactoring with OpenRewrite and Generative AI.pptx.pdf
Automated software refactoring with OpenRewrite and Generative AI.pptx.pdfAutomated software refactoring with OpenRewrite and Generative AI.pptx.pdf
Automated software refactoring with OpenRewrite and Generative AI.pptx.pdf
 
Why Mobile App Regression Testing is Critical for Sustained Success_ A Detail...
Why Mobile App Regression Testing is Critical for Sustained Success_ A Detail...Why Mobile App Regression Testing is Critical for Sustained Success_ A Detail...
Why Mobile App Regression Testing is Critical for Sustained Success_ A Detail...
 
Empowering Growth with Best Software Development Company in Noida - Deuglo
Empowering Growth with Best Software  Development Company in Noida - DeugloEmpowering Growth with Best Software  Development Company in Noida - Deuglo
Empowering Growth with Best Software Development Company in Noida - Deuglo
 
Utilocate provides Smarter, Better, Faster, Safer Locate Ticket Management
Utilocate provides Smarter, Better, Faster, Safer Locate Ticket ManagementUtilocate provides Smarter, Better, Faster, Safer Locate Ticket Management
Utilocate provides Smarter, Better, Faster, Safer Locate Ticket Management
 
Orion Context Broker introduction 20240604
Orion Context Broker introduction 20240604Orion Context Broker introduction 20240604
Orion Context Broker introduction 20240604
 
GOING AOT WITH GRAALVM FOR SPRING BOOT (SPRING IO)
GOING AOT WITH GRAALVM FOR  SPRING BOOT (SPRING IO)GOING AOT WITH GRAALVM FOR  SPRING BOOT (SPRING IO)
GOING AOT WITH GRAALVM FOR SPRING BOOT (SPRING IO)
 
Enterprise Resource Planning System in Telangana
Enterprise Resource Planning System in TelanganaEnterprise Resource Planning System in Telangana
Enterprise Resource Planning System in Telangana
 
E-commerce Development Services- Hornet Dynamics
E-commerce Development Services- Hornet DynamicsE-commerce Development Services- Hornet Dynamics
E-commerce Development Services- Hornet Dynamics
 
Top Features to Include in Your Winzo Clone App for Business Growth (4).pptx
Top Features to Include in Your Winzo Clone App for Business Growth (4).pptxTop Features to Include in Your Winzo Clone App for Business Growth (4).pptx
Top Features to Include in Your Winzo Clone App for Business Growth (4).pptx
 
Oracle Database 19c New Features for DBAs and Developers.pptx
Oracle Database 19c New Features for DBAs and Developers.pptxOracle Database 19c New Features for DBAs and Developers.pptx
Oracle Database 19c New Features for DBAs and Developers.pptx
 
Energy consumption of Database Management - Florina Jonuzi
Energy consumption of Database Management - Florina JonuziEnergy consumption of Database Management - Florina Jonuzi
Energy consumption of Database Management - Florina Jonuzi
 
APIs for Browser Automation (MoT Meetup 2024)
APIs for Browser Automation (MoT Meetup 2024)APIs for Browser Automation (MoT Meetup 2024)
APIs for Browser Automation (MoT Meetup 2024)
 
Fundamentals of Programming and Language Processors
Fundamentals of Programming and Language ProcessorsFundamentals of Programming and Language Processors
Fundamentals of Programming and Language Processors
 
Artificia Intellicence and XPath Extension Functions
Artificia Intellicence and XPath Extension FunctionsArtificia Intellicence and XPath Extension Functions
Artificia Intellicence and XPath Extension Functions
 
SWEBOK and Education at FUSE Okinawa 2024
SWEBOK and Education at FUSE Okinawa 2024SWEBOK and Education at FUSE Okinawa 2024
SWEBOK and Education at FUSE Okinawa 2024
 
OpenMetadata Community Meeting - 5th June 2024
OpenMetadata Community Meeting - 5th June 2024OpenMetadata Community Meeting - 5th June 2024
OpenMetadata Community Meeting - 5th June 2024
 
Mobile App Development Company In Noida | Drona Infotech
Mobile App Development Company In Noida | Drona InfotechMobile App Development Company In Noida | Drona Infotech
Mobile App Development Company In Noida | Drona Infotech
 
Graspan: A Big Data System for Big Code Analysis
Graspan: A Big Data System for Big Code AnalysisGraspan: A Big Data System for Big Code Analysis
Graspan: A Big Data System for Big Code Analysis
 
socradar-q1-2024-aviation-industry-report.pdf
socradar-q1-2024-aviation-industry-report.pdfsocradar-q1-2024-aviation-industry-report.pdf
socradar-q1-2024-aviation-industry-report.pdf
 
AI Fusion Buddy Review: Brand New, Groundbreaking Gemini-Powered AI App
AI Fusion Buddy Review: Brand New, Groundbreaking Gemini-Powered AI AppAI Fusion Buddy Review: Brand New, Groundbreaking Gemini-Powered AI App
AI Fusion Buddy Review: Brand New, Groundbreaking Gemini-Powered AI App
 

Wicket 10 years and beyond

  • 1. Apache Wicket
 10 years and beyond Martijn Dashorst
 topicus onderwijs @dashorst APACHE WICKET
  • 2. a brief history
 of Wicket the current state
 of Wicket the future
 of Wicket
  • 5. started in 2004 at topicus without any knowledge of web programming
  • 9. lots of XML configuration
  • 10. 1 change requires N files to be modified (for large values of N) <command name="admin.tabelbeheer.edittoetsonderdeel">
 <controller class="nl.topicus.bao.web.ctrl.lab.toetsen.
 <view name="success" path="/admin/tabelbeheer/toetsen/e
 <transform path="/mlayout/mainlayout.vm">
 <param name="_pagetitle" value="Beheer Tabellen
 </transform>
 </view>
 <view name="error" path="/admin/tabelbeheer/toetsen/edi
 <transform path="/mlayout/mainlayout.vm">
 <param name="_pagetitle" value="Beheer Tabellen
 </transform>
 </view>
 <view name="list" path="admin.tabelbeheer.edittoets.m" 
 </command>
  • 12. no back button support no multi-tab support
  • 14. little to no reuse </tr>
 #if($model.bean.absentieRegels.empty)
 <tr>
 <td colspan="19" class="border-r">#formname('groep.absent'
 </tr>
 #else
 #set($columnIndexes=[1,2,3,4,5,6,7,8,9,10])
 #foreach($row in $model.bean.absentieRegels)
 <tr>
 <td class="columnvalue">$arrayTool.elementAt($row, 0)</td
 #foreach($index in $columnIndexes)
 #set($melding=$arrayTool.elementAt($row, $index))
  • 15. complex UI neigh impossible
  • 16. a framework that makes reuse possible, minimises configuration, server side state management easy and is as type safe as possible
  • 17. Action Framework Anvil Apache Click Apache MyFaces Apache Shale Apache Sling Apache Struts Apache Struts 2 Apache Tapestry Apache Turbine Apache Wicket AppFuse Aranea Web Framework AribaWeb Aurora Baritus Barracuda Bento Bishop Brill Calyxo Cameleon Canyamo Caramba Cassandra Chiba Chrysalis Dinamica Dovetail DWR Echo Eclipse RAP Expresso fleXive Flower framework Folium FormEngine Genie Grails GWT Hamlets Helma Induction ItsNat Jacquard Jaffa Japple JAT JATO JBanana JBoss Seam Jeenius JFormular JOSSO JPublish JSPWidget Jspx-bay jStatemachine Jucas JVx JWAA JWarp jWic jZeno jZonic Macaw Makumba Maverick Melati Mentawai Millstone Nacho Niggle OpenEmcee OpenLaszlo OpenXava Oracle ADF OXF Pandora Playframework Pustefix Restlet RIFE Roma Meta Framework RSF Scope SerfJ Shocks Smile SOFIA Sombrero Spark Spring MVC Strecks Stripes Swinglets SwingWeb Tapestry TeaServlet ThinWire Trimpath Junction Turbine Vaadin Verge VRaptor Vroom Warfare Wavemaker WebObjects WebOnSwing WebWork wingS Xoplon Ze Framework ZK ztemplates
  • 18. 120+ java web frameworks
  • 20. public class EditPage extends WebPage {
 private Person person;
 
 public EditPage(Person person) {
 this.person = person;
 
 add(new Button("save") {
 @Override
 public void onSubmit() {
 Entities.save(person);
 setResponsePage(new ShowPage(person));
 }
 });
 }
 }
  • 21. a framework that makes reuse possible, minimises configuration, server side state management easy and is as type safe as possible ✓ ✓ ✓ ✓
  • 22. Action Framework Anvil Apache Click Apache MyFaces Apache Shale Apache Sling Apache Struts Apache Struts 2 Apache Tapestry Apache Turbine Apache Wicket AppFuse Aranea Web Framework AribaWeb Aurora Baritus Barracuda Bento Bishop Brill Calyxo Cameleon Canyamo Caramba Cassandra Chiba Chrysalis Dinamica Dovetail DWR Echo Eclipse RAP Expresso fleXive Flower framework Folium FormEngine Genie Grails GWT Hamlets Helma Induction ItsNat Jacquard Jaffa Japple JAT JATO JBanana JBoss Seam Jeenius JFormular JOSSO JPublish JSPWidget Jspx-bay jStatemachine Jucas JVx JWAA JWarp jWic jZeno jZonic Macaw Makumba Maverick Melati Mentawai Millstone Nacho Niggle OpenEmcee OpenLaszlo OpenXava Oracle ADF OXF Pandora Playframework Pustefix Restlet RIFE Roma Meta Framework RSF Scope SerfJ Shocks Smile SOFIA Sombrero Spark Spring MVC Strecks Stripes Swinglets SwingWeb Tapestry TeaServlet ThinWire Trimpath Junction Turbine Vaadin Verge VRaptor Vroom Warfare Wavemaker WebObjects WebOnSwing WebWork wingS Xoplon Ze Framework ZK ztemplates
  • 23. Action Framework Anvil Apache Click Apache MyFaces Apache Shale Apache Sling Apache Struts Apache Struts 2 Apache Tapestry Apache Turbine Apache Wicket AppFuse Aranea Web Framework AribaWeb Aurora Baritus Barracuda Bento Bishop Brill Calyxo Cameleon Canyamo Caramba Cassandra Chiba Chrysalis Dinamica Dovetail DWR Echo Eclipse RAP Expresso fleXive Flower framework Folium FormEngine Genie Grails GWT Hamlets Helma Induction ItsNat Jacquard Jaffa Japple JAT JATO JBanana JBoss Seam Jeenius JFormular JOSSO JPublish JSPWidget Jspx-bay jStatemachine Jucas JVx JWAA JWarp jWic jZeno jZonic Macaw Makumba Maverick Melati Mentawai Millstone Nacho Niggle OpenEmcee OpenLaszlo OpenXava Oracle ADF OXF Pandora Playframework Pustefix Restlet RIFE Roma Meta Framework RSF Scope SerfJ Shocks Smile SOFIA Sombrero Spark Spring MVC Strecks Stripes Swinglets SwingWeb Tapestry TeaServlet ThinWire Trimpath Junction Turbine Vaadin Verge VRaptor Vroom Warfare Wavemaker WebObjects WebOnSwing WebWork wingS Xoplon Ze Framework ZK ztemplates
  • 24. 15 java web frameworks alive i.e. made any release in the last year
  • 26. What is Wicket? Apache Wicket From Wikipedia, the free encyclopedia Apache Wicket, commonly referred to as Wicket, is a lightweight component-based web application framework for the Java programming language conceptually similar to JavaServer Faces and Tapestry. It was originally written by Jonathan Locke in April 2004. Version 1.0 was released in June 2005. It graduated into an Apache top-level project in June 2007.[2]
  • 27. A brief history of Wicket
  • 28. 2004
  • 32. codehaus.org 2004 The Server Side JavaOne 1.0 1.1 2006 1.2 2005 AJAX
  • 33. 2007
  • 37. 2012 6.0 2013 2014 6.12 6.2 6.4 6.6 6.8 6.10 6.1 6.5 6.9 6.11 6.13 7.0.0-M2 6.16 6.14 6.15 7.0.0-M1 6.3 6.7 6.17 7.0.0-M3 7.0.0-M4 6.18
  • 40. 1. core 2. extensions 3. spring 4. datetime 5. auth-roles
  • 45. User Manual 195 25 Wicket Internals 25.1 Page storing During request handling, Wicket manages page instances through interface . This interface creates a new page instance ororg.apache.wicket.request.handler.IPageProvider loads a previously serialized page instance if we provide the corrisponding page id. delegatesIPageProvider page creation and retrieval to interface . When pageorg.apache.wicket.request.mapper.IPageSource class is provided delegates page creation to interface ,IPageSource org.apache.wicket.IPageFactory while when page id is provided it uses interface to load theorg.apache.wicket.page.IPageManager previously serialized page. The following workflow diagram summarizes the mechanism seen so far: IPageManager 's task is to manage which pages have been used in a requestorg.apache.wicket.page.IPageManager and store their last state in the backing stores, namely . The default implementationIPageStore collects all stateful pages which have been used in theorg.apache.wicket.page.PageStoreManager request cycle (more than one page can be used in a single request if for example orsetResponsePage() is used). At the end of the request all collected page instances are being storedRestartResponseException in the first level cache - http session. They are stored in http session attribute named and passed to the underlying"wicket:persistentPageManagerData-APPLICATION_NAME" IPageStore . When the next http request comes will ask for page with specific id andIPageProvider PageStoreManager will look first in the http session and if no match is found then it will delegate to the IPageStore. At the end of the second request the http session based cache is being overwritten completely with the newly used page instances. To setup another implementation useIPageManager . Theorg.apache.wicket.Application.setPageManagerProvider(IPageManagerProvider) custom implementation may or may not use .IPageManager IPageStore/IDataStore IPageStore 's role is to mediate the storing and loading of pages done byorg.apache.wicket.pageStore.IPageStore the underlying . The default implementationIDataStore pre-processes the pages before passing them toorg.apache.wicket.pageStore.DefaultPageStore 183 As you can see above, the Exception gets raised during the initialization of the instance evenWicketTester before the actual test method gets executed. Even though we have applied rather cool and simple annotation based test configuration already described and passed in perfectly well prepared ApplicationContext instance to the WicketTester instance in the constructor, somewhere down the rabbit hole someone complained that no WebApplicationContext instance could have been found which seems to be required in order to initialize the WicketTester properly. The problem that we run against here is due to the fact that SpringComponentInjector during its own initialization is trying to get hold of an according Spring's ApplicationContext instance that would normally be there in a runtime environment but does not find any since we are running in a test environment currently. SpringComponentInjector delegates to Spring's own WebApplicationContextUtils class to retrieve the instance of ApplicationContext out of the ServletContext which is perfectly fine for a runtime environment but is unfortunately failing in a test environment: public WebApplicationContext getRequiredWebApplicationContext(ServletContext sc)static IllegalStateException {throws WebApplicationContext wac = getWebApplicationContext(sc); (wac == ) {if null IllegalStateException(throw new "No WebApplicationContext found: no );ContextLoaderListener registered?" } wac;return } If you still remember we defined a ContextLoaderListener in our web.xml file as part of the configuration of our runtime environment that makes sure an according WebApplicationContext instance gets initialized and registered against the ServletContext properly. Luckily, this problem can easily be solved if we slightly change the way we initialize SpringComponentInjector in our main MyWebApplication class. Apart from the constructor that we have used so far, there is another constructor in the SpringComponentInjector class that expects the caller to provide it with an according ApplicationContext instance rather than trying to resolve one on its own: public SpringComponentInjector(WebApplication webapp, ApplicationContext ctx, wrapInProxies)boolean { (webapp == )if null { IllegalArgumentException( );throw new "Argument [[webapp]] cannot be "null } (ctx == )if null { IllegalArgumentException( );throw new "Argument [[ctx]] cannot be "null } // store context in application's metadata … webapp.setMetaData(CONTEXT_KEY, ApplicationContextHolder(ctx));new // … and create and register the annotation aware injector InjectorHolder.setInjector( AnnotSpringInjector( ContextLocator(),new new
  • 46. In a Nutshell, Wicket... … has had 18,255 commits made by 62 contributors representing 318,037 lines of code … is mostly written in Java with
 a well-commented source code … has a well established, mature codebase maintained by a large development team with stable Y-O-Y commits … took an estimated 84 years of effort (COCOMO model)
 starting with its first commit in September, 2004
 ending with its most recent commit 1 days ago – openhub.net report for Wicket
  • 47.
  • 48.
  • 49.
  • 50.
  • 57. semi-monthly releases mainly bug fixes some new minor features
  • 63. public class HomePage extends WebPage { public HomePage() { add(new Label("title", "Hello!")); } }
  • 64. public class HomePage extends WebPage { public HomePage() { add(new Label("title", "Hello!")); } } <html> <body> <h1 wicket:id="title"></h1> </body> </html>
  • 65. public class HomePage extends WebPage { public HomePage() { add(new Label("title", "Hello!")); } } <html> <body> <h1 wicket:id="title"></h1> </body> </html>
  • 66. Add a <div> around content...
  • 68. <html> <body> <div wicket:id="container"> <h1 wicket:id="title"></h1> </div> </body> </html> public class HomePage extends WebPage {public HomePage() { add(new WebMarkupContainer("container"));add(new Label("title", "Hello!"));} }
  • 69. <html> <body> <div wicket:id="container"> <h1 wicket:id="title"></h1> </div> </body> </html> public class HomePage extends WebPage {public HomePage() { add(new WebMarkupContainer("container"));add(new Label("title", "Hello!"));} }
  • 70. code always follows markup in Wicket
  • 72. public class HomePage extends WebPage { public HomePage() { WebMarkupContainer container = new WebMarkupContainer("container"); add(container); add(new Label("title", "Hello!")); } } <html> <body> <div wicket:id="container"> <h1 wicket:id="title"></h1> </div> </body> </html>
  • 73. public class HomePage extends WebPage { public HomePage() { WebMarkupContainer container = new WebMarkupContainer("container"); add(container); add(new Label("title", "Hello!")); } } <html> <body> <div wicket:id="container"> <h1 wicket:id="title"></h1> </div> </body> </html>
  • 74. public class HomePage extends WebPage { public HomePage() { WebMarkupContainer container = new WebMarkupContainer("container"); add(container); container.add(new Label("title", "Hello!")); } } <html> <body> <div wicket:id="container"> <h1 wicket:id="title"></h1> </div> </body> </html>
  • 75. code always follows markup in Wicket or does it?
  • 76. Enter Component Queuing (coming to you in wicket 7)
  • 77. What if we delay adding components? Queue components until their location in the markup hierarchy is know markupContainer.add(new Label(...)); markupContainer.queue(new Label(...));
  • 78. public class HomePage extends WebPage {
 public HomePage() {
 WebMarkupContainer container = 
 new WebMarkupContainer("container");
 add(container);
 container.add(new Label("title", "Hello!"));
 }
 } public class HomePage extends WebPage {
 public HomePage() {
 queue(new WebMarkupContainer("container"));
 queue(new Label("title", "Hello!"));
 }
 }
  • 81. queue(new Label("label", "Some text"));
 queue(new Label("label", "Other text"));
  • 82. queue(new Label("label", "Some text"));
 queue(new Label("label", "Other text"));
  • 83. queue(new Label("first"));
 queue(new Label("last"));
 
 WebMarkupContainer secure=new WebMarkupContainer("secure") {
 public void onConfigure() {
 super.onConfigure();
 setVisible(isViewingOwnProfile());
 }
 };
 
 queue(secure);
 secure.queue(new Label("creditCardNumber"));
 secure.queue(new Label("creditCardExpiry")); Restrictions of Queuing: Ancestors
  • 84. <h3>
 Welcome,
 <span wicket:id="first"></span>
 <span wicket:id="last"></span>!
 </h3>
 <fieldset wicket:id="secure">
 <legend>Secure</legend>
 <dt>Card expiry: <i wicket:id="creditCardExpiry">
 <dt>Card number: <i wicket:id="creditCardNumber">
 </fieldset>
  • 85. <h3>
 Welcome,
 <span wicket:id="first"></span>
 <span wicket:id="last"></span>!
 </h3>
 <fieldset wicket:id="secure">
 <legend>Secure</legend>
 <dt>Card expiry: <i wicket:id="creditCardExpiry">
 <dt>Card number: <i wicket:id="creditCardNumber">
 </fieldset>
  • 86. <h3>
 Welcome,
 <span wicket:id="first"></span>
 <span wicket:id="last"></span>!
 </h3>
 <fieldset wicket:id="secure">
 <legend>Secure</legend>
 <dt>Card expiry: <i wicket:id="creditCardExpiry">
 </fieldset> <dt>Card number: <i wicket:id="creditCardNumber">
  • 87. <h3>
 Welcome,
 <span wicket:id="first"></span>
 <span wicket:id="last"></span>!
 </h3>
 <fieldset wicket:id="secure">
 <legend>Secure</legend>
 <dt>Card expiry: <i wicket:id="creditCardExpiry">
 </fieldset> <dt>Card number: <i wicket:id="creditCardNumber">
  • 88. <fieldset wicket:id="secure">
 <h3>
 Welcome,
 <span wicket:id="first"></span>
 <span wicket:id="last"></span>!
 </h3>
 <legend>Secure</legend>
 <dt>Card expiry: <i wicket:id="creditCardExpiry">
 <dt>Card number: <i wicket:id="creditCardNumber">
 </fieldset>
  • 89. <fieldset wicket:id="secure">
 <h3>
 Welcome,
 <span wicket:id="first"></span>
 <span wicket:id="last"></span>!
 </h3>
 <legend>Secure</legend>
 <dt>Card expiry: <i wicket:id="creditCardExpiry">
 <dt>Card number: <i wicket:id="creditCardNumber">
 </fieldset>
  • 90. Component Queuing • Wicket 7 feature • Prefer queue() when markup hierarchy can be altered • Uniqueness of Wicket IDs still requirement at same level of queuing • Can move down into child markup hierarchy • Can't move up the markup hierarchy
  • 94. public interface ILinkListener {
 void onLickClicked();
 } ILinkListener l = new ILinkListener(){
 @Override
 public void onLinkClicked() {
 System.out.println("Klik");
 }
 }
  • 95. public interface ILinkListener {
 void onLickClicked();
 } ILinkListener l = () -> {
 System.out.println("Klik");
 }
  • 96. ILinkListener l = () -> {
 System.out.println("Klik");
 } ILinkListener l = new ILinkListener(){
 @Override
 public void onLinkClicked() {
 System.out.println("Klik");
 }
 } or
  • 97. add(new Link<Void>("save") {
 @Override
 public void onClick() {
 dao.save(object);
 getSession().info("Saved.");
 setResponsePage(new OtherPage())
 }
 });
  • 98. add(new Link<Void>("save") {
 @Override
 public void onClick() {
 dao.save(object);
 getSession().info("Saved.");
 setResponsePage(new OtherPage())
 }
 });
  • 100. private void onSave() {
 dao.save(object);
 getSession().info("Saved.");
 setResponsePage(new OtherPage())
 }

  • 101. private void onSave() {
 dao.save(object);
 getSession().info("Saved.");
 setResponsePage(new OtherPage())
 }
 add(new Link<Void>("save")
 .onClick(this::onSave));

  • 102. A link with onclick, visibility and body
  • 105. add(new Link<Void>("like") {
 @Override
 public void onClick() {
 person.likedBy(me);
 }
 });
  • 106. add(new Link<Void>("like") {
 @Override
 public void onClick() {
 person.likedBy(me);
 }
 
 @Override
 public boolean isVisible() {
 return person.isNotLiked();
 }
 });
  • 107. add(new Link<Void>("like") {
 @Override
 public void onClick() {
 person.likedBy(me);
 }
 
 @Override
 public boolean isVisible() {
 return person.isNotLiked();
 }
 }.setBody());
  • 108. add(new Link<Void>("like") {
 @Override
 public void onClick() {
 person.likedBy(me);
 }
 
 @Override
 public boolean isVisible() {
 return person.isNotLiked();
 }
 }.setBody(new AbstractReadOnlyModel<String>() { 
 }));
  • 109. add(new Link<Void>("like") {
 @Override
 public void onClick() {
 person.likedBy(me);
 }
 
 @Override
 public boolean isVisible() {
 return person.isNotLiked();
 }
 }.setBody(new AbstractReadOnlyModel<String>() { 
 @Override
 public String getObject() {
 } }));
  • 110. add(new Link<Void>("like") {
 @Override
 public void onClick() {
 person.likedBy(me);
 }
 
 @Override
 public boolean isVisible() {
 return person.isNotLiked();
 }
 }.setBody(new AbstractReadOnlyModel<String>() { 
 @Override
 public String getObject() {
 StringBuilder sb = new StringBuilder("Like ");
 sb.append(person.getFirstName());
 return sb.toString();
 } }));
  • 111. A link with onclick, visibility and body
  • 114. add(new Link<>("like")
 .visible(() -> person.isNotLiked())
 );

  • 115. add(new Link<>("like")
 .visible(() -> person.isNotLiked())
 .onClick(() -> person.likedBy(me))
 );

  • 116. add(new Link<>("like")
 .visible(() -> person.isNotLiked())
 .onClick(() -> person.likedBy(me))
 .body(() -> {
 })
 );

  • 117. add(new Link<>("like")
 .visible(() -> person.isNotLiked())
 .onClick(() -> person.likedBy(me))
 .body(() -> {
 StringBuilder sb = new StringBuilder("Like ");
 sb.append(person.getFirstName());
 return sb.toString();
 })
 );

  • 118. add(new Link<>("like")
 .visible(() -> person.isNotLiked())
 .onClick(() -> person.likedBy(me))
 .body(() -> {
 StringBuilder sb = new StringBuilder("Like ");
 sb.append(person.getFirstName());
 return sb.toString();
 })
 );
 add(new Link<Void>("like") {
 @Override
 public void onClick() {
 person.likedBy(me);
 }
 
 @Override
 public boolean isVisible() {
 return person.isNotLiked();
 }
 }.setBody(new AbstractReadOnlyModel<String>() { 
 @Override
 public String getObject() {
 StringBuilder sb = new StringBuilder("Like ");
 sb.append(person.getFirstName());
 return sb.toString();
 } })); Anon inner classes: 17 lines Java 8 lambdas: 9 lines
  • 121. ScriptEngineManager m = new ScriptEngineManager(); ScriptEngine nashorn = m.getEngineByName("nashorn"); nashorn.put("age", validatable.getValue()); String js = "age >= 18"; try { Object result = nashorn.eval(js); if(!((Boolean)result) { ValidationError e = new ValidationError(); validatable.error(e); } } catch(Exception e) { }
  • 122. ScriptEngineManager m = new ScriptEngineManager(); ScriptEngine nashorn = m.getEngineByName("nashorn"); nashorn.put("age", validatable.getValue()); String js = "age >= 18"; try { Object result = nashorn.eval(js); if(!((Boolean)result) { ValidationError e = new ValidationError(); validatable.error(e); } } catch(Exception e) { }
  • 123. ScriptEngineManager m = new ScriptEngineManager(); ScriptEngine nashorn = m.getEngineByName("nashorn"); nashorn.put("age", validatable.getValue()); String js = "age >= 18"; try { Object result = nashorn.eval(js); if(!((Boolean)result) { ValidationError e = new ValidationError(); validatable.error(e); } } catch(Exception e) { }
  • 124. ScriptEngineManager m = new ScriptEngineManager(); ScriptEngine nashorn = m.getEngineByName("nashorn"); nashorn.put("age", validatable.getValue()); String js = "age >= 18"; try { Object result = nashorn.eval(js); if(!((Boolean)result) { ValidationError e = new ValidationError(); validatable.error(e); } } catch(Exception e) { }
  • 125. ScriptEngineManager m = new ScriptEngineManager(); ScriptEngine nashorn = m.getEngineByName("nashorn"); nashorn.put("age", validatable.getValue()); String js = "age >= 18"; Object result = nashorn.eval(js); try { if(!((Boolean)result) { ValidationError e = new ValidationError(); validatable.error(e); } } catch(Exception e) { }
  • 126. ScriptEngineManager m = new ScriptEngineManager(); ScriptEngine nashorn = m.getEngineByName("nashorn"); nashorn.put("age", validatable.getValue()); String js = "age >= 18"; Object result = nashorn.eval(js); if(!((Boolean)result) { ValidationError e = new ValidationError(); validatable.error(e); } try { } catch(Exception e) { }
  • 127. ScriptEngineManager m = new ScriptEngineManager(); ScriptEngine nashorn = m.getEngineByName("nashorn"); nashorn.put("age", validatable.getValue()); String js = "age >= 18"; try { Object result = nashorn.eval(js); if(!((Boolean)result) { ValidationError e = new ValidationError(); validatable.error(e); } } catch (Exception e) { }
  • 132. Is there a future for 
 server-side frameworks?
  • 134. JavaScript Frameworks War JQuery AngularJS Ember.js React Backbone.js Meteor KnockoutJS Dojo Agility.js CanJS Polymer Mithril Maria Flight Knockback.jsAmpersand
  • 135. What is the Future for web development?
  • 136. What is the Future for web development? Web Components
  • 137. What is the Future for web development? Web Components PolymerAngularJS (2.0)
  • 138. What is the Future of Wicket?
  • 139. No Revolution but Evolution
  • 140. a brief history
 of Wicket the current state
 of Wicket the future
 of Wicket Summary