Apache Juneau™ is a single cohesive Java ecosystem consisting of the following parts:

juneau-core juneau-marshall POJO marshalling support for JSON, JSON5, XML, HTML, URL-encoding, UON, MessagePack, and CSV using no external module dependencies.
juneau-marshall-rdf Extended marshalling support for RDF/XML, N3, N-Tuple, and Turtle.
juneau-dto A variety of predefined DTOs for serializing and parsing languages such as HTML5, Swagger and ATOM.
juneau-config A sophisticated configuration file API.
juneau-assertions A fluent assertions API.
juneau-rest juneau-rest-server A universal REST server API for creating Swagger-based self-documenting REST interfaces using POJOs, simply deployed as one or more top-level servlets in any Servlet 3.1.0+ container.
juneau-rest-server-springboot Spring Boot integration.
juneau-rest-client A universal REST client API for interacting with Juneau or 3rd-party REST interfaces using POJOs and proxy interfaces.

Questions via email to dev@juneau.apache.org are always welcome.

Juneau is packed with features that may not be obvious at first. Users are encouraged to ask for code reviews by providing links to specific source files such as through GitHub. Not only can we help you with feedback, but it helps us understand usage patterns to further improve the product.


The juneau-marshall and juneau-marshall-rdf modules provides memory-efficient typed and untyped POJO serializing and parsing for a variety of languages.

// A simple bean public class Person { public String name = "John Smith"; public int age = 21; } // Produces: // "{"name":"John Smith","age":21}" String json = Json.of(new Person()); // Parse back into a bean. Person person = Json.to(json, Person.class); // Various other languages. String json5 = Json5.of(person); String xml = Xml.of(person); String html = Html.of(person); String urlEncoding = UrlEncoding.of(person); String uon = Uon.of(person); String openApi = OpenApi.of(person); String rdfXml = RdfXml.of(person); String rdfXmlAbbriev = RdfXmlAbbrev.of(person); String n3 = N3.of(person); String nTriple = NTriple.of(person); String turtle = Turtle.of(person); String plainText = PlainText.of(person); String csv = Csv.of(person); byte[] msgPack = MsgPack.of(person);

The juneau-rest-server and juneau-rest-client libraries provide server and client side REST capabilities that can be used by themselves, or together to create simplified yet sophisticated Java-based REST communications layers that completely hide away the complexities of the REST protocol from end-users.

// Server-side endpoint @Rest(path="/petstore") public class PetStoreRest extends BasicRestServlet implements BasicUniversalConfig { @RestPost(path="/pets", guards=AdminGuard.class) public Ok addPet( @Content CreatePet createPetBean, @Header("E-Tag") UUID etag, @Query("debug") boolean debug ) throws BadRequest, Unauthorized, InternalServerError { // Process request here. return Ok.OK; // Standard 400-OK response. } }

// Client-side Java interface that describes the REST endpoint @Remote(path="/petstore") public interface PetStoreClient { @RemotePost("/pets") Ok addPet( @Content CreatePet createPet, @Header("E-Tag") UUID etag, @Query("debug") boolean debug ) throws BadRequest, Unauthorized, InternalServerError; }

// Use a RestClient with default JSON 5 support and BASIC auth. RestClient client = RestClient.create().json5().basicAuth(...).build(); // Instantiate our proxy interface. PetStoreClient store = client.getRemote(PetStoreClient.class, "http://localhost:10000"); // Use it to create a pet. CreatePet createPet = new CreatePet("Fluffy", 9.99); Pet pet = store.addPet(createPet, UUID.randomUUID(), true);

The juneau-dto module contains several predefined POJOs for generating commonly-used document types that are designed to be used with the Juneau Marshaller APIs for both serializing and parsing. For example, you can build HTML DOMs in Java.

import static org.apache.juneau.dto.html5.HtmlBuilder.*; // An HTML table Object mytable = table( tr( th("c1"), th("c2") ), tr( td("v1"), td("v2") ) ); String html = Html.of(mytable);

<table> <tr> <th>c1</th> <th>c2</th> </tr> <tr> <td>v1</td> <td>v2</td> </tr> </table>

The juneau-config module contains a powerful API for creating and using INI-style config files.

# A set of entries [Section1] # An integer key1 = 1 # A boolean key2 = true # An array key3 = 1,2,3 # A POJO key4 = http://bar

// Create a Config object Config config = Config.create().name("MyConfig.cfg").build(); // Read values from section #1 int key1 = config.getInt("Section1/key1"); boolean key2 = config.getBoolean("Section1/key2"); int[] key3 = config.getObject("Section1/key3", int[].class); URL key4 = config.getObject("Section1/key4", URL.class);

The juneau-assertions module in Juneau is a powerful API for performing fluent style assertions.

import static org.apache.juneau.assertions.Assertions.*; // Check the contents of a string. // "as" methods perform a transformation. // "is" methods perform an assertion. assertString("foo, bar") .asSplit(",") .asTrimmed() .is("foo", "bar"); // Extract a subset of properties from a list of beans and compare using Simplified JSON. List<MyBean> myListOfBeans = ...; assertBeanList(myListOfBeans) .asPropertyMaps("a,b") .asJson().is("[{a:1,b:'foo'}]");

The juneau-rest-springboot modules provides servlets for quickly and seemlessly deploying REST endpoints in a Spring Boot application. Has built-in support for auto-generated Swagger documentation and call statistics on all endpoints.

@SpringBootApplication @Controller public class App { //Entry point method. public static void main(String[] args) { new SpringApplicationBuilder(App.class).run(args); } // Our root REST bean. // Note that this must extend from SpringRestServlet to allow use of injection. // All REST objects are attached to this bean using the Rest.children() annotation. @Bean public RootResources getRootResources() { return new RootResources(); } // Registers our REST bean at the URI root. @Bean public ServletRegistrationBean<Servlet> getRootServlet(RootResources rootResources) { return new ServletRegistrationBean<>(rootResources, "/*"); } // Injected child resource. @Bean public HelloWorldResource getHelloWorldResource() { return new HelloWorldResource(); } // Injected child bean used in injected child resource. @Bean public HelloWorldMessageProvider getHelloWorldMessageProvider() { return new HelloWorldMessageProvider("Hello Spring injection user!"); } }

Our root resource servlet serves as a router page. It is defined as follows:

@Rest( title="Root resources", description="Example of a router resource page.", children={ HelloWorldResource.class, } ) @HtmlDocConfig( widgets={ ContentTypeMenuItem.class }, navlinks={ "api: servlet:/api", "stats: servlet:/stats", "$W{ContentTypeMenuItem}", "source: $C{Source/gitHub}/org/apache/juneau/examples/rest/$R{servletClassSimple}.java" }, aside={ "<div class='text'>", " <p>This is an example of a 'router' page that serves as a jumping-off point to child resources.</p>", " <p>Resources can be nested arbitrarily deep through router pages.</p>", " <p>Note the <span class='link'>API</span> link provided that lets you see the generated swagger doc for this page.</p>", " <p>Also note the <span class='link'>STATS</span> link that provides basic usage statistics.</p>", " <p>Also note the <span class='link'>SOURCE</span> link on these pages to view the source code for the page.</p>", " <p>All content on pages in the UI are serialized POJOs. In this case, it's a serialized array of beans with 2 properties, 'name' and 'description'.</p>", " <p>Other features (such as this aside) are added through annotations.</p>", "</div>" }, asideFloat="RIGHT" ) public class RootResources extends BasicSpringRestServletGroup implements BasicUniversalConfig { // No code! }

HTML representation

The HelloWorldResource class shows an example of a child resource defined as an injected bean.

@Rest( title="Hello World", description="An example of the simplest-possible resource", path="/helloWorld" ) @HtmlDocConfig( aside={ "<div style='max-width:400px' class='text'>", " <p>This page shows a resource that simply response with a 'Hello world!' message</p>", " <p>The POJO serialized is a simple String.</p>", "</div>" } ) public class HelloWorldResource extends BasicRestObject implements BasicUniversalConfig { @Inject private HelloWorldMessageProvider messageProvider; @RestGet(path="/*", summary="Responds with injected message") public String sayHello() { return messageProvider.get(); } }

HTML representation

Other features: