Professional Documents
Culture Documents
ENTERPRISE JAVA
JULY/AUGUST 2016
17 25 31 37
JSF 2.3 JASPIC JSON-P JAVAMAIL
WHATS AUTHENTICATION PROCESS DATA AUTOMATE
COMING? FOR CONTAINERS EASILY ALERTS FROM
JAVA EE APPS
ORACLE.COM/JAVAMAGAZINE
//table of contents /
25 31 37
CUSTOM SERVLET USING THE JAVA APIS USING JAVAMAIL IN
AUTHENTICATION FOR JSON PROCESSING JAVA EE
USING JASPIC By David Delabasse By T. Lamine Ba
By Steve Millidge Two easy-to-use APIs greatly Create web applications that
A little-known Java EE simplify handling JSON data. can send emails.
standard makes it simple to
enforce authentication using
17 your preferred resources.
04 13 56 71
From the Editor Java Books New to Java Fix This
Writing small classes is a universally Review of Building Maintainable Software Generics: The Hard Parts By Simon Roberts
prescribed best practice. While simple in By Michael Klling Our latest code challenges
concept, on real projects this presents its 43 Wildcards, subtyping, and type erasure
Java 9 61
own diiculties.
JShell: Read-Evaluate-Print Loop 62 Java Proposals of Interest
06 for the Java Platform JVM Languages JEP 282 jlink: The Java Linker
Letters to the Editor By Constantin Drabo JRuby 9000: Beautiful 70
Comments, questions, suggestions, Testing code snippets will be part of the Language, Powerful Runtime
and kudos
User Groups
upcoming JDK. By Charles Nutter
Bucharest JUG
09 A simple language that inspired Ruby on
49 Rails facilitates complex Java coding. 76
Events New to Java Contact Us
Upcoming Java conferences and events Modern Java I/O Have a comment? Suggestion?
By Benjamin Evans and David Flanagan
11 Want to submit an article
JavaOne 2016 NIO.2 makes many things easier, includ- proposal? Heres how.
The worlds largest Java conference ing monitoring directories for changes.
01
ORACLE.COM/JAVAMAGAZINE /////////////////////////////////////////// JULY/AUGUST 2016
EDITORIAL PUBLISHING
Editor in Chief Publisher
Andrew Binstock Jennifer Hamilton +1.650.506.3794
Managing Editor Associate Publisher and Audience
Claire Breen Development Director
Copy Editors Karin Kinnear +1.650.506.1985 September 1822, 2016 | San Francisco
Karen Perkins, Jim Donahue Audience Development Manager oracle.com/javaone
Technical Reviewer Jennifer Kurtz
Stephen Chin
ADVERTISING SALES
DESIGN Sales Director
REGISTER NOW
Senior Creative Director Tom Cometa
Francisco G Delgadillo Account Manager
Design Director Mark Makinney
Richard Merchn Account Manager
Senior Designer Marcin Gamza
Arianna Pucherelli
Designer
Jaime Ferrand
Advertising Sales Assistant
Cindy Elhaj +1.626.396.9400 x 201 Respond Early, Save $400*
Mailing-List Rentals
Senior Production Manager Contact your sales representative.
Sheila Brennan
Production Designer
Kathy Cygnarowicz RESOURCES
Oracle Products
+1.800.367.8674 (US/Canada)
Oracle Services
+1.888.283.0591 (US) Learn about Java 9 and beyond
450+ educational sessions
ARTICLE SUBMISSION
Explore innovations at the Java Hub
If you are interested in submitting an article, please email the editors.
Network with 500+ Java experts
SUBSCRIPTION INFORMATION
Subscriptions are complimentary for qualified individuals who complete the
subscription form.
MAGAZINE CUSTOMER SERVICE
java@halldata.com Phone +1.847.763.9635
PRIVACY Innovation Sponsor Diamond Sponsor
Oracle Publishing allows sharing of its mailing list with selected third parties. If you prefer
that your mailing address or email address not be included in this program, contact
Customer Service. Gold Sponsor Silver Sponsors
Copyright 2016, Oracle and/or its affiliates. All Rights Reserved. No part of this publication may be reprinted or otherwise
reproduced without permission from the editors. JAVA MAGAZINE IS PROVIDED ON AN AS IS BASIS. ORACLE EXPRESSLY Bronze Sponsors
DISCLAIMS ALL WARRANTIES, WHETHER EXPRESS OR IMPLIED. IN NO EVENT SHALL ORACLE BE LIABLE FOR ANY
DAMAGES OF ANY KIND ARISING FROM YOUR USE OF OR RELIANCE ON ANY INFORMATION PROVIDED HEREIN. Opinions
expressed by authors, editors, and intervieweeseven if they are Oracle employeesdo not necessarily reflect the views of Oracle.
The information is intended to outline our general product direction. It is intended for information purposes only, and may not
be incorporated into any contract. It is not a commitment to deliver any material, code, or functionality, and should not be relied
upon in making purchasing decisions. The development, release, and timing of any features or functionality described for Oracles
products remains at the sole discretion of Oracle. Oracle and Java are registered trademarks of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective owners.
Java Magazine is published bimonthly and made available at no cost to qualified subscribers by * Save $400 over onsite registration. Visit oracle.com/javaone/register for early bird registration dates and details.
Oracle, 500 Oracle Parkway, MS OPL-3A, Redwood City, CA 94065-1600. Copyright 2016, Oracle and/or its affiliates. All rights reserved. Oracle and Java are registered
trademarks of Oracle and/or its affiliates. Other names may be trademarks of their respective owners.
02
ORACLE.COM/JAVAMAGAZINE ////////////////////////////////////////// JULY/AUGUST 2016
//from the editor /
Erratum
In the May/June issue, in Mr. Kllings article
[Understanding Generics, page 45], he several times
uses HashSet() in his code examples. But I believe
that he meant to use HashMap(), which will actually
work in the code he presents.
Bibhaw Kumar
Contact Us
We welcome comments, suggestions, grumbles,
kudos, article proposals, and chocolate chip cookies.
All but the last two might be edited for publication.
If your note is private, indicate this in your message.
Write to us at javamag_us@oracle.com. For other
ways to reach us, see the last page of this issue.
08
ORACLE.COM/JAVAMAGAZINE /////////////////////////////////////////// JULY/AUGUST 2016
//events /
JVM Language Summit ably. Subject matter is aimed
AUGUST 13 at software developers, engi-
SANTA CLARA, CALIFORNIA neers, project managers, qual-
The JVM Language Summit is ity assurance specialists, and
an open technical collabora- test managers. Participants get
tion among language design- both one-on-one interaction
ers, compiler writers, tool with instructors and opportu-
builders, runtime engineers, nities to network with other
and architects who target the software professionals.
JVM. This years event will be
held in Oracles auditorium. JavaZone
Presentations will run in a SEPTEMBER 68
single track and are allotted 45 OSLO, NORWAY
minutes each (including ques- This year marks the 15th
tions). Workshop sessions will anniversary of JavaZone. The
run for 60 minutes, with two event consists of a day of
or more sessions in parallel. workshops followed by two
Breakfast and lunch are served days of presentations and
onsite. Breakout rooms are more workshops. Last years
available for workshops, con- event drew more than 2,500
versation, and ad hoc consul- attendees and featured 150
tations. Presentations will be talks covering a wide range of
recorded and made available to Java-related topics.
JavaOne SEPTEMBER 1822
SAN FRANCISCO, CALIFORNIA the public.
JDK IO
The ultimate Java gathering celebrates its 20th year. JavaOne features
DevOps Week DC SEPTEMBER 1315
hundreds of sessions and hands-on labs. Topics covered include the core
AUGUST 1519 COPENHAGEN, DENMARK
Java platform, security, DevOps, IoT, scalable services, and development
WASHINGTON DC This annual event hosted by
tools. Georges Saab, vice president of development for the Java Platform
DevOps Week features a series the Danish Java User Group
Group at Oracle and chair of the OpenJDK governing board, and Mark
of specialized courses designed consists of a two-day confer-
Reinhold, chief architect of the Java Platform Group, are slated to speak
to help organizations create ence followed by one day of
at the event, as are many members of the Java development team. Highly
an environment where the workshops. The focus is on all
anticipated Java 9 release enhancements will be presented and discussed.
building, testing, and releas- things Java: the language, the
(See page 11 for more information.)
ing of software can happen platform, the frameworks, and
more rapidly and more reli- the virtual machine.
PHOTOGRAPH BY ERIC E CASTRO/FLICKR
09
ORACLE.COM/JAVAMAGAZINE ////////////////////////////////////////// JULY/AUGUST 2016
//events /
Architecture Conference is explor- W-JAX
ing evolutionary architecture to NOVEMBER 711
relect the broadening of the ield, MUNICH, GERMANY
encompassing new disciplines W-JAX is a conference focused
such as DevOps. Topics include on Java, architecture, and soft-
strategies for meeting business ware innovation. More than 160
goals, developing leadership presentations on technologies
skills, and making the conceptual and languages ranging from Java,
jump from software developer Scala, and Android, to web pro-
to architect. gramming, agile development
models, and DevOps are planned.
VOXXED Days THESSALONIKI The main conference takes place
OCTOBER 21 November 810, with workshops
THESSALONIKI, GREECE scheduled on November 7 and 11.
The inaugural VOXXED Days (No English page available.)
event in Thessaloniki is a devel-
oper conference that promises
expert speakers, core developers Special Note: Event Cancellation
of popular open source technolo- QCon Rio
gies, and professionals willing to OCTOBER 57
Strange Loop ence for cutting-edge software share their knowledge and experi- RIO DE JANEIRO, BRAZIL
SEPTEMBER 1517 engineers and enterprise-level ences. Former Oracle Technology The organizers report: Faced
ST. LOUIS, MISSOURI professionals, bringing together Evangelist Simon Ritter is with an unstable political and
Strange Loop is a multidisciplin- the worlds leading innovators in scheduled to present JDK 9: Big economic environment . . . we
ary conference that brings the ields of Java, microservices, Changes to Make Java Smaller. considered it prudent to cancel our
together developers and think- continuous delivery, and DevOps. edition of QCon 2016. We empha-
ers in ields such as emerging Hands-on workshops take place Devoxx size that this decision does not
languages, alternative databases, on October 10, followed by confer- NOVEMBER 711 afect the preparation of QCon
concurrency, distributed systems, ence sessions, keynotes, and expo. ANTWERP, BELGIUM So Paulo 2017.
security, and the web. Devoxx is one of the largest
OReilly Software Architecture mostly Java conferences in the Have an upcoming conference
JAX London Conference world, with numerous experts youd like to add to our listing?
OCTOBER 1012 OCTOBER 1921 from the US and Europe present- Send us a link and a description of
LONDON, ENGLAND LONDON, ENGLAND ing a wide range of sessions on all your event four months in advance
JAX London is a three-day confer- This year, the OReilly Software aspects of Java development. at javamag_us@oracle.com.
PHOTOGRAPH BY CCHANA/FLICKR
10
ORACLE.COM/JAVAMAGAZINE ////////////////////////////////////////// JULY/AUGUST 2016
//conference /
JavaOne 2016
The largest Java conference is again a must-attend event.
There are many books available level of expertise to be qualiied for each guideline for code that
on writing good code. They dig as authors: practitioners of soft- aims to be in the topmost tier
into a bag of well-known tips ware engineering, the discipline of quality. For example, on the
and recommendations that are that quantiies software devel- rule against redundant code, the
aimed at beginner and interme- opment via analysis of thousands authors state that their model
diate programmers. The prob- of projects from all areas of allows no more than 4.6 percent
lem with some of these books programming. The problem is of lines of code to be redundant.
is that its hard to tell how the that most software engineering Thats helpful data, and it under-
authors are qualiied to dole experts dont examine coding scores the fact that guidelines
out their advice. Most authors style and so, as a ield, theyve cannot always be followed 100
of these texts are consultants, said relatively little on the topic. percent of the time. Ill come
which suggests that they see a The principal author of this book back to this in a moment.
wide range of code. However, and his colleagues come close Each guideline is presented, its
most consultants work within to this level of qualiication, raison dtre explained, its appli-
a narrow range of industries though. For 15 years, theyve cation demonstrated, and the
and dont often stray into areas run the Software Improvement counterarguments to it contested.
where programming is done Group, which studies software This last part is an imaginative
substantially diferently. For quality quantitatively based in addition that targets the reasons
example, can authors credibly part on coding style. developers tell themselves for not
discuss rules for testability if From this work, they came obeying a guideline.
theyve never written software up with 10 guidelines, most of The examples chosen for each
that could cost lives when errors which will be familiar (write guideline contain problematic
occur? Can authors who have no small units of code, use loose code and show the resolution,
experience proving code correct coupling, automate tests, and so frequently relying on tried-and-
speak with authority on writing on). They present them in the true techniques. For example,
correct code? context of a prescriptive model to reduce duplicate code, the
One group of professionals of maintainability, which has authors wisely suggest using
comes close to meeting the high strict numerical requirements the Extract Method and Extract
13
ORACLE.COM/JAVAMAGAZINE ////////////////////////////////////////// JULY/AUGUST 2016
//java books /
Get Java
Superclass refactorings. These values in a switch are no longer
examples are useful although not enforced in a HashMap. (Adding
suiciently numerous to be a guide objects with the same key to a
for readers who are keen to imple- HashMap simply overwrites exist-
ment the suggestions fully. (For ing entries without any error.) The
that, I recommend Martin Fowlers
classic, Refactoring.)
Some implementation sugges-
tions strike me as dubious. For
example, in the chapter on
solution is also weak because if
we handle the lags of, say, Africa,
surely writing by hand 54 classes
is more complex than one large
switch statement. The proposed
Certified
avoiding complexitywhich is
measured solely via cyclomatic
approach also shows a lack of
understanding of enums in Java,
Oracle University
complexitythe authors unwisely which are full classes and guaran-
dig into the switch statement. The teed to maintain the unique keys.
switch construct is a known weak- In addition, by using an enum dec-
ness in the cyclomatic complexity laration, all 54 classes for African
measure, which greatly overesti- lags are generated by the compiler.
Upgrade & Save 35%*
mates its complexity. In an exam- And the EnumMap gives you the data
ple of associating colors with the structure you want.
lags of six European nations, the Although I wish the book more
authors try to prove that a forgot- thoroughly explored topics and Get noticed by hiring managers
ten break statement in the six-way I have quibbles with some of the
switch is the result of complexity. proposed solutions, the overall Learn from Java experts
Problems that arise from complex- level of this work is better than
ity are generally the inability to many other volumes that advise Join online or in the classroom
understand code and how to ix how code should be written. It
it, rather than an omission that certainly can be recommended to
Connect with our Java
is detected by all code analyzers. beginners and early intermediate
The authors suggest that the ideal programmers and those whose
certification community
solution is to create six separate work shows a repeated problem in
classesone for each country code reviews. Andrew Binstock
instantiate each one, and put the
Save 35% when you upgrade or advance your existing Java certification. Offer expires December 31, 2016. Click for further details, terms, and conditions.
For a reusable validator, such as @Email, which can be applied private List<String> inputs;
to many diferent ields in diferent beans, this work is surely
worth it. Multicomponent validation for backing beans is, public void
however, often more ad hoc, and for a one-of validation case initialize(ValidateEqual constraintAnnotation) {
for a single bean, the number of moving parts is perhaps a bit this.inputs =
too much. asList(constraintAnnotation.inputs());
Alternatively, a library of somewhat more-reusable valida- }
tors can be createdfor example, the bean validation coun-
terparts of the OmniFaces multicomponent validators such as public boolean
validateEqual, validateOneOrMore, validateOneOrNone, and isValid(Object bean,
so on. ConstraintValidatorContext ctx) {
To contrast with the example above, Ill show an example return new
of a reusable validateEqual validator that uses an EL-enabled HashSet<>(collectValues(bean, inputs))
attribute to specify the bean properties that should be vali- .size() == 1;
dated. Note that using EL for this is just an example and there }
are certainly other feasible options, such as marking the }
properties with annotations.
Ill irst deine the validation annotation, this time This validator works by leveraging the platform-provided
separately: ELProcessor from the EL 3.0 spec to easily obtain the prop-
erty values from the bean that is being validated. This is
@Constraint(validatedBy = ValidateEqualValidator.class) done as follows:
20
ORACLE.COM/JAVAMAGAZINE /////////////////////////////////////////// JULY/AUGUST 2016
//enterprise java /
public static List<Object> collectValues(Object bean) { @Named
ELProcessor elProcessor = getElProcessor(bean); @RequestScoped
@ValidateEqual(
return inputs.stream() groups = RandomAccess.class,
.map(input -> elProcessor.eval(input)) inputs={"this.foo", "this.bar"})
.collect(toList()); public class IndexBean {
} @NotNull
private String foo;
A fully functional ELProcessor for usage in a Java EE environ- @NotNull
ment can be obtained by just instantiating a new instance, private String bar;
and then providing it with the ELResolver from the CDI bean // + getter/setters
manager. This can be done as shown below: }
public static ELProcessor getElProcessor(Object bean) { Note here that the inputs attribute is initialized with EL refer-
ELProcessor elProcessor = new ELProcessor(); ences to the two properties that should be validated together.
In both cases, the part of a Facelet containing the actual
elProcessor.getELManager() input components looks as follows:
.addELResolver(
CDI.current() 01 <h:form>
.getBeanManager() 02 <h:inputText value="#{indexBean.foo}">
.getELResolver()); 03 <f:validateBean validationGroups =
04 "javax.validation.groups.Default,
elProcessor.defineBean("this", bean); 05 java.util.RandomAccess" />
06 </h:inputText>
return elProcessor; 07
} 08 <h:inputText value="#{indexBean.bar}">
09 <f:validateBean validationGroups =
Notice, in particular, that in the getElProcessor() method, 10 "javax.validation.groups.Default,
the bean to be validated is being added to the ELProcessor 11 java.util.RandomAccess" />
context under the "this" name. This approach will be used 12 </h:inputText>
when the properties that should be validated are deined 13
shortly. (As a side note, its perhaps interesting to realize that 14 <f:validateWholeBean value="#{indexBean}"
four diferent Java EE specs are used together here rather 15 validationGroups="java.util.RandomAccess"/>
seamlessly: those for JSF, bean validation, EL, and CDI.) 16
Finally, the backing bean is annotated again, but this time 17 <h:commandButton value="submit" />
with the reusable validator: 18 </h:form>
21
ORACLE.COM/JAVAMAGAZINE /////////////////////////////////////////// JULY/AUGUST 2016
//enterprise java /
[Lines 4 and 5 are wrapped due to space constraints and The goal for extensionless URLs in JSF 2.3 is threefold:
should be entered as a single line, as are lines 10 and 11. Ed.] First, path mapping should work without an extension.
A rather important aspect of full class bean validation in For example, a URL such as http://example.com/faces/page
combination with JSF is that the bean seen by the valida- should work out of the box.
tor is a copy of the backing bean and not the actual backing Second, exact mapping should be oicially supported. For
bean. The reason for this is that the JSF validation semantics example, a URL such as http://example.com/page should
demand that the model (the backing bean) is not updated work when the following mapping is present in web.xml:
when any validation or conversion failure happens. However,
full class bean validation can happen only after the bean has <servlet>
been fully updated. To break this mismatch, the runtime <servlet-name>Faces Servlet</servlet-name>
irst makes a copy of the backing bean, updates this copy, <servlet-class>
and validates it. Only if all validation constraints pass is the javax.faces.webapp.FacesServlet
actual backing bean updated. </servlet-class>
</servlet>
Extensionless URLs <servlet-mapping>
JSF is implemented internally via a servlet, the so-called <servlet-name>Faces Servlet</servlet-name>
FacesServlet, which listens to requests that have a spe- <url-pattern>/page</url-pattern>
ciic pattern. By default, this pattern includes "/faces/*", </servlet-mapping>
"*.jsf", "*.faces", and, as of JSF 2.3, "*.xhtml". Users can
set their own pattern in web.xml using the same servlet syn- Third, the most ambitious part of the goal is that a URL
tax thats used to map any servlet to a URL pattern. such as http://example.com/page should work without
As can be seen from the information above, both path map- requiring the user to map /page (or any page) explicitly by
ping and extension mapping are supported. An example of path using exact mapping, but rather it should work by setting
mapping would be http://example.com/faces/page.xhtml, only a single coniguration option.
while an example of extension mapping would be something At press time, its not yet clear how the third goal should be
like http://example.com/page.jsf. implemented, but a possible approach would be adding a new
In modern web applications, its often desirable to have listViewResources() method to the ResourceHandler, and
clean URLsthat is, URLs that speciically dont have an then taking advantage of the Servlet 3.0 specs programmatic
extension and generally dont have any kind of clutter in mapping during application startup to automatically add
them. Unfortunately, JSF does not support such URLs out of exact mappings for all view resources (for example, Facelets)
the box. Curiously, even when you are using path mapping, an that are handled by a given ResourceHandler.
extension is still required, as shown above.
Clean URLs in JSF can be obtained by using third-party Programmatic and Annotation-Based Configuration
libraries, such as PrettyFaces or OmniFaces, but this kind of High-level declarative coniguration in JSF is done using
functionality is now deemed to be suiciently well under- either context parameters in web.xml or the dedicated
stood and mature that it qualiies for inclusion in JSF itself. faces-config.xml iles. Additionally, there are some
22
ORACLE.COM/JAVAMAGAZINE /////////////////////////////////////////// JULY/AUGUST 2016
//enterprise java /
lower-level options available, such as coniguration via the @FacesConfig(
Application class or programmatically by providing the con- stateSavingMethod = Server,
tent of a faces-config.xml ile via a callback and the XML faceletsRefreshPeriod = -1,
Document Object Model (DOM) API. projectStage = Production
Context parameters in web.xml particularly have the disad- )
vantage of consisting of mere strings (usually long ones) that public class SomeClass {
have to be looked up and can be misspelled easily. Its also
not directly possible to see what the defaults are for any given }
coniguration item.
Both web.xml and the faces-config.xml ile that resides in The intent here is to use strongly typed values where pos-
a .war iles WEB-INF folder have the shared disadvantage that sible. For example, the Server value would come from an
they cannot be read by CDI extensions and other artifacts that enumeration.
start up early in the Java EE boot process. Although it hasnt been fully worked out yet, the pro-
Finally, XML-based iles (so-called deployment descriptors) grammatic aspect might be added using EL-enabled attri-
are not particularly lexible, speciically because theres no butes, much as in the validator example shown earlier,
overall platform service in Java EE that allows placeholders in for example:
them or a way to provide conditional included iles or overlays.
Because of the above issues, its planned to provide an @FacesConfig(
annotation-based and optionally programmatic high-level stateSavingMethod = Server,
coniguration system in JSF. In its most basic form, such con- faceletsRefreshPeriodExpr =
iguration looks as follows: "this.faceletsRefreshPeriod",
projectStageExpr = "configBean.dev?
@FacesConfig 'Development' : 'Production'"
public class SomeClass { )
public class SomeClass {
} int getFaceletsRefreshPeriod() {
return ? -1 : 0;
This coniguration by itself will automatically add the JSF }
servlet mappings, which is currently done when an empty }
(but valid) faces-config.xml ile exists or when, for example,
the deprecated @ManagedBean annotation is encountered on In this example, the faceletsRefreshPeriod is set by an
any class in the application. expression that directly refers to a property of the bean on
As an alternative to the mentioned context parameters, which the annotation appears. Inside the getter method
attributes on the @FacesConfig annotation can be used to of that property, arbitrary logic can be used to determine
conigure various aspects of JSF: the desired outcome. The projectStage, however, is set
23
ORACLE.COM/JAVAMAGAZINE /////////////////////////////////////////// JULY/AUGUST 2016
//enterprise java /
by an expression that performs some logic directly in EL
itself. Although the complexity of such EL expressions can
13 Billion
be fairly high, its good practice to keep them fairly small.
Note that referencing any bean other than "this" might not
be supported for those attributes that have to be read by
CDI extensions.
Conclusion
JSF 2.3 is moving forward by using existing services from the
Java EE platform and providing glue code where necessary to
Devices Run Java
bridge gaps. In addition to that main theme, an assortment of
features will be introduced that aim to keep JSF up to date and
generally easier to use. The features presented in this article
represent a work in progress and might still change before
the inal release of JSF 2.3. More details about the features ATMs, Smartcards, POS Terminals, Blu-ray Players,
discussed here, as well as about other JSF 2.3 features, can be
Set Top Boxes, Multifunction Printers, PCs, Servers,
found on my blog. </article>
Routers, Switches, Parking Meters, Smart Meters,
Arjan Tijms is a member of the Expert Groups for JSF (JSR 372)
and the Java EE Security API (JSR 375). He is the cocreator of Lottery Systems, Airplane Systems, IoT Gateways,
the popular OmniFaces library for JSF that was a 2015 Dukes Programmable Logic Controllers, Optical Sensors,
Choice Award winner, and he is the main creator of a suite of tests
for the Java EE authentication service provider interface (JASPIC) Wireless M2M Modules, Access Control Systems,
that has been used by several Java EE vendors. [See the article Medical Devices, Building Controls, Automobiles
on JASPIC in this issue. Ed.] Tijms holds a Master of Science
degree in computer science from the University of Leiden in
the Netherlands.
#1 Development Platform
learn more
The authors blog on JSF 2.3 updates
The oicial JSF 2.3 JSR
24
ORACLE.COM/JAVAMAGAZINE /////////////////////////////////////////// JULY/AUGUST 2016
//enterprise java /
W hen you build web applications using Java EE, you often
need to work with some organization-speciic user
repository for authenticating users and obtaining a users
article, I examine an alternative solution that is tucked away
in Java EE. I expect readers to have a basic working knowledge
of Java EE and its authentication mechanisms.
groups. Typically users are deined in a speciic database, a
strange LDAP coniguration, or some other user-identity store Enter JASPIC
speciic to the project. All Java EE application servers ship with When developers design their own authentication modules,
the capability to integrate with a common set of identity stores. the Java Authentication Service Provider Interface for Con-
For example, GlassFish Server ships with several so-called tainers (JASPIC) provides an elegant solution. JASPIC has
realms: ile, LDAP, JDBC, Oracle Solaris, PAM, and certiicate. been part of Java EE since Java EE 6, but it is not well known
Each realm needs to be manually conigured, and the con- and has a reputation for being diicult to use. The goal of the
iguration is speciic to the application server and outside the JASPIC speciication is to deine, in a standard way, how the
control of your application. If the predeined realms dont authentication process occurs within a Java EE container and
it your needs, you then need to develop an application- the points within that process where custom authentication
speciic module to extend the capabilities using applica- modules for validating security messages, users, and groups
tion serverspeciic APIs. Many developers faced with this can be integrated.
prospect build some custom code in the web application, If you just download the JASPIC speciication and dive right
which integrates with their required identity store and uses in with the aim of building a compliant Server Authentication
application-speciic mechanisms to manage authentication Module (SAM), you will surely become confused and dispir-
and authorization. ited. This is because the speciication is designed to describe
The problem with this approach is that these developer- in depth what an implementer of a Java EE container has to
designed mechanisms for managing authentication are do. It also covers both client and server authentication and
not integrated with the application server, so the standard a large number of security scenarios, most of which are not
Java EE security model does not apply, the power of Java EE relevant to you.
APIs such as isUserInRole and getUserPrincipal cant be In this article, I cut through the confusion and demonstrate
used, and standard Java EE declarative security fails. In this that developing an authentication module that is well inte-
25
ORACLE.COM/JAVAMAGAZINE /////////////////////////////////////////// JULY/AUGUST 2016
//enterprise java /
grated with Java EE and comes packaged in your web applica- before it is returned to the client. The SAM is the key com-
tion is actually, barring some boilerplate code, pretty simple. ponent you need to implement to develop a custom authen-
This is because in the case of custom servlet authentication, tication provider for your web application. A SAM needs to
JASPIC provides a small proile and deines the interaction implement the JASPIC-deined interface ServerAuthModule.
between your module and the servlet containerand this Listing 1 shows the key method deinitions that need to
interaction is fairly simple. In this article, I assume that you be implemented.
are familiar with standard Java, Java Authentication and
Authorization Service (JAAS), and Java EE security concepts Listing 1.
such as principals, subjects, and callback handlers. public Class[] getSupportedMessageTypes();
The secureResponse method is called after the servlet request MessageInfo object and retrieve whatever information you
has been processed. In the case of a simple SAM for use need to use to authenticate a user.
with servlets, this method doesnt really need to contain Connect to your identity store and authenticate the user and
any speciic processing. If you need to do any postprocess- retrieve the groups associated with the user.
27
ORACLE.COM/JAVAMAGAZINE /////////////////////////////////////////// JULY/AUGUST 2016
//enterprise java /
Use the stored callback handler to pass these user and (Principal)null)
group principals to the servlet container. };
Finally, return success to the servlet container to allow the }
request to proceed to the servlet.
In Listing 6, which shows the body of my validateRequest try {
method, I retrieve the username and the users groups handler.handle(callbackArray);
directly from the servlet request parameters and use these } catch (Exception ex) {
to set up the user and group principals. Obviously this is AuthException ae =
not very secure, but it illustrates the skeleton of what needs new AuthException(ex.getMessage());
to be done. ae.initCause(ex);
}
Listing 6. return SUCCESS;
HttpServletRequest request =
(HttpServletRequest) Some key points to note about this implementation are
messageInfo.getRequestMessage(); that if you decide that the authentication is successful, the
String user = request.getParameter("user"); resulting Principals need to be passed to the container. To
String groups[] = pass Principals to the servlet container, you need to create
request.getParameterValues("group"); instances of speciic callbacks that are deined by JASPIC.
The irst is a CallerPrincipalCallback, which should be
Callback callbackArray [] = null; initialized with the clientSubject passed into your validate
if (user != null && groups != null ) { RequestMethod and a String representing your username or a
// callback used to set the user Principal custom Principal object.
Callback userCallback = The second callback is a GroupPrincipalCallback, which
new CallerPrincipalCallback( also should be initialized with the clientSubject and with
clientSubject, user); an array of Strings representing the names of the groups the
Callback groupsCallback = user belongs to or an array of custom Principals. These call-
new GroupPrincipalCallback( back handlers are then passed to the handle method of the
clientSubject,groups); handler you stored in your initialize method earlier so that
callbackArray = new Callback[] { the servlet container can initialize the Java EE caller principal
userCallback, and set up the Java EE roles.
groupsCallback}; If the authentication is not successful, you need to create a
} CallerPrincipalCallback initialized with the clientSubject
else { and a null Principal, and then pass these to the handler. This
callbackArray = new Callback[] { has the efect of letting the request proceed but with no user
new CallerPrincipalCallback( associated. Authorization security checks in the container
clientSubject, will then deny access.
28
ORACLE.COM/JAVAMAGAZINE /////////////////////////////////////////// JULY/AUGUST 2016
//enterprise java /
Therefore, you always return SUCCESS from your validate AuthConfigFactory
Request method. FAILURE should be used as a return value .getFactory()
only if there was some problem with your SAMfor example, .removeRegistration(
if you were unable to contact some external resource such as registrationid);
an LDAP server. }
}
Registering Your SAM
To deploy your custom SAM with your application, you pack- There are some additional boilerplate classes required to inte-
age the implementation classes into the WAR ile, as you grate your SAM into the JASPIC infrastructure. These classes
would for any other application classes. The JASPIC specii- are implementations of three interfaces, and they are rarely
cation deines how to register and unregister a custom SAM; diferent than the versions in the zip ile available in the Java
this can be done in a WebListener, which is called when your Magazine download area. Typically, if youre using a single
web application starts. Listing 7 shows how to register and SAM, youll use the following iles without modiication:
unregister the SAM in a WebListener. AuthConfigProvider is a factory for creating ServerAuth
Config objects.
Listing 7. ServerAuthConfig is an object that describes a conigu-
public void contextInitialized( in the general case there can be multiple SAMs, but in most
ServletContextEvent sce) { casesand in my examplethere is only one. If there are
String appContext = multiple SAMs, the ServerAuthContext implementation
registrationid = should call each in turn and then adjudicate the results.
AuthConfigFactory.getFactory() The implementation included in this article will work as
.registerConfigProvider( expected unless there are more-complex initialization and
new SimpleSAMAuthConfigProvider( coniguration requirements or there are multiple SAMs that
null,null), need to be invoked.
"HttpServlet",
appContext, Testing the Example SAM
"Simple SAM"); In my example SAM, I implemented validateRequest so
} that the user and groups were obtained from the servlet
request parameters.
public void contextDestroyed( To test the SAM, I need to deine a servlet with a security
ServletContextEvent sce) { constraint, as shown in Listing 8.
29
ORACLE.COM/JAVAMAGAZINE /////////////////////////////////////////// JULY/AUGUST 2016
//enterprise java /
up the admin role and the caller principal from the servlet
request parameters.
For this to work in your application server, you will need to
conigure role mapping in your web application for the logi-
cal role admin that is declared on your servlet to be mapped
Figure 2. Testing error message
to a server group admin. This is typically done in the appli-
cation serverspeciic deployment descriptor. In the case of
Listing 8. GlassFish, the server can be conigured to map roles auto-
@WebServlet(name = "SecureServlet", matically to the group with the same name.
urlPatterns = {"/SecureServlet"})
@DeclareRoles("admin") Conclusion
@ServletSecurity(@HttpConstraint( I encourage you to use JASPIC to build your own custom web
rolesAllowed = "admin")) application authentication modules. It is not too diicult once
public class SecureServlet extends HttpServlet { you get started and you realize that the core of the imple-
... mentation is purely in your validateRequest method of your
custom SAM. The additional support classes can be used
For this example, I implemented the servlet so that it just directly from my example project to support your SAM and
prints the caller principal: are suicient for the majority of cases. Once you have built a
SAM, you can take full advantage of the power of the stan-
out.println("User Principal is " + dard Java EE declarative security mechanisms for securing
request.getUserPrincipal().getName()); your application. </article>
If I access the servlet directly without any request parame- Steve Millidge (@l33tj4v4) is the founder and director of Payara
ters, I receive the forbidden access response from the con- Services and C2B2 Consulting. He has used Java extensively
tainer, because my SAM cannot ind the user or groups (see since version 1.0 and is a member of the Expert Groups for
Figure 2). JSR 107 (Java caching), JSR 286 (portlets), and JSR 347 (data
If I use the URLincluding a user and group admin, as in grids). He founded the London Java EE User Group and is an ardent
http://127.0.0.1:8080//jaspic-sam-example/Secure Java EE advocate. Millidge has spoken at several conferences.
Servlet?user=steve&group=adminI get the authenticated
response from the servlet (see Figure 3) because the SAM sets
30
ORACLE.COM/JAVAMAGAZINE /////////////////////////////////////////// JULY/AUGUST 2016
//enterprise java /
34
ORACLE.COM/JAVAMAGAZINE /////////////////////////////////////////// JULY/AUGUST 2016
//enterprise java /
//1. Create a streaming parser from an InputStream // no need to parse the rest of doc
URL url = new URL("http://restcountries.eu/rest/v1/all"); foundCapital = true;
try (InputStream is = url.openStream(); }
JsonParser parser = Json.createParser(is)) { break;
Conclusion
JSON-P provides a simple object model API to parse, gener-
ate, and query JSON documents. It also ofers an eicient,
lower-level API to parse and generate large JSON payloads in a
streaming way.
JSON-P is obviously not the irst Java-based JSON-related
API, but it is the irst one that has been standardized through
the Java Community Process. And given that JSON-P is now
part of Java EE, you can be sure that this API will be available
regardless of the Java EE 7 application server you are using. In
addition, JSON-P has no dependency on Java EE, so it can also
be used in regular Java SE applications. </article>
learn more
Introducing JSON
JSON object model Javadoc
JSON Stream API Javadoc
36
ORACLE.COM/JAVAMAGAZINE /////////////////////////////////////////// JULY/AUGUST 2016
//from the vault /
T. LAMINE BA
I n this article, I explain how to build a simple web application
that uses the core JavaMail API to send email. The applica-
tion includes three web pages: a front page, a sent e-mail
not plain text, including Multipurpose Internet Mail Exten-
sions (MIME), URLs, and ile attachments.
needs to be validated.
Listing 2. Accordingly, the code shown in Listing 2 accomplishes the fol-
public void validateEmail(FacesContext context, lowing tasks:
UIComponent toValidate, Object value) { It gets the local value of the web component.
String message = ""; If the value is null or empty, the method sets the compo-
String email = (String) value; nents valid property to false and sets the error message
to E-mail address is required.
if(email == null || email.equals("")) { Otherwise, the method checks whether the @ character and
tive tool that evaluates declarations, statements, and expres- In my examples in this article, the characters in blue indicate
sions of the Java programming language. text entered at the command line into JShell, and the result-
In this article, I present a brief overview of JShell, explain ing output is shown in black monospace font.
its use, and demonstrate its beneits for developers. Like Java code, JShell allows you to declare variables, meth-
ods, and classes:
Overview
JShell is a new tool in JDK 9 that ofers a basic shell for Java that int x, y , sum
uses a command-line interface. It is also the irst oicial REPL | Added variable x of type int
implementation for the Java platform, although this concept | Added variable y of type int
has existed in many languages (for example, Groovy and Lisp) | Added variable sum of type int
and in third-party tools (such as Java REPL and BeanShell).
JShell acts like a UNIX shell: it reads the instructions, eval- x = 10 ; y = 20 ; sum = x + y;
uates them, prints the result of the instructions, and then | Variable x has been assigned the value 10
displays a prompt while waiting for new commands. It is built | Variable y has been assigned the value 20
around several core conceptssnippets, state, wrapping, Variable sum has been assigned the value 30
instruction modiication, forward references, and snippet
dependenciesthat I explain. System.out.println("Sum of " + x + " and " + y +
A snippet corresponds to an instruction that is based on " = " + sum);
Java Language Speciication (JLS) syntax. It represents a Sum of 10 and 20 = 30
single expression, statement, or declaration. What follows is
a simple snippet. When you enter the snippet into JShell, the And now, heres an example of a valid class, which I use
line below is displayed by the REPL: later:
43
ORACLE.COM/JAVAMAGAZINE /////////////////////////////////////////// JULY/AUGUST 2016
//java 9 /
class Student { The indentation, of course, looks diferent than in Java,
private String name ; because this code was typed at the JShell command line.
private String classRoom ; Note that some normal Java statements are not allowed at
private double grade ; this initial declaration. The only permitted class modiier is
abstract. Packages are not allowed. Even public wont work:
public Student() {
public class University {
} Student student = new Student();
}
public String getName() { | Warning:
return name ; | Modifier 'public' not permitted in top-level
} declarations, ignored
| public class University {
public void setName(String name) { | ^----^
this.name = name ; | Added class University
}
State. Each statement in JShell has a state. The state deines
public String getClassRoom() { the execution status of snippets and of variables. It is deter-
return classRoom ; mined by results of the eval() method of the JShell instance,
} which evaluates code. There are seven status states:
DROPPED: The snippet is inactive.
public void setClassRoom(String classRoom) { NONEXISTENT: The snippet is inactive because it does not
public void setGrade(double grade) { tion snippet with potentially recoverable unresolved refer-
ences or other issues. (I discuss the diference between this
this.grade = grade ; and the previous state shortly.)
} REJECTED: The snippet is inactive because it failed com-
ByteBuffer b = ByteBuffer.allocateDirect(65536); The single value form also supports a form used for absolute
ByteBuffer b2 = ByteBuffer.allocate(4096); positioning within the bufer:
try { One drawback of this API is that this will only return elements
WatchService watcher = that match according to glob syntax, which is sometimes
FileSystems.getDefault().newWatchService(); insuiciently lexible. We can go further by using the new
Files.find and Files.walk methods to address each element
Path dir = obtained by a recursive walk through the directory:
FileSystems.getDefault().getPath("/home/ben");
WatchKey key = final Pattern isJava = Pattern.compile(".*\\.java$");
dir.register(watcher, final Path homeDir = Paths.get("/Users/ben/projects/");
StandardWatchEventKinds.ENTRY_CREATE, Files.find(homeDir, 255,
StandardWatchEventKinds.ENTRY_MODIFY, (p, attrs) -> isJava.matcher(p.toString()).find())
StandardWatchEventKinds.ENTRY_DELETE); .forEach(
q -> {System.out.println(q.normalize());});
while(!shutdown) {
key = watcher.take(); It is possible to go even further and construct advanced solu-
for (WatchEvent<?> event: key.pollEvents()) { tions based on the FileVisitor interface in java.nio.file,
Object o = event.context(); but that requires the developer to implement all four meth-
if (o instanceof Path) { ods on the interface rather than just using a single lambda
System.out.println("Path altered: "+ o); expression as done here.
} In sum, you can see that the NIO.2 library provides a lot of
} useful functionality and saves you a lot of code. If youre still
key.reset(); working with preJava 7 ile handling, youre doing far more
} work than necessary. </article>
}
This article was adapted with permission from Java in a Nutshell,
By contrast, the directory streams provide a view into all iles by Benjamin Evans and David Flanagan.
currently in a single directory. For example, to list all the Java
source iles and their size in bytes, we can use code like Benjamin Evans is the cofounder of jClarity, a Java Champion and
Rock Star, and a frequent contributor to Java Magazine. David
try(DirectoryStream<Path> stream = Flanagan is a software engineer at Mozilla, best known for his
Files.newDirectoryStream( master work JavaScript: the Definitive Guide (OReilly, 2011).
55
ORACLE.COM/JAVAMAGAZINE /////////////////////////////////////////// JULY/AUGUST 2016
//new to java /
MICHAEL KLLING
W elcome back to the discussion of generic types in Java.
In my previous article, I started discussing generics
typeswhy they are useful, what you can do with them, and
deined in Person and redeined appropriately in the sub-
types). All seems well.
The problem becomes apparent when you consider that
how to use them. The introductory part of this topic was quite the printList method could also modify the list. It could, for
straightforward, but at the end of that discussion I mentioned example, include the following line:
a problem: generic collections and subtyping.
In short, I wanted to write a general printList method such list.add(new Faculty());
as this:
Because the static type of the list variable (the formal
private void printList(List<Person> list) parameter to the method) is List<Person>, and Faculty is a
subtype of Person, adding this object causes no type prob-
And I wanted it to print out lists of subtypes of Person, such lems. However, if the actual list passed to the printList
as List<Student> or List<Faculty>. In other words, given that method were a list of students, then I have now added a
Student is a subtype of Person, I wanted to call the method Faculty object to the Student list! This is a clear error and
above like this: should not be allowed to happen.
The only solution is to declare that List<Student> is not a
List<Student> students = getStudentList(); subtype of List<Person>, and to prevent student lists from
printList(students); being passed in to the printList method. Type safety is pre-
served, but I am back to square one: How can I now write my
This does not work in Java. The reason is that List<Student> general printList method?
is not considered a subtype of List<Person> even though
Student is a subtype of Person. Wildcards to the Rescue
The solution to this problem is the use of wildcards. I can
Whats the Problem? write my printList method like this:
So why is List<Student> not a subtype of List<Person>? If
you think only about printing out the list, there seems to be private void printList(List<?> list)
no problem. The printList method could call, for instance,
PHOTOGRAPH BY
JOHN BLYTHE a print method on all the lists elements (which might be Note the question mark in place of the element type of
56
ORACLE.COM/JAVAMAGAZINE /////////////////////////////////////////// JULY/AUGUST 2016
//new to java /
the list. The question mark is the wildcard symbol, and it every type is a subtype of Object). So I cannot treat element
denotes a type called unknown. My parameter is now a list of types as Persons.
unknown type. Not knowing much about the element type can still be OK
There is an obvious beneit to this construct. I can now do in some cases. I could still use all list operations that do not
what I intended to do: I can call my printList method with depend on the element type, such as size() and clear(). I
both List<Student> and List<Faculty> as parameters: could also do anything that I can do with the Object type,
such as using the toString method (maybe implicitly by call-
List<Student> students = getStudentList(); ing System.out.println).
List<Faculty> professors = getFacultyList(); But to call type-speciic methods, I need something else.
printList(students); In using the wildcard, I went from saying that my parameter
printList(professors); is exactly a List of Person to saying that it is a List of anything.
Instead, I would like to say that it is a List of any subtype of
Every list type is considered to be a subtype of the list of this Person. I can do this with a bounded wildcard.
unknown type, so this code now works. The trade-of is that I
cannot add to the list when the element type is unknown, so Bounded Wildcards
I avoid the type problem discussed earlier when I tried to add Generic parameters can have bounds, which restrict what
to the list. kind of actual types can be used for them. Consider this next
version of my printList method:
What Is Known About the Unknown Type?
The wildcard is a good step forward, but it does not solve all private void printList(List<? extends Person> list)
my problems. You can see this if you think about what I can
do with my list elements now. What if my Person superclass This deinition now allows lists of Person or subtypes of
had a method printAddressDetails that I want to use as part Person (and only these) as parameters, just as I intended.
of my printList method: Because I am using a wildcard, I am still not allowed to add to
the list, but I know that all elements are of type Person (or its
private void printList(List<?> list) { subtypes). I can now treat elements as Person objects and call
for (Person p: list) { the appropriate methods. This inally solves my problem.
...
p.printAddressDetails(); Other Bounded Types
} Wildcards are not the only place where bounds can be used
} and are useful. Type bounds can also be employed in the dec-
laration of generic types and in methods without wildcards.
This will now not work. The advantage of using the unknown For example, I can deine a generic type PersonList that
type is that you can pass in lists of any type, but you pay by accepts only Person and its subtypes as parameters:
virtue of the fact that you dont know much about that type.
All you know, in fact, is that it is a subtype of Object (because class PersonList<T extends Person>
57
ORACLE.COM/JAVAMAGAZINE /////////////////////////////////////////// JULY/AUGUST 2016
//new to java /
This is similar to the deinition of ArrayList that I showed in so no type parameter has previously been declared. To use a
the last issue of Java Magazine, but this time only subtypes of generic type in the parameter list, I need to declare this type
Person can be used to instantiate the type: irstthat is the efect of writing the type <T> in the header.
This code will fail, however, because the less-than operator
PersonList<Student> students = cannot be applied to any unspeciied type T. Instead, I can
new PersonList<Students>(); use the compareTo method, but this works only when T is a
PersonList<Faculty> professors = subtype of Comparable. I can enforce this by changing my
new PersonList<Faculty>(); method as follows:
In return, all methods from the Person type can now be used public <T extends Comparable<T>> void underLimit(
on objects of type T in my implementation of the PersonList List<T> myList, T limit) {
class, because I have a guarantee that any concrete instantia- for (T e : myList) {
tion of T will have these methods. if (e.compareTo(limit) < 0)
System.out.println(e);
Generic Methods }
This is a good time to introduce another generic feature: }
generic methods. In the previous examples, the generic
type parameter was introduced in the class header when Here, I have declared that I only accept types for type T that
we declared a generic class. It is also possible to have single are subtypes of Comparable so that the methods needed are
generic methods, without making the whole class generic. In guaranteed to be available.
that case, the single method can handle generic types. Generic
methods are often combined with bounded generic types. Upper Bounds and Lower Bounds
Consider the following example. Here, I attempt to write a So far, I have discussed bounded types only by showing an
method that prints all elements from a list that are smaller upper bound to establish a supertype (an upper bound) for the
than a given limit: wildcard parameter, for example:
This code looks entirely reasonable, but if you consult the Because this ield is shared between all variants of the type, it
previous section on type erasure, you will see why it does cannot refer to the type parameter of speciic instantiations.
not work: the runtime system has no idea whether a type
is List<Person>, because it does not keep this information Java Trivia: Arrays and Type Safety
around. (All it knows about is List<Object> but nothing more If you are interested in the details of Java and type safety, you
speciic.) So it cannot perform this check and give you the might like this little bit of Java trivia: the implementation of
answer. You will see an error saying illegal generic type arrays in Java has a hole in its type system. This is one of the
for instanceof. rare cases where Java is not statically type-safe.
The same problem shows up when you use the getClass The problem is the same problem I discussed earlier in
method: this article: If B is a subtype of A, is then List<B> a subtype of
List<A>? For lists, the answer is no. Earlier in this article, I
List<Student> sl = new ArrayList<Student>(); explained why this is and how it could go wrong if we were to
List<Faculty> fl = new ArrayList<Faculty>(); consider List<B> a subtype. However, for arrays (a very simi-
if (sl.getClass() == fl.getClass()) lar situation), Java does consider the list to be a subtype. This
... introduces a potential type problem. Consider the following
code:
At irst glance, you might think that the condition in the if-
statement is false, but because of type erasure, it will actually A[] aa;
evaluate to true. As far as the runtime system is concerned, B[] ba = new B[3];
the class of both objects is ArrayList.
aa = ba; // allowed! B[] is subtype of A[]
Generic Classes and Static Attributes aa[0] = new B();
One of the areas where type erasure becomes most visible aa[1] = new A(); // java.lang.ArrayStoreException: A
in source code is when you use static attributes in generic
classes. Static methods and static ields are shared between The last line in this example represents a type error: I am
all instantiations of a generic class. The reason is again the trying to insert an A object into an array of B. The problem is
same: only one copy of the generic class actually exists. You that the assignment in the third line is allowed. This problem
60
ORACLE.COM/JAVAMAGAZINE /////////////////////////////////////////// JULY/AUGUST 2016
//new to java / //java proposals of interest /
is picked up only at runtime, not at compile time, breaking
Javas static type safety. When it designed generic classes,
the Java team decided to be more conservative and detect the FEATURED JDK ENHANCEMENT PROPOSAL
equivalent problem at compile time.
JEP 282 jlink: The Java Linker
Conclusion
Generic types are easy to understand in principle and gener- For most readers, the idea of a linker for Java might
ally quite easy to use. However, when you start writing more seem very peculiar indeed. Linker functions, which are
sophisticated codeparticularly if youre writing libraries part of a build tool associated with native languages, are
you might run into a whole range of situations where you need performed by the JVM in its class-loading mechanism.
to understand the advanced constructs in generics. In particular, these functions are executed in the algo-
When you put all of the concepts together, the class and rithms for inding JARs that contain referred-to classes
method deinitions can become quite tricky to read even for and methods and then loading them into the current JVM
experienced programmers. Have a look at the max method of memory space. [For more information on this process,
class Collections in the standard library, for example, or the download a PDF of our article How the JVM Locates,
deinition of methods in the Class class. You will see that it Loads, and Runs Libraries by Oleg elajev. Ed.]
can take some time to get your head around the combination What JEP 282 proposes is not the traditional linker but,
of all the constructs. Do not let this discourage you; these rather, a generic tool that runs where a linker does in the
complex constructs are rare, and with the concepts I have build processafter the compiler but before creation of
discussed here and some practice, you should be able to work the executable. The tool would deine a plugin interface,
out most of it. More importantly, you should be able to write by which a variety of tools could be inserted into the build
correct and lexible code yourself. </article> process. The most obvious of these would be an optimizer,
especially a whole-program optimizer that could iden-
Michael Klling is a Java Champion and a professor at the tify opportunities to improve performance and reduce
University of Kent, England. He has published two Java textbooks code size that are not visible to the compiler on a class
and numerous papers on object orientation and computing educa- basis. Other plugins suggested in the JEP document could
tion topics, and he is the lead developer of BlueJ and Greenfoot, remove debug information, reorder resources so that they
two educational programming environments. Klling is also a can be loaded faster, and even compress generated iles.
Distinguished Educator of the ACM. In theory, many other reinements to generated code
could be performedincluding those from third parties.
Some examples are insertion of instrumentation data,
supplementation of debugging data, conversion of byte-
learn more codes to other formats, intraclass optimization, and so
on. All of this could be done through plugins to the pro-
The Java Tutorial on generic types posed jlink technology.
61
ORACLE.COM/JAVAMAGAZINE /////////////////////////////////////////// JULY/AUGUST 2016
//jvm languages /
In addition to the actual application code and tests, the scaf- Deploying Rails on JRuby
folding generated whats called a database migration. This is a In CRuby, if you want to handle any requests in parallel, you
short script that can take one version of the database scheme need to spin up separate processes that is, completely inde-
and apply changes needed to migrate to the next version. pendent VMs that share no resources. As a result, even small
These migrations allow you to roll schemas back and forth in applications will consume more memory, and if they need to
a database-agnostic way. do any communication, youre forced to use some interpro-
Then I just need to roll the database migration forward and cess communication. Data sharing has to be done in a third
start the server again. process, such as a database or memcached, because those
processes share only read-only application structure. Now
$ rake db:migrate you have a whole bunch of Ruby virtual machines running,
== 20160606083900 CreatePosts: migrating ========= each with its own heap and garbage collectorthis is not the
-- create_table(:posts) best use of resources in this multicore era.
-> 0.0075s In JRuby, you can take that same Rails application and han-
-> 0 rows dle your entire load inside a single process, with a single gar-
== 20160606083900 CreatePosts: migrated (0.0099s) bage collector tuned for concurrency and scalable heaps. That
one process can be a standalone server, or you can deploy
$ rails server JRuby on Rails as a Java WAR ile to any standard web con-
=> Booting WEBrick tainer such as Tomcat or WildFly. Whether youre coming to
... JRuby from Ruby or Java, deployments of JRuby applications
it your world and make better use of your hardware.
Here I am using the rake com- For simple, standalone use, the Puma gem, which is
mand, which is roughly equiva-
JRuby supports the most popular pure-Ruby web server, is generally
lent to using Ant or Maven, two-way integration recommended.
minus the dependency manage- with other JVM
ment. Once Rails has migrated $ gem install puma
to the latest database schema,
languages, so all Fetching: puma-3.4.0-java.gem (100%)
I can start up the server and, those Java libraries Successfully installed puma-3.4.0-java
presto, I have a basic web GUI for youre familiar with can 1 gem installed
CRUD operations. $ puma
Rails is still the killer app for
still be in your toolbox. Puma starting in single mode...
Ruby, and if you havent tried it * Version 3.4.0 (jruby 9.1.3.0-SNAPSHOT - ruby 2.3.0),
65
ORACLE.COM/JAVAMAGAZINE /////////////////////////////////////////// JULY/AUGUST 2016
//jvm languages /
codename: Owl Bowl Brawl java_import java.lang.System
* Min threads: 0, max threads: 16
* Environment: development Frame = javax.swing.JFrame
* Listening on tcp://0.0.0.0:9292 Button = javax.swing.JButton
Use Ctrl-C to stop Label = javax.swing.JLabel
If you need to deploy to an existing Java app server or web frame = Frame.new("Java Home Checker")
container, use the Warbler gem to package your Rails app button = Button.new("Display Java Home")
(plus all its dependencies) into a deployable WAR ile. label = Label.new
Thats all there is to it. This simple example already shows some of JRubys advan-
tages. Speciically, imports are just plain Ruby code. The code
Scripting Java shows two ways to import a class: using the java_import
Theres another feature of JRuby that makes it even more function or simply using the fully qualiied long class name
attractive for Ruby and Rails developers: you can call (and assigning it to a short one).
any library on the JVM as if it were just another piece of Java method names are tweaked a bit to make them look
Ruby code. more like Ruby method names: snake_case is used instead of
JRuby supports two-way integration with other JVM lan- camelCase, set/get properties can omit set/get and be called
guages, so all those Java libraries youre familiar with can still by just the attribute name, parentheses are optional, and so
be in your toolbox. In fact, scripting Java libraries with JRuby on. In fact, you might not even know this code calls a Java
is often much more fun and much easier than writing Java library if you werent familiar with Swing.
code. Lets have a look at a few examples. Simple interfaces can be implemented on the ly by passing
66
ORACLE.COM/JAVAMAGAZINE /////////////////////////////////////////// JULY/AUGUST 2016
//jvm languages /
a block of code, similar to Java 8 lambdas. But JRuby can also libraries are installed on the local ilesystem as Ruby sources,
dynamically add an interface implementation to any object, but occasionally they will bring along extensions written in
and it doesnt have to implement all methods (usually by other languages.
including a method_missing fallback). On line 3, I have a Ruby class deinition extending the
Theres a lot less noise and ceremony in this code than JRubyFX::Application class. Classes in Ruby are declared
there would be in the Java version. with the class keyword, just as in Java, but instead of having
Lets take a look at a few more-advanced examples of what an extends keyword Ruby uses the less-than symbol (<). The
you can do with JRubys Java integration. double colons are Rubys way to indicate namespacing.
The irst method deinition is on line 4. Because Ruby
JRubyFX is dynamically typed, there are no type declarations for a
In late 2008, Sun Microsystems released the irst version of method return or method parameters.
JavaFX, a new GUI toolkit inspired by web technologies and Lines 5 through 8 set up the stage. I set a title and window
destined to be the replacement for Swing. JavaFX initially had size (using Ruby-style attribute assignment rather than Javas
its own language, JavaFX Script, but in an already tight world set methods), and then I tell JavaFX to show the stage.
of language options, only the GUI Toolkit survives to this Lines 9 and 10 end the method and the class deinition.
day. That means youll be writing your JavaFX logic in Java. Most lexical scopes in Ruby are closed with the end keyword,
Perhaps a little JRuby can help here, too. although short blocks (lambdas) frequently use curly braces.
Enter JRubyFX, a Ruby API and wrapper for writing JavaFX And inally, on line 12, I tell the new JRubyFX application to
applications. Lets walk through a simple example. launch itself. Its that easy.
Now lets look at how Ruby can really make the application
01 require 'jrubyfx' fun and easy to write.
02
03 class HelloWorldApp < JRubyFX::Application def start(stage)
04 def start(stage) with(stage, title: "Hello World!") do
05 stage.title = "Hello World!" layout_scene(800, 600) do
06 stage.width = 800 label("Hello World!")
07 stage.height = 600 end
08 stage.show() end
09 end stage.show # you can also put the
10 end # method call inside the block
11 end
12 HelloWorldApp.launch
Here, the start method is a bit more complicated. The most
On line 1, I require jrubyfx, which is a set of bindings for obvious change is the call to with, which takes a block of code
the JavaFX library, so I can use its features. In Ruby, libraries using JRubyFXs scene-building DSL. Given the Stage pro-
are brought into the process using require. Generally these vided by JavaFX and a title, I proceed to build the stages con-
67
ORACLE.COM/JAVAMAGAZINE /////////////////////////////////////////// JULY/AUGUST 2016
//jvm languages /
tents. I tell the DSL how to lay out this scene, and then I add show
some actual content: a JavaFX label. end
What about FXML, JavaFXs XML-based markup for describ- end
ing scenes? Building the scene with Ruby is great (and cer-
tainly a lot less hassle than doing it in Java), but for larger JRuby and JavaFX work really well together, so if you havent
applications, you probably want a description of the GUI thats had a chance to try JavaFX, JRubyFX might be the most fun
separate from the application code. youll have this week. Check out the complete Getting Started
Heres an FXML deinition for my simple scene: page for JRubyFX.
pid, uid = POSIX.getpid, POSIX.getuid JRubys FFI also provides a way to deine native data types,
puts "Process #{pid} running as user #{uid}" such as structs. In the preceding code, I deine a Timeval
struct that has an in-memory layout of two unsigned longs:
In this example, Ive created a Ruby module to hold native tv_sec and tv_usec. I bind in the libc gettimeofday function,
function bindings. Think of a module as an interface with construct a new instance of Timeval, and make the call. The
default implementations for every method. Those methods native call populates a native struct that I can then read from
can be class methods (similar to static methods in Java) or like a normal Ruby object, all without writing a line of C code.
instance methods that are added to a class hierarchy when Pretty cool, right?
the module is included (similar to implementing an interface FFI is capable of much more than this, and there are many
in Java). large production apps out there leveraging JRubys native capa-
Inside the LibC module, in the next listing, I extend the bilities. For more information, stop by the Ruby FFI project.
FFI::Library module, which injects other FFI methods I
can use to bind functions and deine native data types. Now The Future of JRuby 9000
I have access to attach_function from the previous listing, JRuby 9000 represents one of the most advanced JVM lan-
which takes as arguments the name of the function I want guage implementations available. It has its own bytecode-like
to call, an optional Ruby name to assign to the function, and intermediate representation, an optimizing compiler, and a
information about parameter types. mixed-mode interpreter plus a JIT compiler (very much like
Thats it. Run this code on JRuby, and youll see the real, live the JVM itself). The JRuby team has been pushing the limits
process ID and user ID for the host JVMsomething thats of what a language can do atop the JVM. In fact, JRuby is cur-
not possible to do with pure Java code. rently the fastest Ruby implementation available. By the end
of this year, the team hopes to utilize its internal representa-
class Timeval < FFI::Struct tion (IR) runtime to make all JRuby code perform compara-
layout :tv_sec => :ulong, :tv_usec => :ulong bly to equivalent Java code, without sacriicing any of Rubys
end unique features.
But the JRuby team is not stopping there. In late 2014,
module LibC the team partnered with Oracle Labs to open-source their
extend FFI::Library Trule-based Ruby implementation as part of the JRuby
attach_function :gettimeofday, project. Trule is a next-generation language runtime that
69
ORACLE.COM/JAVAMAGAZINE /////////////////////////////////////////// JULY/AUGUST 2016
//jvm languages / //user groups /
lives alongside JVM bytecode but it uses the pure-Java Graal
JIT compiler to directly optimize a languages behavior. As a
result, JRuby plus Trule might prove to be the fastest way
BUCHAREST JUG
to run Ruby on any runtime, albeit with the requirement that Bucharest, Romania, is a
you run on a Graal-friendly JVM such as JDK 9. The JRuby regional leader in soft-
team hopes to see the JRuby plus Trule runtime production- ware development. The
ready in the next couple of years. Bucharest Java User Group
The team is very excited, both about its IR runtime and was formed to create a
about Trules potential. Ruby is no longer a slow language. strong community for all
the developers in Bucharest
Conclusion who are using Java- and
Ruby is a beautiful, fun language with a rich ecosystem and JVM-based programming
a friendly, helpful community. That community has built languages.
Rails into the powerhouse it is todaythe fastest way to get The irst meeting took
a well-structured web application deployed to production. place in May 2012 with approximately 25 participants. The
You can leverage the best of the Ruby world and the best of Java user group (JUG) is now led by Alex Proca and Alin
the Java world using JRubydeploying to the same servers, Pandichi and has more than 600 registered members. It
using the same libraries, getting the best out of the JVM organizes monthly meetings with one or two presentations,
and you just might have fun doing it. Its a great time to starting around 7 p.m.; later on, it moves to a pub for drinks.
try JRuby. </article> Occasionally, it hosts hands-on labs such as the recent work-
shops on the MVC 1.0 (JSR 371) Java EE speciication and on
Charles Nutter is a Java Champion who works at Red Hat on JavaFX. Around 50 participants usually attend the talks, and
JVM languages and bending the JVM to his whims. He has been a 10 attend the workshops.
co-lead of the JRuby project for the past 10 years, and worked as The speakers are often selected from the local pool of
a lead Java EE architect for many years before that. He hopes to talented Java developersfor instance, Eugen Paraschiv (also
keep the Java platform open and evolving, and works to expand the known as Baeldung), whose tutorials and reviews have gar-
platform to new languages and new ways of building software. nered a sizable following. From time to time, the JUG hosts
international speakers such as Java Champion Axel Fontaine,
who gave a presentation about immutable infrastructure.
Local interest in Java, catalyzed by the JUG, led to a Java
conference, Voxxed Days Bucharest, which was irst held in
learn more March 2016. The organizers are already looking forward to
next years event.
Home of the Ruby language (non-JVM) The Bucharest JUG keeps in close contact with members
Trule on the JDK of the worldwide Java communities. Contact it via email or
follow it on Twitter, Facebook, Google+, or Meetup.
70
ORACLE.COM/JAVAMAGAZINE /////////////////////////////////////////// JULY/AUGUST 2016
//ix this /
Quiz Yourself
More subtle questions from an author of the Java certification tests
SIMON ROBERTS
I ve put together more interesting problems that simulate
questions from the 1Z0-809 Programmer II exam, which is
the certiication test for developers who have been certiied
public class MultiCatch {
public void fingersCrossed()
throws OneException, TwoException,
at a basic level of Java programming knowledge and now are ThreeException { }
looking to demonstrate more-advanced expertise. [Readers
wishing basic instruction should consult the New to Java public void tryThingsOut() /* Point A */{
column, which appears in every issue. Ed.] try {
Question 1. Given this class declaration: fingersCrossed();
public class Tire { private int diameter, width; } } catch (OneException | TwoException ex) {
ex.printStackTrace();
Which two actions are normally performed to support simple use throw ex;
in the Collections framework? Choose two. } catch (ThreeException e) {
a. Add a method with the signature public boolean e.printStackTrace();
equals(Tire t). }
b. Add a method with the signature public int }
hashCode(Tire t). }
c. Add a method with the signature public boolean
equals(Object o). Which is the best change? Choose one.
d. Add a method with the signature public int a. No change is necessary; the code is ideal as shown.
hashCode(). b. The code should be modiied by adding at /* Point A */
e. Arrange that the class implements Comparable<Tire>. the text throws Exception.
c. The code should be modiied by adding at /* Point A */
Question 2. Given the following code: the text throws BaseException.
public class BaseException extends Exception {} d. The code should be modiied by adding at /* Point A */
public class OneException extends BaseException {} the text throws OneException, TwoException.
public class TwoException extends BaseException {} e. The code should be modiied by adding at /* Point A */
public class ThreeException extends Exception {} the text throws OneException, TwoException,
ThreeException.
71
ORACLE.COM/JAVAMAGAZINE /////////////////////////////////////////// JULY/AUGUST 2016
//ix this /
Question 3. Given the following code: actually depend on ordering, such as TreeSetorder isnt
System.out.println( really a fundamental part of the API as a whole. However,
Stream.empty().findAny() the idea of equality is absolutely fundamental. The basic
// Line n1 way that most collections determine whether they contain
); one particular object is by using the equals method to see
whether the object in the collection is equivalent to the one
Which two, applied independently, may be added at line n1 to being asked about.
cause the output "Empty"? Choose two. So, equals is almost certainly the irst method youll
a. .ifPresent(s->s).orElse("Empty") think about implementing for any class thats going to be
b. .orElse("Empty") stored in a collection, at least if theres any chance of need-
c. .orElseGet(() -> "Empty") ing to ind it directly. The next question is which of the
d. .orElseGet("Empty") two proposed method signatures is correct. Both will com-
e. .orElseSupply(()->"Empty") pile, but the actual signature must take an Object argu-
f. .otherwise("Empty") ment. There are two reasons. First, from a syntax perspec-
tive, this method must override the equals method deined
Question 4. Which of the following two statements, indepen- in java.lang.Object, and thats deined to take an Object
dently, might be good uses of assertions? Choose two. argument. Second, from a philosophical perspective, its
a. assert x >= 0 : "X must be non-negative"; perfectly reasonable to ask whether this apple is equal to
b. assert x++ > 0; that banana. The answer is simply no. Its tempting in
c. assert x == 0; these days of familiar generics to think that the method
d. assert (++x > 0 , "X must be non-negative"); would take an argument of the objects own type, but if that
e. assertTrue "X must be zero" : x == 0; method is implemented, it will be ignored by the Collections
API. So, option A is incorrect, and option C is the proper
equals method. Dont forget that when overriding a method,
its good practice to use the @Override annotation. That
will ensure that if you declare the argument as anything
Answers other than Object, the compiler will tell you that you made
a mistake.
Next, the documentation for equals states, Note that it is
generally necessary to override the hashCode method when-
ever this method is overridden, so as to maintain the general
Question 1. The correct answers are options C and D. In this contract for the hashCode method, which states that equal
question, there are three methods to choose among: equals, objects must have equal hash codes.
hashCode, and the compareTo method of the Comparable Given this requirement, its pretty clear that implement-
interface. While order comparisons are certainly relevant ing equals almost mandates implementing hashCode. The
to some parts of the Collections APInotably those that remaining question is what the signature should be. Given
72
ORACLE.COM/JAVAMAGAZINE /////////////////////////////////////////// JULY/AUGUST 2016
//ix this /
that this is an instance method, and it generates a represen- Finally, theres the question of whether the other answers
tative number based on the contents of this, its fairly clear are wrong or whether they could be cause for a complaint to
that no argument is needed, and indeed, the documentation the examiners. Well, its certainly true that options B, C, and E
shows that option D is correct and option B is wrong. also compile. Functionally, they work perfectly well, too, and
Its fair to note that although equals and hashCode are the that might tempt you to believe that theyre all equally valid.
most fundamental methods required of classes that partici- However, checked exceptions have two consequences.
pate in collections, the Comparable interface, with its method First, they put a burden on the programmer who writes
compareTo, is certainly relevant in some situations. Ordered the calling code, and (except with interfaces) you should not
structures, such as the implementations of SortedSet and declare more exceptions than you might throw without a
SortedMap, often use it. If this were an exam question, the good reason. Second, they should convey useful information
fact that youre told to select two answers should remove about failure modes to the caller. If you declare a more gen-
any small doubt you might have had about leaving option E eral exception, that information is diluted or lost, which is
unchecked. Its worth mentioning that its a matter of policy: unhelpful and reduces readability. Both of these reasons
Oracles Java certiication exam questions always state exactly should tell you that options B, C, and E, all of which declare
how many answers you should select. Be careful not to throw throwing more exception classes than are actually possible,
points away by ignoring this advice! are not as good as option D.
Question 2. The correct answer is option D. The essence of Of course, its possible that you dont accept the reasoning
this question has two parts. First, the exception classes are just given. Javas checked exception mechanism is the subject
all checked exceptions, which means that if you rethrow the of much debate, so its clear that opinions difer. But most of
exception caught in the multicatch (that is, in the part catch those who dislike checked exceptions would strongly sup-
(OneException | TwoException ex)), you must declare that port the notion that throwing too many exceptions is bad.
the method throws that exception type. This means that Anyway, the inal observation is that you are told to choose
option A is incorrect; the code does not compile as is. one answer. So, you know that you must distinguish among
The second part of the question relates to what the type of four compilable answers. You need to ind a plausible reason
the formal parameter ex actually is, and what the checked to make a choice, even if you dont personally like the reason.
exception mechanism demands for the declaration. This is Dont be afraid to apply a little logic to separate plausible
slightly trickier, and its where that bothersome word best in answers from better answers. Its probably the case that this
the phrase the best change comes in. question would be subject to considerable scrutiny by the
In the code, ex can really have only one type, and this is exam team. Indeed, I suspect it might be rejected. My purpose
actually the closest common parent of the types listed in in including it here is to illustrate how logic and knowledge of
the multicatch; that is BaseException. However, the checked good practices can be applied to choose one right answer
exception mechanism understands the multicatch syntax, among several answers that compile and run successfully.
and when rethrowing ex, only those exceptions speciically Question 3. The correct answers are options B and C. This
listed in the catch parameter list need to be declared in the question hinges on some knowledge about Stream API behav-
throws clause. Option D lists exactly the same exceptions as ior and the Optional class.
the catch block, and it is the correct answer. First, the findAny method returns an object from the
73
ORACLE.COM/JAVAMAGAZINE /////////////////////////////////////////// JULY/AUGUST 2016
//ix this /
stream. However, the stream might be empty, and whenever pile. Option D fails because the assert keyword is just that: a
theres a chance that a stream terminal operation might not keyword. Its not a method call, so the syntax there is bogus.
have anything to return, the Optional class is used to repre- Also, assertTrue in option E is not part of the core Java SE
sent the result. As a side note, Optional is an API mechanism API, but the name is used in tools such as JUnit. However,
intended to avoid null pointer exceptions. Tony Hoare, inven- assertTrue in JUnit is a method, so it requires parentheses
tor of null pointers, has acknowledged that these have caused and a comma rather than a colon to separate its parameters.
many bugs; he now refers to them as his billion-dollar mis- Option E is, therefore, wrong. As a side note, the Java exam is
take. To be fair, the use of special values to indicate errors or about core Java features, not third-party APIs, so if you knew
exceptional situations is now almost universally recognized what assertTrue is about, you should have rejected it from
as a bad thing, and exceptions address this issue, too. consideration for that reason.
Once you recognize that you will get an Optional from the Of the three compilable options, two are good and one
findAny terminal operation, you need to know how to interact is severely broken. Option A is the two-operand form of
with it and get the text Empty from our println method assert; the irst operand is a boolean expression, and the
call. In this case, you know that the stream is empty and, second is a text message that will become the message in the
therefore, findAny will return an empty Optional to us. AssertionError that is thrown if the boolean evaluates to
Given an empty Optional, there are two methods intended false. Option C uses the single-operand form, which executes
to directly return a value for your use. Consulting the API the boolean test and builds an AssertionError with a null
documentation, you can see that these methods are orElse message if the boolean evaluates to false. Next, lets look at
and orElseGet. Both methods return the contents of the why option B is a huge error, even though it compiles.
Optional if it is not empty or an alternative value if it is The goal of assertions is to allow the programmer to put
empty. The orElse version takes a simple value that is to be certain statements about design intent into the code, in a way
returned, matching the call in option B. The orElseGet ver- that forms documentation that cannot be wrong. The bool-
sion takes a Supplier, which is invoked in the event that ean expression that forms the required operand for an assert
the Optional is empty. Supplier is a functional interface must be true; otherwise, the assert is expected to complain.
that deines a method that takes no arguments and returns These little statements can be very helpful when picking up
a value. To create that as a lambda expression requires the code that someone else wrote; they can tell all sorts of use-
empty parentheses, followed by the arrow symbol, and then ful details about how the code works. However, because the
the expression that deines what the newly supplied value expression in the assertion seemingly must be evaluated
will be. That suggests the form () -> expression, or, to every time the program runs past the statement, its possible
return the speciic literal: () -> "Empty", which is option C. to be concerned that the CPU usage of all these little tests
The other options are syntactically incorrect. could adversely afect performance.
Question 4. The correct answers are options A and C. Heres A performance concern like that would probably discourage
that word good again. It gives you a bit of a hint that some most programmers from using assertions freely. However,
level of judgment beyond whether or not something compiles assertions have a neat trick: the code of assert statements
might be important here. can be stripped from the bytecode during classloading. If
In this case, three optionsoptions A, B, and Cwill com- this happens, the statements have zero performance impact.
74
ORACLE.COM/JAVAMAGAZINE /////////////////////////////////////////// JULY/AUGUST 2016
//ix this /
It turns out that stripping them is the default behavior.
So, you must explicitly use the command-line option -ea,
or -enableassertions, for the assertions to be executed.
(Unfortunately, IDEs also generally duplicate this default.)
The intention is that programmers always test their code
with -ea in efect and that the user runs the inal program
without it. That creates an elegant best of both worlds
situation that, in my view, gets far less use than it should.
Of course, this conditional execution also creates an
interesting potential problem. Imagine that the boolean
expression in your assertion actually does something of
computational signiicance. It has a side efect and changes
something in some way. Now you have the makings of a
disaster; the functional behavior changes depending on
whether you run in development mode (with -ea) or produc-
tion mode (without it). The documentation of assert goes to
great lengths to point out that side efects of any kind must
be avoided in an assert statement. For this reason, option B is
bad and, therefore, incorrect.
The Java Language Speciication, in section 14.10, notes,
Because assertions may be disabled, programs must not
assume that the expressions contained in assertions will be
evaluated. Thus, these boolean expressions should gener-
ally be free of side efects. You can ind more discussion
on safe and appropriate uses of assert here. Notice that in
that document, there are other dos and donts, which is why
the question in this quiz asks which might be good uses...,
rather than which are good uses.... Options B, D, and E
cannot possibly be good; the other two might be if other
conditions are met, but no information is available on those
issues. </article>
76
ORACLE.COM/JAVAMAGAZINE /////////////////////////////////////////// JULY/AUGUST 2016