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 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 Surrogate interface for identifying surrogate classes.
- Serializers can now serialize to {@link java.lang.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.
- PojoSwap.swap(BeanSession,Object)and PojoSwap.unswap(BeanSession,Object,ClassMeta) can now throw arbitrary exceptions instead of having to wrap them in SerializeException/ParseException.
- New CalendarUtils class that encapsulates serialization/parsing logic from CalendarSwapand DateSwap.
- New annotation {@link oaj.html.annotation.Html#anchorText}.
- New methods on ObjectList:
  - ObjectList.get(int,Class) get(int,Class)
  - oaj.ObjectList.get(int,Type,Type...) get(int,Type,Type...)
  - ObjectList.getMap(int,Class,Class) getMap(int,Class,Class)
  - ObjectList.getList(int,Class) getList(int,Class)
- New methods on ObjectMap:
  - ObjectMap.get(String,Class) get(String,Class)
  - oaj.ObjectMap.get(String,Type,Type...) get(String,Type,Type...)
  - ObjectMap.getWithDefault(String,Object) getWithDefault(String,Object)
  - ObjectMap.getWithDefault(String,Object,Class) getWithDefault(String,Object,Class)
  - oaj.ObjectMap.getWithDefault(String,Object,Type,Type...) getWithDefault(String,Object,Type,Type...)
  - ObjectMap.getSwapped(String,PojoSwap) getSwapped(String,PojoSwap)
  - ObjectMap.getAt(String,Class) getAt(String,Class)
  - oaj.ObjectMap.getAt(String,Type,Type...) getAt(String,Type,Type...)
  - ObjectMap.getMap(String,Class,Class,Map) getMap(String,Class,Class,Map)
  - ObjectMap.getList(String,Class,List) getList(String,Class,List)
- New methods on PojoRest:
  - PojoRest.get(String,Class) get(String,Class)
  - oaj.utils.PojoRest.get(String,Type,Type...) get(String,Type,Type...)
  - PojoRest.getWithDefault(String,Object) getWithDefault(String,Object)
  - PojoRest.getWithDefault(String,Object,Class) getWithDefault(String,Object,Class)
  - 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: 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 @RestHookannotation.
  - The RestServlet.init(ServletConfig)method is now final and can no longer be extended.
    Instead, use HookEvent.INIT or HookEvent.POST_INIT for initialization.
  - The following methods on RestServlet have been removed:
    - init(RestConfig) - Use HookEvent.INIT instead.
    - onSuccess(RestRequest, RestResponse, long) - Use HookEvent.END_CALL instead.
    - onPreCall(RestRequest) - Use HookEvent.PRE_CALL instead.
    - onPostCall(RestRequest, RestResponse) - Use 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}.
- 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 RestMethod @RestMethod:
  - 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}
  - RestConverter
  - RestGuard
  - ResponseHandler
  - RestCallHandler
  - RestInfoProvider
  - RestResourceResolver
  - 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 DebugResourcefor 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):