Τρίτη 17 Νοεμβρίου 2009

DEVOXX 09

Two whole years have passed, since Javapolis 2007. I decided to attend Javapolis, now called Devoxx, again, with the same excitement as before. And since a (female) Java developer friend complained that I didn't update my blog about it, I decided to do so.
Even in the middle of the financial crisis, something like 2500 people attended this year's event, which took place from 16th-20th of November. The kiosks where less and less rich than from what I remember two years ago. However, the excitement was still the same, maybe higher!
Only one other Greek guy came for the whole event, Paris Apostolopoulos, the founder of JHUG. Dimitris Andreadis, now project manager or something at jboss, joined in the 3rd day. So, only 3 Greek guys this time, very few compared to the around 7 that were back in 2007.

Well, let's get started. I focus mainly on technology in this blog, putting down what I managed to note during the presentations. You may find the conference schedule in http://devoxx.be/display/DV09/Schedule.

Day 1 - University Day 1

Unfortunately, I didn't keep many notes the first day. I started with Introduction to Java Generics by Prof. Eric Steegmans of university of Leuven. Well, I had some questions about generics, which I hoped this session would help to clarify, which it did. Even though it was introductory in nature, it turned out to be quite fruitful. I put down few notes:
  • Since, due to backwards compatibility, every generic type is translated to an Object, and since we cannot instantiate a generic type, it makes sense to write something like: this.elements = (E[]) new Object[Math.abs(capacity)];
  • We can always attempt to return a wrong type
T t = (T) new Date();
T f() {return (T) new Date(); }


Eric also demonstrated how we can use Generics to create whole frameworks, and he demonstrated an implementation of the Composite pattern using Generics.

After lunch, I attended JSF 2: Keep the progress coming by Dan Allen, Peter Muir and Andy Schwartz . A lot of new features where presented, but unfortunately I didn't keep many notes. I remember however one useful feature:
javax.faces.VALIDATE_EMPTY_FIELDS = true

in the web.xml which checks for empty fields. You may start a jcp.org account and of course check javaserverfaces.org for JSF2.next.

I then attended Easing JPA data access with Hades by Oliver Gierke , which has some useful additions. Please check the http://hades.synyx.org web site.

Finally, Spock - the smarter testing and specification framework by Peter Niederwieser is a testing framework based on Groovy, that has a common syntax to run both junits and mock objects. The Next Generation Profiling and Diagnostics Tools by Noora Peura and Anders Astrand has been JRockit. This is actually a JVM which allows you to profile your application.

Day 2 - University Day 2

The kiosks and stands were in place. Around for collecting any goodies like pens, T-shirts etc. Less participants than other times. A good collection of books at Amazon prices.
The second day started with the presentation of The Java EE 6 Platform by Antonio Goncalves and Alexis Moussine-Pouchkine. These two amazing guys presented all the new specification that will be part of JEE 6:
  • JPA 2.0: pessimistic locking, caching, Criteria API as an alternative to SQL queries and JPQL and type safety
  • Servlet 3.0: plugability, asynchronous support, FileUpload (finally!!!), no need for web.xml (@WebServlet annotation); it will be supported by Glassfish 3, Tomcat 7, JBoss 6, Jetty 8
  • Managed Beans 1.0, EJB 3.1 & 3.1 lite: Everything is managed beans. E.g. EJB is a managed bean with transactional support, security and multithreading; RESTful service is a managed bean with HTTP support. EJB lite allows EJBs to be deployed to .war files (no need for .ear files). EJB 3.1 lite spec contains local session beans, security, interceptors, CMT/BMT and injection; but not CMP, MDBs, JMS, RMI/IIOP etc. It also adds an embeddable EJB container (e.g. for testing), Singleton components with concurrency management per application per JVM, optional remote interfaces, asynchronous calls (no threads allowed) etc.
  • JAX-RS 1.1 adds support for RESTful web services and integrates with EJBs. Simply annotate a stateless EJB with (some of) the following annotations to make it a service (everything is transactional): @Path("/path") @GET @Produces("text/html") @POST @Consumes("text/xml").
  • JSF 2.0 does not require Servlet 3.0. Facelets has become the alternative to JSPs View Description Language or VDL. faces-config.xml is also optional (like web.xml); navigation now belongs to the page, e.g. return "targetPage.xhtml"; Component creation is easy; single .xhtml files with JSF tags and no Java code. Error reporting and stack trace has been improved and looks like ASPX .NET's. For the first time there is official Javascript support via jsf.js; e.g. jsf.ajax.request and f:ajax tags. Other features introduced are new scopes, templates (layouts), project stages (e.g. dev, test, production) etc.
  • Bean Validation 1.0 introduces the rule constraint once, validate anywhere. Declarative validation is done with the annotations @NotNull @Valid @Size etc.
  • Profiles to simplify the spec; currently, only one profile, Web Profile is supported (no EJBs, no JMS etc.)
  • Standard (portable) JNDI names across application servers
  • Interceptors 1.1 now separated from EJB spec
  • @Inject tag for dependency injection
  • JCDI 1.0 which allows developers to bind Java EE components to lifecycle contexts, to inject these components, and to enable them to support loosely coupled communication
Recommended book: "Beginning Java™ EE 6 Platform with GlassFish™ 3: From Novice to Professional" of Antonio Goncalves.

From the server side to the client side, The JavaFX Platform - A Java Developer's Guide by Stephen Chin. JavaFX is the new way for building rich clients, or GUIs. It is a replacement (?) of Swing. It is the future, as Sun claims.
Example code:
Stage {
scene: Scene {
content: []
}
}

Stage is the equivalent to Swing's Window/JFrame. Inspired from 3D graphics I suppose, you then define a scene, which represents the scene graph of the components to be added, and then the content where you add the components. scene:Scene <=> Scene scene = new Scene();
JavaFX has support for closures, new layouts (HBox, VBox, Tile, MigLayout etc.), binds (the equivalent to Swing events), sequences, animations (e.g transitions) and type inferencing. It doesn't support annotations, generics and multi threads. It is a strongly typed language like Java. Examples of:
  • binds (regular/lazy): var x = bind a + b; whenever a or b change, x changes as well
  • sequences: [1 .. 3] means 1 2 3
  • [1 .. <4] means 1 2 3
  • [1..3 step 2] means 1 3
  • var ints = [1 4 4 6 5]
  • ints [k | k>4] returns 6 5
  • insert -1 into ints[2]
  • delete 4 from ints returns [1 6 5]
  • Support for stylesheets (.css)
Try JfxBuilder and FxBuilder.

JavaFX for Mobile applications currently supports only the common profile and runs on Windows ME platforms.

Recommended book
: "Pro JavaFX Platform" by James Weaver et al.
Recommended sites: http://javafx.com, http://jfxtras.org, http://learnjavafx.typepad.com, http://steveonjava.com

A Year of Monitoring with Java-monitor by Kees Jan Koster got us into the workings of the garbage collector, or garbage collectors. In case you didn't know, there are two garbage collectors in Java: the Scavenger who is faster but doesn't do such a good job, and the MarkSweeper who is slower, but cleans everything! He gave examples of memory leaks, like e.g. how file descriptors in Linux (1024) can easily been allocated (FreeBSD has some 10000 fds, Solaris?), so man ulimit and limits commands to see how to increase the number of file descriptors in your system.
-Xss limits thread stacks. Don't use System.gc() inside an application server e.g. Tomcat; it affects all deployed applications. Use the server version of jdk, i.e. java -server.

Recommended sites: http://www.java-monitor.com

In Scala Actors: A Tool to Harness the Power of Multicore CPUs on the JVM, Frank Sommers presented Scala actors who communicate via immutable messages. Actors are executed in threads in a thread pool. You can write your own actor by extending scala.actors.Actor. Messages are defined with case classes. The framework allows pattern matching and remote actors.

Recommended book
: "Programming in Scala" by Martin Odersky, Lex Spoon, and Bill Venners
Recommended site: http://www.artima.com

Day 3 - Conference Day 1


Devoxx's first conference day started with lots and lots of people, joining just for the conference. And with the traditional key note of the guy who started all this, Stephan Janssen. He was happy that participants reached once again 2500. The presentations will be available for free in parleys.com from January 2010.

Steven Harris from Oracle talked about Java, the Platform for the Future. He spoke about WebLogic's Dynamic module which uses profiles to capture collections of OSGi bundles and about virtualisation. He created a VMWare instance, by using Oracle Assembly Builder Studio, that ran just a java application.

The next key speakers Roberto Chinnici and Ludovic Champenois presented Java EE 6 and GlassFish V3: Evolution of a Platform. The good news are that Java EE 6 together with Glassfish v3 and Netbeans 6.8 will all be released on 10th December 2009! I already spoke about the new features of the new JEE 6 platforms above, but here some additional things:
  • @Email String email;
  • Modular web applications
  • EJB Container now works in Java SE too
  • @Singleton, @Startup beans, @asynchronous invocations
  • JSF 2.0 features: standardized facelets, composite components, autodiscovery of components, javascript API (jsf.js) for AJAX support
  • A POJO is turned into an EJB 3.1 by adding the @Stateless annotation to it.
Then Christophe Coenraets from Adobe took over with his impressive Integrating designers into your application development presentation. Adobe Flash 10.1 targets smartphones and flash applications now run exactly the same in the smartphone as in the desktop. AIR 2.0 now allows accessing native applications. Finally, he gave an impressive presentation of Adobe Flash Catalyst, a tool which allows a developer to transform a .psp image created by the web designer to the GUI of a web application!

After the lunch break, I chose to attend JDK7 Update by Mark Reinhold. Mark showed what we should expect from JDK 7. JDK 7 will be modular, multi-lingual (Java, JRuby, Jython etc.), productive and performant. As the size of the JRE is around 13 Mb, Java is currently refactored into modules; there will be a base module and other modules which will depend on this base module, like awt module, swing, sound, tools, corba etc. modules. Modules may eventually replace jar files. The user will download just the modules s/he needs.
JDK 7 introduces the diamond (<>) operator: Map<String, String> map = new HashMap<>();
Some other new syntax has been inspired from Ruby, e.g.: long l = 322_123_888L; New binary representation: 0b1001. The [] operator is not privileged by arrays only:
List<String> list = ["1","4","5"];
list[2] = "6";


JDK 7 will have limited closure support and additional multi-threading goodies (invokeAll). Static methods can be declared in interfaces. An example of a closure:
#int (int, int) multiplier = #(int x, int y) { x*y }

Recommended site: http://openjdk.java.net/project/jdk7.


After the lunch break, I decided not to attend James Gosling's talk, but HTML 5 Communications - The New Network Framework for the Web by Frank Greco instead and it proved to be a rewarding choice! HTML 5 will bring Web 3.0 in our lives. Web 1.0 served only static pages; Web 2.0 is dynamic, with the advances of Ajax and RIA applications; Web 3.0, however, will be a Read/Write Web, event-driven, secure, reliable and will support real-time communications with no latency.

W3C and IETF, who work together on HTML 5, have decided to get rid of HTTP altogether; HTTP is half-duplex protocol. A new protocol WS (and its equivalent WSS, i.e. secure) will be introduced in Web 3.0, where WS stands for Web Sockets, i.e. we will be able to write ws://www.foo.com!

The new spec will contain the following:
  • TCP bi-directional Web Sockets
  • Standardised HTTP Streaming which means that browsers will support mashups (this is a standardisation of Comet for server sent events)
  • Secure cross-site remote connectivity
  • Secure browser cross-document messaging
The Web Sockets API is already available for download and Frank presented a demo of real-time stock option available by Kaazing. In short, Web 3.0 will be:
  • highly scalable
  • backwards compliant
  • extensible with new protocols, security etc.
  • performant, and
  • compliant with open standards
jBPM is a framework I always wanted to use, but never had a chance. So, whenever I find the opportunity, I try to go and listen to what Tom Baeyens has to say about it. jBPM4 in Action is a total refactoring of the previous version.

Business Process is defined as a way of doing things with a certain goal. jBPM has a transactional state machine, a generic graph execution engine and a process VM. In version 4 there is:
  • new API with new query mechanism
  • native spring integration
  • compact DB schema
  • GWT web console
  • Signavio web modelling
  • BPMN2 jPDL (process language) that supports concurrency and asynchronous continuations
  • task forms for rapid prototyping
  • eclipse plugin (eclipse process designer)
Recommended sites: http://www.jbpm.org, http://www.jorambarrez.be

Being curious of Comet, I decided to go for Writing Asynchronous Web application (Comet) using the Atmosphere Framework by Jean-Francois Arcand and Paul Sandoz.
The guys compared polling, Ajax push and HTTP streaming. Atmosphere is based on RESTful web services, i.e. with JAX-RS. No vendor lock, works with all application servers, runs on top of any Servlet 2.3/3.0 compliant servlet container. REST + Jersey = Atmosphere plus a number of tags: @Suspend, @Resume, @Broadcast, @Schedule, @Cluster. Features:
  • cookie based transactions
  • web socket support
  • persistence support
  • adaptive event aggregator
Recommended sites: http://atmosphere.dev.java.net, http://jersey.dev.java.net

The day finished with Project Coin by Joseph D. Darcy and the new additions to Java 7. So, there will be the possibility to write:

String s;
switch (s) {
case "one" :
...
}
  • variable names will contain any character
  • automatic resource management, e.g.
try (FileInputStream is, FileOutputStream os) {
...
}

i.e. there will be no catch statement and resources will be released automatically.
  • simplified varargs method invocation
  • collections will now use [], e.g.
List l = new LinkedList<>();
l[0] = 6;
  • New elvis operator (from Groovy): a ?: b <=> if (a!=null) a else b
  • JSR 292 support
  • EnumSet, EnumMap
  • reification
  • multiple exceptions support
try {
...
} catch (final Exception1 ex | Exception2 ex) {
throw ex;
}

The day finishes with a beer call and free chips.

Day 4 - Conference Day 2

Day 4 starts very interestingly too, with Ivar Jacobson and Do we really know how to develop software? For those who didn't know, Ivar is one of the three amigos behind UML.
Ivar spoke about people who don't know about software and try to make money out of it. He also addressed the issue that academic research must be aligned with industry practice.


There are currently thousands of methods and methodologies which simply reinvent the wheel over and over again. We don't know what others are doing. We need a theoretical basis to develop software!!! One that aligns academic research with industry practice.
He has started a Software Engineering Method And Theory (SEMAT) which can be found in http://www.semat.org. In this work, he defines a kernel to be an empty process which defines a common basis to start with. The kernel ensures common understanding across all teams. The kernel is surrounded by practices which define the various practices specific to the kernel.
He asks to give him our thoughts about this theory by sending an email to a_theory@ivarjacobson.com. He doesn't know if he will succeed or not, but he finished his presentation with a saying of Kurt Lewin: "There is nothing as practical as a good theory".

And the day continues with Robert C. Martin or uncle Bob and Filling The Professionalism Gap: Craftsmanship and Policy. Eccentric uncle Bob, author of books like "UML for Java Programmers" and "Clean Code" starts walking up and down the scene describing the story of his career. He started his career in the late 70s, when at the age of 18 he was hired along with 2 other teenagers to migrate a program to a new system for which they even had to write the operating system for! He went on describing the 80s, the 90s and our decade and he always ended up to the same conclusion between management and developers: "They hated us; we hated them"!!!!! He dared to say a great truth, that we, developers, do not have a defined profession yet! The difference between professionalism and craftmanship is that a professional is proud of what s/he does, and is able to do a good job. What prevents us from doing a good job? The managers? He advises that we should learn to say no! We are being viewed as blue colar workers (with a hourly rate). Do doctors and lawyers charge per hour?
There is also a temptation for developers to become managers (management is a profession by the way).


There is a manifesto of software craftmanship, which came out of the agile manifesto.
So, how can a software developer behave like a professional?
  1. Do no harm (say no when managers say they want it tommorrow)
  2. Write clean code by using TDD with 100% test coverage (it is not professional to not know if your code works)! QA is a specification not a verification.
  3. Work team-based, not project-based and keep the team together! Do not change teams depending on projects; all projects should be assigned to the same team.
Recommended book: "Clean Code" by Robert C. Martin.
Recommended site: http://www.objectmentor.com

After such a morning, I continued with Spring Framework 3.0 by Arjen Poutsma. So, what to expect from the 3rd version of the most used Java framework. Well, six things:
  1. Java 5 syntax
  2. Expression language as an independent component
  3. RESTful web services support
  4. Portlets 2.0 support
  5. Declarative annotation support (JSR 303)
  6. JEE 6 support
In more detail. Spring 3.0 will provide Generics support which will backward compatible like in Java. Object XML (OXM) module moved to the core. There will be property editors, type converters and formatters, and annotated factory methods and meta-annotations.
Spring configuration can now be defined in a Spring Java config class:

@Configuration
public class AppConfig {

}

EL came out of the core as a separate component. EL is now used, additionally to web navigation, in bean definitions, in annotations, and in default context attributes determined at runtime.

Sping 3.0 now supports URI templates to create RESTful URLs, e.g. /hotel/{hotelid}
@PathVariable @RequestMapping(/hotels/{hotelid}
class HotelController {
public void handleHotel(@PathVariable ("hotel") String hotel) { }
}
Other annotations: @CookieValue, @RequestHeader, @RequestBody, @ResponseBody.

template = new RestTemplate();
result = template.getForObject(uri, HotelList.class, "1");
template.postForLocation(uri, booking, vars); // vars is a hashmap of {hotel}
template.delete(location);
template.execute(uri, HttpMethodGET, myReqCallback, myResCallback);

Partial support for JEE 6 will include: JSF 2, JPA 2, Bean Validation, JSR 303 and dependency injection. Spring 3.1 will provide full JEE 6 support.

In Spring 3.0, Common Attributes and TopLink have been pruned. MVC controller hierarchy, JUnit 3.8, Struts 1.x, and some outdated helper classes have been deprecated.

And the day continues with The not so dark art of Performance Tuning by Kirk Pepperdine and Dan Hardiker. Kirk, together with Java evangelist Heinz Kabutz, are located in Chania Crete from where they provide expertise on many Java issues; one of them, performance. Kirk demonstrated Apache JMeter, a tool for load and stress testing, to find performance problems in a web application. One can create a test plan to do his/her tests. There are four dominating consumers: hardware, JVM/OS, application and actors.
He also talked about VisualVM, ThreadDumpAnalyzers and stack traces.

Recommended site: http://www.javaperformancetuning.com

iBeans: dead-simple integration for the Web by Ross Mason. Ross presented an alternative solution to SOA and ESB for web integration. An iBean is a Java Interface with annotated methods; a definition of how to talk to a service; a web service without XML! iBeans provide a simple solution for performing common integration tasks such as receiving and sending messages over Email, JMS or calling a Web Service. iBeans use no SOA, are cross-platform, easy to resuse and task-focused. iBeans central is a shared repository of iBeans. There is a Server API with functions like send/receive data, schedule tasks, create request/receive services, support protocols, and a Client API which allows you application to talk to other systems like Twitter, Google, Amazon, Facebook etc.
iBeans deals with details like security in various service providers.

The Server API is contained in ibeans.war and has a number of useful annotations to use in your server side code:

@Send (uri="xmpp:// ... ")
@Schedule (interval="60000")
void method() { ... }

@Receive (uri="jms://my_queue")
void onMessage(Object msg) { ... }

@Transform // transforms a JMS message to an object we define e.g. Order

@IntegrationBean

On the client side, you can use iBeans in Javascript:

var ibeans = new IBeansClientCJ;
var x = ibeans.config.get( ... );
ibeans.twitter.set(x);

iBeans provide support for GWT, Grails, Spring, Struts 2.x, Play! Its target is to become the WCF for the Web. What's next? WS support.

Recommended site:
http://www.mulesoft.org/display/IBEANS/Home

After the lunch break, back to some more JEE stuff: Deep dive on the Java EE 6 platform with GlassFish V3 by Roberto Chinnici and Ludovic Champenois. Lets see what new features does JEE 6 bring on.
- The new Web Servlet container brings initializers. Initializer libraries are stored in /META-INF/resources/. Initializer class implements ServletContainerInitializer inside /META-INF/web-fragment.xml:


<web-fragment>
<servlet>ServletClassName<.servlet>
</web-fragment>


- CDI portable extensions. WebBeans support JSR-330 Context Injection. There is context management with scopes (and a new @ConversationScope), bean discovery and injection points in a bean. Below is an extension interface:

public Interface Bean extends Contextual {
interface AnnotatedType extends Annotated;
}

These are stored in /META-INF/services. Finally, there is support for Before/After discovery events.

Glassfish v3

Very fast, very small, modular, embedded, OSGi, RESTful administration, various containers (JRuby, Django, Grails, Rails). Containers are added/removed automatically.
There is also a stripped jar (<1Mb) that contains all JEE 6 jars.

java -jar glassfish.jar mywebapp.war

There is automatic compilation support; thus you can change your servlet, then save your changes and refresh your browser to see your changes. There is a maven web application to manage your maven projects.
Monitoring and management are exposed via RESTful web services:
http://localhost:4848/management/domain
http://localhost:4848/monitoring/domain/


Recommended site: http://java.sun.com/javaee/downloads/index.jsp


The last presentation of the day was Maven Reloaded by Jason van Zyl. Jason presented the new features of Maven 3.0. There will be backwards compatibility. The project builder has been refactored, there is a pluggable model reader and mixins to extend POMs, DSLs (Groovy, Ruby, Python, Scala), incremental build support (also in mEclipse), lifecycle extension points, OSGi bundles and a maven shell.

And this ends day 4.

Day 5 - Conference Day 3

The companies have started packaging their kiosks, and the exposition area seems empty. After 4 tiring but rewarding days, time for some fun with Gaming JavaFX by Richard Bair and Jasper Potts.
Their games are based in a physics library: Phys2D --> JBox2D --> Phys2D.
World contains a static and dynamic body. Collision detection is expensive. In JavaFx, you start by creating a PhysicalScene which contains a PhysicsWorld with gravity and interactions. A PhysicalObject is a node in the scene with a physics body which has a geometry. Prism replaces AWT, and talks directly to the hardware (Direct3D or OpenGL).
The speakers presented a number of games, one involving explosions. An explosion visual has been emulated with iterating images.

class ExplosionFS extends FourceSource
public var explosions[]

Stage {
Scene: PhysicalScene {
content {
Ground {
...
}
Ball {
}
}
}
}

Recommended site: http://www.fxexperience.com

The next presentation was mainly due to work. Managing Glassfish on OpenSolaris by Simon Ritter. Glassfish and OpenSolaris are both free and open source under CDDL license. Simon talked about various containers: ZFS, Zone (multi-core CPUs virtualisation), Crossbow (network virtualisation), SMF (automate services) and how to run GF with RBAC (Robust Access Control) and SMF.
ZFS is the new file system created by SUN Microsystems. It is a pool based storage with no volumes, that prevents silent data corruption (i.e. no need for fsck) using a big checksum, almost zero overhead and easy rollback.
Volumes have been replaced by a 128-bit storage pool and all free storage is always available, fast and simple. ZFS snapshots are read-only, incremental, thus efficient. ZFS storage pools can be accessed with the following commands:

# zpool list
# zpool status
# pfexec zpool create mypool ()
# pfexec zfs snapshot
# pfexec zfs rollback
# pfexec zfs send
# pfexec zfs receive

Zones virtualise system resources (CPUs, NICs, memory etc) not the hardware. They are lightweight and no virtual machine is needed. Crossbow, e.g. can virtualise a number of NICs (Virtual NICs) that run different applications:

SMF provides a uniform mechanism to manage services:

svcadm [disable|enable] mydomain

Dependencies are declared in an xml manifest for the service. Compared to rc*.d, there is a GUI.

asadmin create-service

And the last presentation was ArchiMate: A common language for Enterprise Architecture by Remco Blom. Archimate is a standard language for modelling and visualising enterprise architectures. It bridges the gap from business pictures to technical UML diagrams. UML is not designed for Enterprise Architecture; business people don't understand it; there is no explicit service paradigm and has many models.
BizzDesign is an IDE that supports the Archimate language. Architype is a structure of a system in terms of components, relations, underlying principles and visible properties. Enterprise Architecture has a process view (way of working) and a product view (design). TOGAF (Open Group Architecture Framework) defines the process and Archimate defines the language. The archimate IO specification defines 3 layers (business, application and technology) and 3 aspects (passive structure, active structure and behaviour).
Then, he demonstrated the bizzdesign tool and he didn't miss to mention a TOGAF eclipse plugin, too. BizzDesign can be integrated with Visio (with stencils) or can be downloaded as an IDE (BizzDesign Architect). One can refer from an archetype diagram to a UML diagram and vice versa.

Recommended sites: http://www.archimate.org, http://www.opengroup.org/archimate, http://bizzdesign.com.

And this ends 2009 Devoxx conference. All the presentations will be available from January next year hopefully, in parleys.com and all those who couldn't participate will have a chance to take a snif of what was presented there, and what you missed. See you, hopefully, next year!