6.4.0 (Oct 5, 2017)

The major change in this release is the project structure.

The library now consists of the following artifacts found in the Maven group "org.apache.juneau":

Category | Maven Artifacts | Description | Prereqs
--- | --- | --- | ---
Juneau Core | juneau-marshall | Serializers and parsers for: JSON XML HTML UON URL-Encoding MessagePack SOAP/XML CSV BSON (coming soon) YAML (coming soon) Protobuf (coming soon) | Java 6
juneau-marshall-rdf | Serializers and parsers for: RDF/XML RDF/XML-Abbrev N-Triple Turtle N3 | Java 6 Apache Jena 2.7.1
juneau-dto | Data Transfer Objects for: HTML5 Atom Cognos JSON-Schema Swagger 2.0 | Java 6
juneau-svl | Simple Variable Language API | Java 6
juneau-config | Configuration file API | Java 6
Juneau REST | juneau-rest-server | REST Servlet API | Java 6 Servlet 3.1
juneau-rest-server-jaxrs | Optional JAX-RS support | Java 6 JAX-RS 2.0
juneau-rest-client | REST Client API | Java 6 Apache HttpClient 4.5
Juneau Microservice | juneau-microservice-server | REST Microservice Server API | Java 8 Eclipse Jetty 9.4.3
juneau-microservice-template | Developer template project | Java 8 Eclipse Jetty 9.4.3
Examples | juneau-examples-core | Core code examples |
juneau-examples-rest | REST code examples |
Juneau All | juneau-all | Combination of the following: juneau-marshall juneau-dto juneau-svl juneau-config juneau-rest-server juneau-rest-client | Java 6 Servlet 3.1 Apache HttpClient 4.5

##### juneau-marshall

- Improvements to swap support.
  - New {@link oaj.annotation.Swap @Swap} annotation.
    Replaces the @Pojo and @BeanProperty(swap) annotations.
  - Support for per-media-type swaps.
    Programmatic example:

    @Swap(MyJsonOnlySwap.class) public class MyPojo {} public class MyJsonOnlySwap extends PojoSwap<MyPojo,String> { public MediaType[] forMediaTypes() { return MediaType.forStrings("*/json"); } public String swap(BeanSession session, MyPojo o) throws Exception { return "It's JSON!"; }

    Annotated example:

    @Swap(impl=ToStringSwap.class, mediaTypes="*/json") public class MyBean { ... } public class ToStringSwap extends PojoSwap<Object,String> { public String swap(BeanSession session, Object o) throws Exception { return o.toString(); } }

  - Support for templated swaps which provide additional context information for a swap.
    The following is an example of a templated swap class used to serialize POJOs to HTML using FreeMarker:

    // Our abstracted templated swap class. public abstract class FreeMarkerSwap extends PojoSwap<Object,Reader> { public MediaType[] forMediaTypes() { return MediaType.forStrings("*/html"); } public Reader swap(BeanSession session, Object o, String template) throws Exception { return getFreeMarkerReader(template, o); // Some method that creates raw HTML. } }

    @Swap(impl=FreeMarkerSwap.class, template="MyPojo.div.ftl") public class MyPojo {}

  - New {@link oaj.annotation.Swaps @Swaps} annotation for defining multiple swaps against the same POJO when they're differentiated by media types:

    @Swaps( { @Swap(MyJsonSwap.class), @Swap(MyXmlSwap.class), @Swap(MyOtherSwap.class) } ) public class MyPojo {}

- New {@link oaj.transform.Surrogate} interface for identifying surrogate classes.
- Serializers can now serialize to {@link java.util.StringBuilder StringBuilders}.
- Serializers now serialize the contents of {@link java.io.Reader Readers} and {@link java.io.InputStream InputStreams} directly to the output stream or writer.
  When used with conjunction with PojoSwaps, this can be used to provide customized output for specific content types.

  @Pojo(swap=MyBeanSwap.class) public class MyBean {...} public class MyBeanSwap extends PojoSwap<MyBean,Object> { public Object swap(BeanSession session, MyPojo o) throws Exception { MediaType mt = session.getMediaType(); if (mt.hasSubType("json")) return new StringReader("{foo:'bar'}"); // Custom JSON output return o; // Otherwise treat as normal bean } } // Produces "{foo:'bar'}" String json = SimpleJsonSerializer.DEFAULT .toString(new MyBean());

  This feature helps with the implementation of language-agnostic template support such as for using FreeMaker to serialize POJOs to HTML.
- {@link oaj.serializer.SerializerSession} and {@link oaj.parser.ParserSession} objects are now reusable if used within the same thread.

  // Old way (still works) JsonSerializer.DEFAULT.serialize(writer1, pojo1); JsonSerializer.DEFAULT.serialize(writer2, pojo2); // Same, but using a session object SerializerSession session = JsonSerializer.DEFAULT.createSession(); try { session.serialize(writer1, pojo1); session.serialize(writer2, pojo2); } finally { session.close(); }

  This is mostly an internal change and doesn't affect the existing APIs.
- {@link oaj.transform.PojoSwap#swap(BeanSession,Object)} and {@link oaj.transform.PojoSwap#unswap(BeanSession,Object,ClassMeta)} can now throw arbitrary exceptions instead of having to wrap them in SerializeException/ParseException.
- New {@link oaj.utils.CalendarUtils} class that encapsulates serialization/parsing logic from {@link oaj.transforms.CalendarSwap} and {@link oaj.transforms.DateSwap}.
- New annotation {@link oaj.html.annotation.Html#anchorText}.
- New methods on {@link oaj.ObjectList}:
  - {@link oaj.ObjectList#get(int,Class) get(int,Class)}
  - {@link oaj.ObjectList#get(int,Type,Type...) get(int,Type,Type...)}
  - {@link oaj.ObjectList#getMap(int,Class,Class) getMap(int,Class,Class)}
  - {@link oaj.ObjectList#getList(int,Class) getList(int,Class)}
- New methods on {@link oaj.ObjectMap}:
  - {@link oaj.ObjectMap#get(String,Class) get(String,Class)}
  - {@link oaj.ObjectMap#get(String,Type,Type...) get(String,Type,Type...)}
  - {@link oaj.ObjectMap#getWithDefault(String,Object) getWithDefault(String,Object)}
  - {@link oaj.ObjectMap#getWithDefault(String,Object,Class) getWithDefault(String,Object,Class)}
  - {@link oaj.ObjectMap#getWithDefault(String,Object,Type,Type...) getWithDefault(String,Object,Type,Type...)}
  - {@link oaj.ObjectMap#getSwapped(String,PojoSwap) getSwapped(String,PojoSwap)}
  - {@link oaj.ObjectMap#getAt(String,Class) getAt(String,Class)}
  - {@link oaj.ObjectMap#getAt(String,Type,Type...) getAt(String,Type,Type...)}
  - {@link oaj.ObjectMap#getMap(String,Class,Class,Map) getMap(String,Class,Class,Map)}
  - {@link oaj.ObjectMap#getList(String,Class,List) getList(String,Class,List)}
- New methods on {@link oaj.utils.PojoRest}:
  - {@link oaj.utils.PojoRest#get(String,Class) get(String,Class)}
  - {@link oaj.utils.PojoRest#get(String,Type,Type...) get(String,Type,Type...)}
  - {@link oaj.utils.PojoRest#getWithDefault(String,Object) getWithDefault(String,Object)}
  - {@link oaj.utils.PojoRest#getWithDefault(String,Object,Class) getWithDefault(String,Object,Class)}
  - {@link oaj.utils.PojoRest#getWithDefault(String,Object,Type,Type...) getWithDefault(String,Object,Type,Type...)}
- Fixed bug where {@link oaj.BeanSession#getMediaType()} wasn't returning a value.
- Eliminated the @Consumes and @Produces annotations.
  The supported media types are now passed in through the constructors.
  This was changed to eliminate a performance issue where a field could not be set as final because the call to getClass() to retrieve the annotation value could not be called before calling the super() method.
- New class: {@link oaj.utils.PojoMerge}
- New doc: 2.6.2 - @Pojo annotation
- New doc: 2.6.5 - Serializing Readers and InputStreams

##### juneau-dto

- {@link oaj.dto.html5.HtmlElementMixed#children(Object...)} can now take in collections of objects.
- The DTO beans can now be serialized to strings of their typical language by calling the toString() method.
  For example, Swagger.toString() produces JSON and the HTML5 Form.toString() produces HTML.

##### juneau-rest-server

- Revamped and simplified servlet and REST-call lifecycle handling through new {@link oajr.annotation.RestHook @RestHook} annotation.
  - The {@link oajr.RestServlet#init(ServletConfig)} method is now final and can no longer be extended.
    Instead, use {@link oajr.annotation.HookEvent#INIT} or {@link oajr.annotation.HookEvent#POST_INIT} for initialization.
  - The following methods on {@link oajr.RestServlet} have been removed:
    - init(RestConfig) - Use {@link oajr.annotation.HookEvent#INIT} instead.
    - onSuccess(RestRequest, RestResponse, long) - Use {@link oajr.annotation.HookEvent#END_CALL} instead.
    - onPreCall(RestRequest) - Use {@link oajr.annotation.HookEvent#PRE_CALL} instead.
    - onPostCall(RestRequest, RestResponse) - Use {@link oajr.annotation.HookEvent#POST_CALL} instead.
- Simplified {@link oajr.widget.MenuItemWidget}.
  Exposes an abstract method getContent(RestRequest) that can return raw HTML via readers or char-sequences, or any other object (such as HTML5 beans) that will get converted to HTML using {@link oaj.html.HtmlSerializer#DEFAULT}.
- {@link oajr.RestResourceResolver} instances are now inherited from parent resources to child resources unless explicitly overridden at the child level.
  It's also been changed to an interface.
- New annotations on @RestResource:
  - resourceResolver()
    Allows you to specify a resource resolver on the servlet context to make it easier to work with dependency injection frameworks.
  - contextPath() -
    Allows you to override the context path value inherited from the servlet container.
  - allowHeaderParams() -
    Replaces the RestContext.REST_allowHeaderParams setting.
  - allowMethodParam() -
    Replaces the RestContext.REST_allowMethodParam setting.
  - allowBodyParam() -
    Replaces the RestContext.REST_allowBodyParam setting.
  - renderResponseStackTraces() -
    Replaces the RestContext.REST_xxx setting.
  - useStackTraceHashes() -
    Replaces the RestContext.REST_useStackTraceHashes setting.
  - defaultCharset() -
    Replaces the RestContext.REST_defaultCharset setting.
  - paramFormat() -
    Replaces the RestContext.REST_paramFormat setting.
- New annotations on {@link oajr.annotation.RestMethod @RestMethod}:
  - {@link oajr.annotation.RestMethod#defaultCharset() defaultCharset()} -
    Replaces the RestContext.REST_defaultCharset setting.
  - RestMethod.paramFormat() -
    Replaces the RestContext.REST_paramFormat setting.
- The following implementation classes can now be defined as non-static inner classes of servlets/resources:
  - {@link oajr.widget.Widget}
  - {@link oajr.RestConverter}
  - {@link oajr.RestGuard}
  - {@link oajr.ResponseHandler}
  - {@link oajr.RestCallHandler}
  - {@link oajr.RestInfoProvider}
  - {@link oajr.RestResourceResolver}
  - {@link oajr.RestLogger}
  - {@link oaj.html.HtmlDocTemplate}
- New tooltip template: {@link oajr.widget.Tooltip}
- New dark theme:
- Stylesheet selection now stored in HTTP session when passed in via ?stylesheet query parameter.
- New doc: Lifecycle Hooks
- Eliminated the RestServletJenaDefault class to remove the Jena dependency class on the juneau-rest-server artifact.
  It's simple enough to simply extend BasicRestServlet and add the RDF serializers and parsers.

##### juneau-microservice

- The microservice has been significantly modified to be configured via a jetty.xml file for maximum flexibility instead of the hodge-podge of support in the config file.
  Top-level servlets should now be defined in the provided jetty.xml file.
- New methods on RestMicroservice:
  - addServlet(Servlet,String)
  - addServletAttribute(String,Object)
  - getServer()
  - getInstance()
  - getPort()
  - getContextPath()
  - getProtocol()
  - getHostName()
- New methods on {@link oaj.microservice.Microservice}:
  - {@link oaj.microservice.Microservice#getInstance() getInstance()}
- New class JettyLogger for directing Jetty logging to the java.util.logging framework.
- New class DebugResource for viewing and generating Jetty thread dumps through REST calls.

##### org.apache.juneau.rest.examples

- New example of adding a menu-item widget to the Pet Store resource (including tooltips):