Recent Posts
Archives

Posts Tagged ‘Modularity’

PostHeaderIcon [DevoxxUS2017] 55 New Features in JDK 9: A Comprehensive Overview

At DevoxxUS2017, Simon Ritter, Deputy CTO at Azul Systems, delivered a detailed exploration of the 55 new features in JDK 9, with a particular focus on modularity through Project Jigsaw. Simon, a veteran Java evangelist, provided a whirlwind tour of the enhancements, categorizing them into features, standards, JVM internals, specialized updates, and housekeeping changes. His presentation equipped developers with the knowledge to leverage JDK 9’s advancements effectively. This post examines the key themes of Simon’s talk, highlighting how these features enhance Java’s flexibility, performance, and maintainability.

Modularity and Project Jigsaw

The cornerstone of JDK 9 is Project Jigsaw, which introduces modularity to the Java platform. Simon explained that the traditional rt.jar file, containing over 4,500 classes, has been replaced with 94 modular components in the jmods directory. This restructuring encapsulates private APIs, such as sun.misc.Unsafe, to improve security and maintainability, though it poses compatibility challenges for libraries relying on these APIs. To mitigate this, Simon highlighted options like the --add-exports and --add-opens flags, as well as a “big kill switch” (--permit-illegal-access) to disable modularity for legacy applications. The jlink tool further enhances modularity by creating custom runtimes with only the necessary modules, optimizing deployment for specific applications.

Enhanced APIs and Developer Productivity

JDK 9 introduces several API improvements to streamline development. Simon showcased factory methods for collections, allowing developers to create immutable collections with concise syntax, such as List.of() or Set.of(). The Streams API has been enhanced with methods like takeWhile, dropWhile, and ofNullable, improving expressiveness in data processing. Additionally, the introduction of jshell, an interactive REPL, enables rapid prototyping and experimentation. These enhancements reduce boilerplate code and enhance developer productivity, making Java more intuitive and efficient for modern application development.

JVM Internals and Performance

Simon delved into JVM enhancements, including improvements to the G1 garbage collector, which is now the default in JDK 9. The G1 collector offers better performance for large heaps, addressing limitations of the Concurrent Mark Sweep collector. Other internal improvements include a new process API for accessing operating system process details and a directive file for controlling JIT compiler behavior. These changes enhance runtime efficiency and provide developers with greater control over JVM performance, ensuring Java remains competitive for high-performance applications.

Housekeeping and Deprecations

JDK 9 includes significant housekeeping changes to streamline the platform. Simon highlighted the new version string format, adopting semantic versioning (major.minor.security.patch) for clearer identification. The directory structure has been flattened, eliminating the JRE subdirectory and tools.jar, with configuration files centralized in the conf directory. Deprecated APIs, such as the applet API and certain garbage collection options, have been removed to reduce maintenance overhead. These changes simplify the JDK’s structure, improving maintainability while requiring developers to test applications for compatibility.

Standards and Specialized Features

Simon also covered updates to standards and specialized features. The HTTP/2 client, introduced as an incubator module, allows developers to test and provide feedback before it becomes standard. Other standards updates include support for Unicode 8.0 and the deprecation of SHA-1 certificates for enhanced security. Specialized features, such as the annotations pipeline and parser API, improve the handling of complex annotations and programmatic interactions with the compiler. These updates ensure Java aligns with modern standards while offering flexibility for specialized use cases.

Links:

PostHeaderIcon [DevoxxBE2012] Architecture All the Way Down

Kirk Knoernschild, a software developer passionate about modular systems and author of “Java Application Architecture,” explored the pervasive nature of architecture in software. Kirk, drawing from his book on OSGi patterns, challenged traditional views, arguing architecture permeates all levels—from high-level designs to code.

He invoked the “turtles all the way down” anecdote to illustrate architecture’s recursive essence: decisions at every layer impact flexibility. Kirk critiqued ivory-tower approaches, advocating collaborative, iterative practices aligning business and technology.

Paradoxically, architecture aims for change resistance yet adaptability. Temporal dimensions—decisions’ longevity—affect modularity: stable elements form foundations, volatile ones remain flexible.

Kirk linked SOA’s service granularity to modularity, noting services as deployable units fostering reuse. He emphasized patterns ensuring evolvability without rigidity.

Demystifying Architectural Paradoxes

Kirk elaborated on architecture’s dual goals: stability against volatility. He used examples where over-design stifles agility, advocating minimal upfront planning with evolutionary refinement.

Temporal hierarchies classify decisions by change frequency: strategic (years), tactical (months), operational (days). This guides layering: stable cores support variable extensions.

Granularity and Modularity Principles

Discussing granularity, Kirk warned against extremes: monolithic systems hinder reuse; overly fine-grained increase complexity. Patterns like base and dependency injection promote loose coupling.

He showcased OSGi’s runtime modularity, enforcing boundaries via exports/imports, preventing spaghetti code.

Linking Design to Temporal Decisions

Kirk connected design principles—SOLID—to temporal aspects: single responsibility minimizes change impact; open-closed enables extension without modification.

He illustrated with code: classes as small modules, packages as mid-level, OSGi bundles as deployable.

SOA and Modular Synergies

In SOA, services mirror modules: autonomous, composable. Kirk advocated aligning service boundaries with business domains, using modularity patterns for internal structure.

He critiqued layered architectures fostering silos, preferring vertical slices for cohesion.

Practical Implementation and Tools

Kirk recommended modular frameworks like OSGi or Jigsaw, but stressed design paradigms over tools. Patterns catalog aids designing evolvable systems.

He concluded: multiple communication levels—classes to services—enhance understanding, urging focus on modularity for adaptive software.

Kirk’s insights reframed architecture as holistic, from code to enterprise, essential for enduring systems.

Links:

PostHeaderIcon [DevoxxFR2013] The Classpath Persists, Yet Its Days Appear Numbered

Lecturer

Alexis Hassler has devoted more than fifteen years to Java development. Operating independently, he engages in programming while also guiding enterprises through training and advisory roles to refine their Java-based workflows and deployment strategies. As co-leader of the Lyon Java User Group, he plays a pivotal part in orchestrating community gatherings, including the acclaimed annual Mix-IT conference held in Lyon.

Abstract

Alexis Hassler meticulously examines the enduring complexities surrounding Java’s classpath and classloading mechanisms, drawing a sharp contrast between conventional hierarchical approaches and the rise of sophisticated modular frameworks. By weaving historical insights with hands-on illustrations and deep integration of JBoss Modules, he unravels the intricacies of dependency clashes, application isolation techniques, and viable transition pathways. The exploration extends to profound consequences for application server environments, delivering practical remedies to alleviate classpath-induced frustrations while casting an anticipatory gaze toward the transformative potential of Jigsaw.

Tracing the Roots: Classloaders and the Enduring Classpath Conundrum

Hassler opens by invoking Mark Reinhold’s bold 2009 JavaOne proclamation that the classpath’s demise was imminent, a statement that fueled expectations of modular systems seamlessly resolving all dependency conflicts. Despite the passage of four years, the classpath remains a fixture within the JDK and application server landscapes, underscoring its stubborn resilience.

Within the JDK, classloaders operate through a delegation hierarchy: the Bootstrap classloader handles foundational rt.jar components, the Extension classloader manages optional javax packages, and the Application classloader oversees user-defined code. This parent-first delegation model effectively safeguards core class integrity yet frequently precipitates version mismatches when disparate libraries demand conflicting implementations.

Hassler vividly demonstrates notorious pitfalls, such as the perplexing ClassNotFoundException that arises despite a JAR’s presence in the classpath or the insidious NoDefClassError triggered by incompatible transitive dependencies. These issues originate from the classpath’s flat aggregation paradigm, which indiscriminately merges all artifacts without regard for scoping or versioning nuances.

Hierarchical Containment Strategies in Application Servers: The Tomcat Paradigm

Application servers like Tomcat invert the delegation flow to enforce robust isolation among deployed artifacts. The WebappClassLoader prioritizes local resources before escalating unresolved requests to parent loaders, thereby permitting each web application to maintain its own dependency ecosystem.

This inverted hierarchy facilitates per-application versioning, substantially mitigating library collisions. Hassler delineates Tomcat’s layered loader architecture, encompassing common, server, shared, and per-webapp classloaders, each serving distinct scoping responsibilities.

Nevertheless, memory leaks persist as a formidable challenge, particularly during hot redeployments when static fields retain references to obsolete classes, inflating PermGen space. Mitigation demands meticulous resource cleanup through context listeners and disciplined finalization practices.

Modular Paradigms on the Horizon: OSGi, Jigsaw, and the Pragmatism of JBoss Modules

OSGi introduces the concept of bundles equipped with explicit import and export declarations, complete with version range specifications. This dynamic loading and unloading capability proves ideal for plugin architectures, though it necessitates substantial refactoring of existing codebases.

Project Jigsaw, slated for Java 9, aspires to embed modularity natively through module declarations that articulate precise dependencies. Despite repeated delays, its eventual integration promises standardized resolution, yet its absence compels interim solutions.

JBoss Modules, already battle-tested within JBoss AS7, employs a dependency graph resolution mechanism. Modules are defined with dedicated resource paths and dependency linkages, enabling parallel coexistence of multiple library versions. Hassler elucidates a module descriptor:

<module xmlns="urn:jboss:module:1.1" name="com.example.app">
    <resources>
        <resource-root path="app.jar"/>
    </resources>
    <dependencies>
        <module name="javax.api"/>
        <module name="org.hibernate" slot="4.3"/>
    </dependencies>
</module>

This structure empowers fine-grained version isolation, exemplified by simultaneous deployment of Hibernate 3 and 4 instances.

Hands-On Deployment Scenarios: JBoss Modules in Standalone and Tomcat Environments

Within JBoss AS7, modules reside in a dedicated directory structure, and applications declare dependencies via jboss-deployment-structure.xml manifests. Standalone execution leverages module-aware classloaders, either through MANIFEST entries or programmatic instantiation.

Hassler showcases a proof-of-concept integration with Tomcat, wherein a custom ClassLoader delegates to JBoss Modules, thereby endowing legacy web containers with modern dependency management. The prototype, available on GitHub, acknowledges limitations in hot-redeployment memory cleanup but validates conceptual soundness.

This adaptability extends modular benefits to environments traditionally tethered to classpath constraints.

Forward-Looking Consequences for Java Ecosystems: Transition Pathways and Jigsaw’s Promise

Classpath tribulations exact a heavy toll on developer productivity, manifesting in protracted debugging sessions and fragile builds. Modular frameworks counter these by enhancing maintainability, accelerating startup through lazy initialization, and fortifying deployment reliability.

Migration hurdles encompass tooling maturity and knowledge gaps, yet the advantages—conflict elimination, streamlined packaging—outweigh transitional friction. Hassler advocates incremental adoption, leveraging JBoss Modules as a bridge to Jigsaw’s eventual standardization.

In conclusion, while the classpath lingers, modular evolution heralds its obsolescence, equipping practitioners with robust tools to transcend historical limitations.

Links:

PostHeaderIcon [DevoxxBE2012] What’s New in Groovy 2.0?

Guillaume Laforge, the Groovy Project Lead and a key figure in its development since its inception, provided an extensive overview of Groovy’s advancements. Guillaume, employed by the SpringSource division of VMware at the time, highlighted how Groovy enhances developer efficiency and runtime speed with each iteration. He began by recapping essential elements from Groovy 1.8 before delving into the innovations of version 2.0, emphasizing its role as a versatile language on the JVM.

Guillaume underscored Groovy’s appeal as a scripting alternative to Java, offering dynamic capabilities while allowing modular usage for those not requiring full dynamism. He illustrated this with examples of seamless integration, such as embedding Groovy scripts in Java applications for flexible configurations. This approach reduces boilerplate and fosters rapid prototyping without sacrificing compatibility.

Transitioning to performance, Guillaume discussed optimizations in method invocation and arithmetic operations, which contribute to faster execution. He also touched on library enhancements, like improved date handling and JSON support, which streamline common tasks in enterprise environments.

A significant portion focused on modularity in Groovy 2.0, where the core is split into smaller jars, enabling selective inclusion of features like XML processing or SQL support. This granularity aids in lightweight deployments, particularly in constrained settings.

Static Type Checking for Reliability

Guillaume elaborated on static type checking, a flagship feature allowing early error detection without runtime overhead. He demonstrated annotating classes with @TypeChecked to enforce type safety, catching mismatches in assignments or method calls at compile time. This is particularly beneficial for large codebases, where dynamic typing might introduce subtle bugs.

He addressed extensions for domain-specific languages, ensuring type inference works even in complex scenarios like builder patterns. Guillaume showed how this integrates with IDEs for better code completion and refactoring support.

Static Compilation for Performance

Another cornerstone, static compilation via @CompileStatic, generates bytecode akin to Java’s, bypassing dynamic dispatch for speed gains. Guillaume benchmarked scenarios where this yields up to tenfold improvements, ideal for performance-critical sections.

He clarified that dynamic features remain available selectively, allowing hybrid approaches. This flexibility positions Groovy as a bridge between scripting ease and compiled efficiency.

InvokeDynamic Integration and Future Directions

Guillaume explored JDK7’s invokedynamic support, optimizing dynamic calls for better throughput. He presented metrics showing substantial gains in invocation-heavy code, aligning Groovy closer to Java’s performance.

Looking ahead, he previewed Groovy 2.1 enhancements, including refined type checking for DSLs and complete invokedynamic coverage. For Groovy 3.0, a revamped meta-object protocol and Java 8 lambda compatibility were on the horizon, with Groovy 4.0 adopting ANTLR4 for parsing.

In Q&A, Guillaume addressed migration paths and community contributions, reinforcing Groovy’s evolution as responsive to user needs.

His session portrayed Groovy as maturing into a robust, adaptable toolset for modern JVM development, balancing dynamism with rigor.

Links: