Recent Posts
Archives

Archive for the ‘General’ Category

PostHeaderIcon [DevoxxFR2014] Cassandra: Entering a New Era in Distributed Databases

Lecturer

Jonathan Ellis is the project chair of Apache Cassandra and co-founder of DataStax (formerly Riptano), a company providing professional support for Cassandra. With over five years of experience working on Cassandra, starting from its origins at Facebook, Jonathan has been instrumental in evolving it from a specialized system into a general-purpose distributed database. His expertise lies in high-performance, scalable data systems, and he frequently speaks on topics related to NoSQL databases and big data technologies.

Abstract

This article explores the evolution and key features of Apache Cassandra as presented in a comprehensive overview of its design, applications, and recent advancements. It delves into Cassandra’s architecture for handling time-series data, multi-data center deployments, and distributed counters, while highlighting its integration with Hadoop and the introduction of lightweight transactions and CQL. The analysis underscores Cassandra’s strengths in performance, availability, and scalability, providing insights into its practical implications for modern applications and future developments.

Introduction to Apache Cassandra

Apache Cassandra, initially developed at Facebook in 2008, has rapidly evolved into a versatile distributed database system. Originally designed to handle the inbox messaging needs of a social media platform, Cassandra has transcended its origins to become a general-purpose solution applicable across various industries. This transformation is evident in its adoption by companies like eBay, Adobe, and Constant Contact, where it manages high-velocity data with demands for performance, availability, and scalability.

The core appeal of Cassandra lies in its ability to manage vast amounts of data across multiple nodes without a single point of failure. Unlike traditional relational databases, Cassandra employs a peer-to-peer architecture, ensuring that every node in the cluster is identical and capable of handling read and write operations. This design philosophy stems from the need to support applications that require constant uptime and the ability to scale horizontally by adding more commodity hardware.

In practical terms, Cassandra excels in scenarios involving time-series data, which includes sequences of data points indexed in time order. Examples range from Internet of Things (IoT) sensor readings to user activity logs in applications and financial transaction records. These data types benefit from Cassandra’s efficient storage and retrieval mechanisms, which prioritize chronological ordering and rapid ingestion rates.

Architectural Design and Data Distribution

At the heart of Cassandra’s architecture is its data distribution model, which uses consistent hashing to partition data across nodes. Each row in Cassandra is identified by a primary key, which is hashed using the Murmur3 algorithm to produce a 128-bit token. This token determines the node’s responsibility for storing the data, mapping keys to a virtual ring where nodes are assigned token ranges.

To enhance fault tolerance, Cassandra supports replication across multiple nodes. In a simple setup, replicas are placed by walking the ring clockwise, but production environments often employ rack-aware strategies to avoid placing multiple replicas on the same rack, mitigating risks from power or network failures. The introduction of virtual nodes (vnodes) in later versions allows each physical node to manage multiple token ranges, typically 256 per node, which balances load more evenly and simplifies cluster management.

Adding nodes to a cluster, known as bootstrapping, involves the new node randomly selecting tokens from existing nodes, followed by data streaming to transfer relevant partitions. This process occurs without service interruption, as existing nodes continue serving requests. Such mechanisms ensure linear scalability, where doubling the number of nodes roughly doubles the cluster’s capacity.

For multi-data center deployments, Cassandra optimizes cross-data center communication by sending updates to a single replica in the remote center, which then locally replicates the data. This approach minimizes bandwidth usage across expensive wide-area networks, making it suitable for hybrid environments combining on-premises data centers with cloud providers like AWS or Google Cloud.

Handling Distributed Counters and Integration with Analytics

One of Cassandra’s innovative features is its support for distributed counters, addressing the challenge of maintaining accurate counts in a replicated system. Traditional increment operations can lead to lost updates if concurrent clients overwrite each other’s changes. Cassandra resolves this by partitioning the counter value across replicas, where each replica maintains its own sub-counter. The total value is computed by summing these partitions during reads.

This design ensures eventual consistency while allowing high-throughput updates. For instance, if a counter starts at 3 and two replicas each increment by 2, the partitions update independently, and gossip protocols propagate the changes, resulting in a final value of 7 across all replicas.

Cassandra’s integration with Hadoop further extends its utility for analytical workloads. Beyond simple input formats for MapReduce jobs, Cassandra can partition a cluster into segments for operational workloads and others for analytics, automatically handling replication between them. This setup is ideal for recommendation systems, such as suggesting related products based on purchase history, where Hadoop computes correlations and replicates results back to the operational nodes.

Advancements in Transactions and Query Language

Prior to version 2.0, Cassandra lacked traditional transactions, relying on external lock managers like ZooKeeper for atomic operations. This approach introduced complexities, such as handling client failures during lock acquisition. To address this, Cassandra introduced lightweight transactions in version 2.0, enabling conditional inserts and updates using the Paxos consensus algorithm.

Paxos ensures fault-tolerant agreement among replicas, requiring four round trips per transaction, which increases latency. Thus, lightweight transactions are recommended sparingly, only when atomicity is critical, such as ensuring unique user account creation. The syntax integrates seamlessly with Cassandra Query Language (CQL), resembling SQL but omitting joins to maintain single-node query efficiency.

CQL, introduced in version 2.0, enhances developer productivity by providing a familiar interface for schema definition and querying. It supports collections (sets, lists, maps) for denormalization, avoiding the need for joins. Version 2.1 adds user-defined types and collection indexing, allowing nested structures and queries like selecting songs containing the tag “blues.”

Implications for Application Development

Cassandra’s design choices have profound implications for building resilient applications. Its emphasis on availability and partition tolerance aligns with the CAP theorem, prioritizing these over strict consistency in distributed settings. This makes it suitable for global applications where downtime is unacceptable.

For developers, features like triggers and virtual nodes reduce operational overhead, while CQL lowers the learning curve compared to thrift-based APIs. However, challenges remain, such as managing eventual consistency and avoiding overuse of transactions to preserve performance.

In production, companies like eBay leverage Cassandra for time-series data and multi-data center setups, citing its efficiency in bandwidth-constrained environments. Adobe uses it for audience management in the cloud, processing vast datasets with high availability.

Future Directions and Conclusion

Looking ahead, Cassandra continues to evolve, with version 2.1 introducing enhancements like new keywords for collection queries and improved indexing. The beta releases indicate stability, paving the way for broader adoption.

In conclusion, Cassandra represents a paradigm shift in database technology, offering scalable, high-performance solutions for modern data challenges. Its architecture, from consistent hashing to lightweight transactions, provides a robust foundation for applications demanding reliability across distributed environments. As organizations increasingly handle big data, Cassandra’s blend of simplicity and power positions it as a cornerstone for future innovations.

Links:

PostHeaderIcon [DevoxxFR2013] Lily: Big Data for Dummies – A Comprehensive Journey into Democratizing Apache Hadoop and HBase for Enterprise Java Developers

Lecturers

Steven Noels stands as one of the most visionary figures in the evolution of open-source Java ecosystems, having co-founded Outerthought in the early 2000s with a mission to push the boundaries of content management, RESTful architecture, and scalable data systems. His flagship creation, Daisy CMS, became a cornerstone for large-scale, multilingual content platforms used by governments and global enterprises, demonstrating that Java could power mission-critical, document-centric applications at internet scale. But Noels’ ambition extended far beyond traditional CMS. Recognizing the seismic shift toward big data in the late 2000s, he pivoted Outerthought—and later NGDATA—toward building tools that would make the Apache Hadoop ecosystem accessible to the average enterprise Java developer. Lily, launched in 2010, was the culmination of this vision: a platform that wrapped the raw power of HBase and Solr into a cohesive, Java-friendly abstraction layer, eliminating the need for MapReduce expertise or deep systems programming.

Bruno Guedes, an enterprise Java architect at SFEIR with over a decade of experience in distributed systems and search infrastructure, brought the practitioner’s perspective to the stage. Having worked with Lily from its earliest alpha versions, Guedes had deployed it in production environments handling millions of records, integrating it with legacy Java EE applications, Spring-based services, and real-time analytics pipelines. His hands-on experience—debugging schema migrations, tuning SolrCloud clusters, and optimizing HBase compactions—gave him unique insight into both the promise and the pitfalls of big data adoption in conservative enterprise settings. Together, Noels and Guedes formed a perfect synergy: the visionary architect and the battle-tested engineer, delivering a presentation that was equal parts inspiration and practical engineering.

Abstract

This article represents an exhaustively elaborated, deeply extended, and comprehensively restructured expansion of Steven Noels and Bruno Guedes’ seminal 2012 DevoxxFR presentation, “Lily, Big Data for Dummies”, transformed into a definitive treatise on the democratization of big data technologies for the Java enterprise. Delivered in a bilingual format that reflected the global nature of the Apache community, the original talk introduced Lily as a groundbreaking platform that unified Apache HBase’s scalable, distributed storage with Apache Solr’s full-text search and analytics capabilities, all through a clean, type-safe Java API. The core promise was radical in its simplicity: enterprise Java developers could build petabyte-scale, real-time searchable data systems without writing a single line of MapReduce, without mastering Zookeeper quorum mechanics, and without abandoning the comforts of POJOs, annotations, and IDE autocompletion.

This expanded analysis delves far beyond the original demo to explore the philosophical foundations of Lily’s design, the architectural trade-offs in integrating HBase and Solr, the real-world production patterns that emerged from early adopters, and the lessons learned from scaling Lily to billions of records. It includes detailed code walkthroughs, performance benchmarks, schema evolution strategies, and failure mode analyses.

EDIT:
Updated for the 2025 landscape, this piece maps Lily’s legacy concepts to modern equivalents—Apache HBase 2.5, SolrCloud 9, OpenSearch, Delta Lake, Trino, and Spring Data Hadoop—while preserving the original vision of big data for the rest of us. Through rich narratives, architectural diagrams, and forward-looking speculation, this work serves not just as a historical archive, but as a practical guide for any Java team contemplating the leap into distributed, searchable big data systems.

The Big Data Barrier in 2012: Why Hadoop Was Hard for Java Developers

To fully grasp Lily’s significance, one must first understand the state of big data in 2012. The Apache Hadoop ecosystem—launched in 2006—was already a proven force in internet-scale companies like Yahoo, Facebook, and Twitter. HDFS provided fault-tolerant, distributed storage. MapReduce offered a programming model for batch processing. HBase, modeled after Google’s Bigtable, delivered random, real-time read/write access to massive datasets. And Solr, forked from Lucene, powered full-text search at scale.

Yet for the average enterprise Java developer, this stack was inaccessible. Writing a MapReduce job required:
– Learning a functional programming model in Java that felt alien to OO practitioners.
– Mastering job configuration, input/output formats, and partitioners.
– Debugging distributed failures across dozens of nodes.
– Waiting minutes to hours for job completion.

HBase, while promising real-time access, demanded:
– Manual row key design to avoid hotspots.
– Deep knowledge of compaction, splitting, and region server tuning.
– Integration with Zookeeper for coordination.

Solr, though more familiar, required:
– Separate schema.xml and solrconfig.xml files.
– Manual index replication and sharding.
– Complex commit and optimization strategies.

The result? Big data remained the domain of specialized data engineers, not the Java developers who built the business logic. Lily was designed to change that.

Lily’s Core Philosophy: Big Data as a First-Class Java Citizen

At its heart, Lily was built on a simple but powerful idea: big data should feel like any other Java persistence layer. Just as Spring Data made MongoDB, Cassandra, or Redis accessible via repositories and annotations, Lily aimed to make HBase and Solr feel like JPA with superpowers.

The Three Pillars of Lily

Steven Noels articulated Lily’s architecture in three interconnected layers:

  1. The Storage Layer (HBase)
    Lily used HBase as its primary persistence engine, storing all data as versioned, column-family-based key-value pairs. But unlike raw HBase, Lily abstracted away row key design, column family management, and versioning policies. Developers worked with POJOs, and Lily handled the mapping.

  2. The Indexing Layer (Solr)
    Every mutation in HBase triggered an asynchronous indexing event to Solr. Lily maintained tight consistency between the two systems, ensuring that search results reflected the latest data within milliseconds. This was achieved through a message queue (Kafka or RabbitMQ) and idempotent indexing.

  3. The Java API Layer
    The crown jewel was Lily’s type-safe, annotation-driven API. Developers defined their data model using plain Java classes:

@LilyRecord
public class Customer {
    @LilyId
    private String id;

    @LilyField(family = "profile")
    private String name;

    @LilyField(family = "profile")
    private int age;

    @LilyField(family = "activity", indexed = true)
    private List<String> recentSearches;

    @LilyFullText
    private String bio;
}

The @LilyRecord annotation told Lily to persist this object in HBase. @LilyField specified column families and indexing behavior. @LilyFullText triggered Solr indexing. No XML. No schema files. Just Java.

The Lily Repository: Spring Data, But for Big Data

Lily’s LilyRepository interface was modeled after Spring Data’s CrudRepository, but with big data superpowers:

public interface CustomerRepository extends LilyRepository<Customer, String> {
    List<Customer> findByName(String name);

    @Query("age:[* TO 30]")
    List<Customer> findYoungCustomers();

    @Query("bio:java AND recentSearches:hadoop")
    List<Customer> findJavaHadoopEnthusiasts();
}

Behind the scenes, Lily:
– Translated method names to HBase scans.
– Converted @Query annotations to Solr queries.
– Executed searches across sharded SolrCloud clusters.
– Returned fully hydrated POJOs.

Bruno Guedes demonstrated this in a live demo:

CustomerRepository repo = lily.getRepository(CustomerRepository.class);
repo.save(new Customer("1", "Alice", 28, Arrays.asList("java", "hadoop"), "Java dev at NGDATA"));
List<Customer> results = repo.findJavaHadoopEnthusiasts();

The entire operation—save, index, search—took under 50ms on a 3-node cluster.

Under the Hood: How Lily Orchestrated HBase and Solr

Lily’s magic was in its orchestration layer. When a save() was called:
1. The POJO was serialized to HBase Put operations.
2. The mutation was written to HBase with a version timestamp.
3. A change event was published to a message queue.
4. A Solr indexer consumed the event and updated the search index.
5. Near-real-time consistency was guaranteed via HBase’s WAL and Solr’s soft commits.

For reads:
findById → HBase Get.
findByName → HBase scan with secondary index.
@Query → Solr query with HBase post-filtering.

This dual-write, eventual consistency model was a deliberate trade-off for performance and scalability.

Schema Evolution and Versioning: The Enterprise Reality

One of Lily’s most enterprise-friendly features was schema evolution. In HBase, adding a column family requires manual admin intervention. In Lily, it was automatic:

// Version 1
@LilyField(family = "profile")
private String email;

// Version 2
@LilyField(family = "profile")
private String phone; // New field, no migration needed

Lily stored multiple versions of the same record, allowing old code to read new data and vice versa. This was critical for rolling deployments in large organizations.

Production Patterns and Anti-Patterns

Bruno Guedes shared war stories from production:
Hotspot avoidance: Never use auto-incrementing IDs. Use hashed or UUID-based keys.
Index explosion: @LilyFullText on large fields → Solr bloat. Use @LilyField(indexed = true) for structured search.
Compaction storms: Schedule major compactions during low traffic.
Zookeeper tuning: Increase tick time for large clusters.

The Lily Ecosystem in 2012

Lily shipped with:
Lily CLI for schema inspection and cluster management.
Lily Maven Plugin for deploying schemas.
Lily SolrCloud Integration with automatic sharding.
Lily Kafka Connect for streaming data ingestion.

Lily’s Legacy After 2018: Where the Ideas Live On

EDIT
Although Lily itself was archived in 2018, its core concepts continue to thrive in modern tools.

The original HBase POJO mapping is now embodied in Spring Data Hadoop.

Lily’s Solr integration has evolved into SolrJ + OpenSearch.

The repository pattern that Lily pioneered is carried forward by Spring Data R2DBC.

Schema evolution, once a key Lily feature, is now handled by Apache Atlas.

Finally, Lily’s near-real-time search capability lives on through the Elasticsearch Percolator.

Conclusion: Big Data Doesn’t Have to Be Hard

Steven Noels closed with a powerful message:

“Big data is not about MapReduce. It’s not about Zookeeper. It’s about solving business problems at scale. Lily proved that Java developers can do that—without becoming data engineers.”

EDIT:
In 2025, as lakehouse architectures, real-time analytics, and AI-driven search dominate, Lily’s vision of big data as a first-class Java citizen remains more relevant than ever.

Links

PostHeaderIcon [DevoxxFR2013] MongoDB and Mustache: Toward the Death of the Cache? A Comprehensive Case Study in High-Traffic, Real-Time Web Architecture

Lecturers

Mathieu Pouymerol and Pierre Baillet were the technical backbone of Fotopedia, a photo-sharing platform that, at its peak, served over five million monthly visitors using a Ruby on Rails application that had been in production for six years. Mathieu, armed with degrees from École Centrale Paris and a background in building custom data stores for dictionary publishers, brought a deep understanding of database design, indexing, and performance optimization. Pierre, also from Centrale and with experience at Cambridge, had spent nearly a decade managing infrastructure, tuning Tomcat, configuring memcached, and implementing geoDNS systems. Together, they faced the ultimate challenge: keeping a legacy Rails monolith responsive under massive, unpredictable traffic while maintaining content freshness and developer velocity.

Abstract

This article presents an exhaustively detailed expansion of Mathieu Pouymerol and Pierre Baillet’s 2012 DevoxxFR presentation, “MongoDB et Mustache, vers la mort du cache ?”, reimagined as a definitive case study in high-traffic web architecture and the evolution of caching strategies. The Fotopedia team inherited a Rails application plagued by slow ORM queries, complex cache invalidation logic, and frequent stale data. Their initial response—edge-side includes (ESI), fragment caching, and multi-layered memcached—bought time but introduced fragility and operational overhead. The breakthrough came from a radical rethinking: use MongoDB as a real-time document store and Mustache as a logic-less templating engine to assemble pages dynamically, eliminating cache for the most volatile content.

This analysis walks through every layer of their architecture: from database schema design to template composition, from CDN integration to failure mode handling. It includes performance metrics, post-mortem analyses, and lessons learned from production incidents. Updated for 2025, it maps their approach to modern tools: MongoDB 7.0 with Atlas, server-side rendering with HTMX, edge computing via Cloudflare Workers, and Spring Boot with Mustache, offering a complete playbook for building cache-minimized, real-time web applications at scale.

The Legacy Burden: A Rails Monolith Under Siege

Fotopedia’s core application was built on Ruby on Rails 2.3, a framework that, while productive for startups, began to show its age under heavy load. The database layer relied on MySQL with aggressive sharding and replication, but ActiveRecord queries were slow, and joins across shards were impractical. The presentation layer used ER 15–20 partials per page, each with its own caching logic. The result was a cache dependency graph so complex that a single user action—liking a photo—could invalidate dozens of cache keys across multiple servers.

The team’s initial strategy was defense in depth:
Varnish at the edge with ESI for including dynamic fragments.
Memcached for fragment and row-level caching.
Custom invalidation daemons to purge stale cache entries.

But this created a house of cards. A missed invalidation led to stale comments. A cache stampede during a traffic spike brought the database to its knees. As Pierre put it, “We were not caching to improve performance. We were caching to survive.”

The Paradigm Shift: Real-Time Data with MongoDB

The turning point came when the team migrated dynamic, user-generated content—photos, comments, tags, likes—to MongoDB. Unlike MySQL, MongoDB stored data as flexible JSON-like documents, allowing embedded arrays and atomic updates:

{
  "_id": "photo_123",
  "title": "Sunset",
  "user_id": "user_456",
  "tags": ["paris", "sunset"],
  "likes": 1234,
  "comments": [
    { "user": "Alice", "text": "Gorgeous!", "timestamp": "2013-04-01T12:00:00Z" }
  ]
}

This schema eliminated joins and enabled single-document reads for most pages. Updates used atomic operators:

db.photos.updateOne(
  { _id: "photo_123" },
  { $inc: { likes: 1 }, $push: { comments: { user: "Bob", text: "Nice!" } } }
);

Indexes on user_id, tags, and timestamp ensured sub-millisecond query performance.

Mustache: The Logic-Less Templating Revolution

The second pillar was Mustache, a templating engine that enforced separation of concerns by allowing no logic in templates—only iteration and conditionals:

{{#photo}}
  <h1>{{title}}</h1>
  <img src="{{url}}" alt="{{title}}" />
  <p>By {{user.name}} • {{likes}} likes</p>
  <ul class="comments">
    {{#comments}}
      <li><strong>{{user}}</strong>: {{text}}</li>
    {{/comments}}
  </ul>
{{/photo}}

Because templates contained no business logic, they could be cached indefinitely in Varnish. Only the data changed—and that came fresh from MongoDB on every request.

data = mongo.photos.find(_id: params[:id]).first
html = Mustache.render(template, data)

The Hybrid Architecture: Cache Where It Makes Sense

The final system was a hybrid of caching and real-time rendering:
Static assets (CSS, JS, images) → CDN with long TTL.
Static page fragments (headers, footers, sidebars) → Varnish ESI with 1-hour TTL.
Dynamic content (photo, comments, likes) → MongoDB + Mustache, no cache.

This reduced cache invalidation surface by 90% and average response time from 800ms to 180ms.

2025: The Evolution of Cache-Minimized Architecture

EDIT:
The principles pioneered by Fotopedia are now mainstream:
Server-side rendering with HTMX for dynamic updates.
Edge computing with Cloudflare Workers to assemble pages.
MongoDB Atlas with change streams for real-time UIs.
Spring Boot + Mustache for Java backends.

Links

PostHeaderIcon [DevoxxBE2013] CQRS for Great Good

Oliver Wolf, principal consultant and executive board member at INNOQ, challenges conventional architectures with CQRS (Command-Query Responsibility Segregation). A SOA and Java expert, Oliver traces CQRS’s evolution from CQS, demonstrating incremental adoption—from read-write separation to event sourcing. His session, enriched with examples, equips developers to rethink data flows, optimizing for asymmetric workloads in banking and beyond.

CQRS decouples commands (writes) from queries (reads), enabling tailored models. Oliver illustrates phased implementation, culminating in event-sourced systems for auditability and scalability.

From CQS to CQRS: Foundational Concepts

Oliver recalls CQS—Bertrand Meyer’s principle segregating mutators from inspectors. CQRS extends this, allowing distinct read/write models. He demos a simple e-commerce app, splitting a unified model into command (order placement) and query (inventory views).

This separation, Oliver explains, resolves impedance mismatches, enhancing performance.

Incremental Adoption Strategies

Phased rollout minimizes risk: start with asymmetric databases, Oliver advises, using separate stores for reads/writes. He showcases materialized views, syncing via background jobs.

Advanced steps introduce event sourcing: commands emit events, replayed for state reconstruction, ensuring immutability.

Event Sourcing and Distribution

Event sourcing captures changes as immutable logs, Oliver illustrates, rebuilding state on demand. Distribution follows: client/server variants, with web frontends querying dedicated services.

In banking, Oliver notes, CQRS optimizes configurable systems, balancing risk with extensibility.

Guidelines for Application

Oliver urges starting small: identify read-heavy operations, segregate gradually. Avoid over-engineering; CQRS suits complex domains, not simple CRUD.

Community examples, he shares, validate phased approaches, with INNOQ projects exploring hybrid models.

Links:

PostHeaderIcon [DevoxxFR2013] Clean JavaScript? Challenge Accepted: Strategies for Maintainable Large-Scale Applications

Lecturer

Romain Linsolas is a Java developer with over two decades of experience, passionate about technical innovation. He has worked at the CNRS on an astrophysics project, as a consultant at Valtech, and as a technical leader at Société Générale. Romain is actively involved in the developpez.com community as a writer and moderator, and he focuses on continuous integration principles to automate and improve team processes. Julien Jakubowski is a consultant and lead developer at OCTO Technology, with a decade of experience helping teams deliver high-quality software efficiently. He co-founded the Ch’ti JUG in Lille and has organized the Agile Tour Lille for two years.

Abstract

This article analyzes Romain Linsolas and Julien Jakubowski’s exploration of evolving JavaScript from rudimentary scripting to robust, large-scale application development. By dissecting historical pitfalls and modern solutions, the discussion evaluates architectural patterns, testing frameworks, and automation tools that enable clean, maintainable code. Contextualized within the shift from server-heavy Java applications to client-side dynamism, the analysis assesses methodologies for avoiding common errors, implications for developer productivity, and challenges in integrating diverse ecosystems. Through practical examples, it illustrates how JavaScript can support complex projects without compromising quality.

Historical Pitfalls and the Evolution of JavaScript Practices

JavaScript’s journey from a supplementary tool in the early 2000s to a cornerstone of modern web applications reflects broader shifts in user expectations and technology. Initially, developers like Romain and Julien used JavaScript for minor enhancements, such as form validations or visual effects, within predominantly Java-based server-side architectures. A typical 2003 example involved inline scripts to check input fields, turning them red on errors and preventing form submission. However, this approach harbored flaws: global namespace pollution from duplicated function names across files, implicit type coercions leading to unexpected concatenations instead of additions (e.g., “100” + 0.19 yielding “1000.19”), and public access to supposedly private variables, breaking encapsulation.

These issues stem from JavaScript’s design quirks, often labeled “dirty” due to surprising behaviors like empty array additions resulting in strings or NaN (Not a Number). Romain’s demonstrations, inspired by Gary Bernhardt’s critiques, highlight arithmetic anomalies where [] + {} equals “[object Object]” but {} + [] yields 0. Such inconsistencies, while entertaining, pose real risks in production code, as seen in scope leakage where loop variables overwrite each other, printing values only 10 times instead of 100.

The proliferation of JavaScript-driven applications, fueled by innovations from Gmail and Google Docs, necessitated more code—potentially 100,000 lines—demanding structured approaches. Early reliance on frameworks like Struts for server logic gave way to client-side demands for offline functionality and instant responsiveness, compelling developers to confront JavaScript’s limitations head-on.

Architectural Patterns for Scalable Code

To tame JavaScript’s chaos, modular architectures inspired by Model-View-Controller (MVC) patterns emerge as key. Frameworks like Backbone.js, AngularJS, and Ember.js facilitate separation of concerns: models handle data, views manage UI, and controllers orchestrate logic. For instance, in a beer store application, an MVC setup might use Backbone to define a Beer model with validation, a BeerView for rendering, and a controller to handle additions.

Modularization via patterns like the Module Pattern encapsulates code, preventing global pollution. A counter example encapsulates a private variable:

var Counter = (function() {
    var privateCounter = 0;
    function changeBy(val) {
        privateCounter += val;
    }
    return {
        increment: function() {
            changeBy(1);
        },
        value: function() {
            return privateCounter;
        }
    };
})();

This ensures privacy, unlike direct access in naive implementations. Advanced libraries like RequireJS implement Asynchronous Module Definition (AMD), loading dependencies on demand to avoid conflicts.

Expressivity is boosted by frameworks like CoffeeScript, which compiles to JavaScript with cleaner syntax, or Underscore.js for functional utilities. Julien’s analogy to appreciating pungent cheese after initial aversion captures the learning curve: mastering these tools reveals JavaScript’s elegance.

Testing and Automation for Reliability

Unit testing, absent in early practices, is now feasible with frameworks like Jasmine, adopting Behavior-Driven Development (BDD). Specs describe behaviors clearly:

describe("Beer addition", function() {
    it("should add a beer with valid name", function() {
        var beer = new Beer({name: "IPA"});
        expect(beer.isValid()).toBe(true);
    });
});

Tools like Karma run tests in real browsers, while Istanbul measures coverage. Automation integrates via Maven, Jenkins, or SonarQube, mirroring Java workflows. Violations from JSLint or compilation errors from Google Closure Compiler are flagged, ensuring syntax integrity.

Yeoman, combining Yo (scaffolding), Grunt (task running), and Bower (dependency management), streamlines setup. IDEs like IntelliJ or WebStorm provide seamless support, with Chrome DevTools for debugging.

Ongoing Challenges and Future Implications

Despite advancements, integration remains complex: combining MVC frameworks with testing suites requires careful orchestration, often involving custom recipes. Perennial concerns include framework longevity—Angular vs. Backbone—and team upskilling, demanding substantial training investments.

The implications are profound: clean JavaScript enables scalable, responsive applications, bridging Java developers into full-stack roles. By avoiding pitfalls through patterns and tools, projects achieve maintainability, reducing long-term costs. However, the ecosystem’s youth demands vigilance, as rapid evolutions could obsolete choices.

In conclusion, JavaScript’s transformation empowers developers to tackle ambitious projects confidently, blending familiarity with innovation for superior outcomes.

Links:

PostHeaderIcon MultiException[java.lang.RuntimeException: Error scanning file]

Case

I run a project with JSF 2 / PrimeFaces 5 (BTW: it rocks!) / Spring 4 / Jetty 9 / Java 8:
[java]MultiException java.lang.RuntimeException: Error scanning file SummerBean.class, java.lang.RuntimeException: Error scanning entry …/SummerService.class from jar file:/…/spring-tier-1.0-SNAPSHOT.jar, java.lang.RuntimeException: Error scanning entry …/SummerServiceImpl.class from jar file:/…/spring-tier-1.0-SNAPSHOT.jar
at org.eclipse.jetty.annotations.AnnotationConfiguration.scanForAnnotations(AnnotationConfiguration.java:530)[/java]

Explanation

The error occurs because of a conflict on the JARs of ASM.

Fix

You have to override Jetty’s dependencies to ASM.
In Maven’s POM, amend Jetty plugin to force ASM versions:
[xml]<plugin>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-maven-plugin</artifactId>
<version>${jetty.version}</version>
<dependencies>
<dependency>
<groupId>org.ow2.asm</groupId>
<artifactId>asm</artifactId>
<version>5.0.2</version>
</dependency>
<dependency>
<groupId>org.ow2.asm</groupId>
<artifactId>asm-commons</artifactId>
<version>5.0.2</version>
</dependency>
</dependencies>
<!– … –>
</plugin>
[/xml]

Then it should work 😉

PostHeaderIcon [DevoxxBE2013] OpenShift Primer: Get Your Applications into the Cloud

Eric D. Schabell, JBoss technology evangelist at Red Hat, demystifies OpenShift, a PaaS revolutionizing cloud deployment for Java EE, PHP, Ruby, and beyond. Author of the OpenShift Primer e-book, Eric—drawing from his integration and BPM expertise—guides attendees through rapid app migration, showcasing portability without code rewrites. His action-packed session deploys a Java project in minutes, contrasting OpenShift’s ease with cumbersome VMs.

OpenShift’s open-source ethos, Eric argues, delivers developer freedom: Git-based workflows, auto-scaling gears, and cartridge-based runtimes. From free tiers to enterprise scalability, it transforms cloud adoption, with European data centers addressing latency and privacy concerns.

Demystifying PaaS and OpenShift Fundamentals

Eric contrasts IaaS’s VM drudgery with PaaS’s streamlined abstraction. OpenShift, atop Red Hat Enterprise Linux, provisions environments via cartridges—pre-configured stacks for languages like Java.

He demos creating an app: rhc app create, Git push, and instant deployment, emphasizing no vendor lock-in.

Rapid Deployment and Portability

Portability reigns: Eric deploys a legacy Java EE app unchanged, leveraging JBoss EAP cartridges. PHP/Ruby examples follow, highlighting multi-language support.

This agnosticism, Eric notes, preserves investments, scaling from localhost to cloud seamlessly.

Scaling, Monitoring, and Security

Auto-scaling gears adjust to loads, Eric illustrates, with hot-deploy for zero-downtime updates. Monitoring via console tracks metrics; security integrates LDAP and SSL.

For Europe, Irish data centers mitigate latency, with GDPR-compliant options addressing data sovereignty.

Why OpenShift? Open-Source Advantages

Eric’s pitch: unmatched ease, no code changes, and open-source values. Free tiers on AWS East Coast suit demos, with paid plans offering local regions like Ireland.

He invites booth chats, contrasting OpenShift’s speed with competitors’ rigidity.

Links:

PostHeaderIcon [DevoxxFR2013] From Cloud Experimentation to On-Premises Maturity: Strategic Infrastructure Repatriation at Mappy

Lecturer

Cyril Morcrette serves as Technical Director at Mappy, a pioneering French provider of geographic and local commerce services with thirteen million euros in annual revenue and eighty employees. Under his leadership, Mappy has evolved from a traditional route planning service into a comprehensive platform integrating immersive street-level imagery, local business discovery, and personalized recommendations. His infrastructure strategy reflects deep experience with both cloud and on-premises environments, informed by multiple large-scale projects that pushed technological boundaries.

Abstract

Cloud computing excels at enabling rapid prototyping and handling uncertain demand, but its cost structure can become prohibitive as projects mature and usage patterns stabilize. This presentation chronicles Mappy’s journey with immersive geographic visualization — a direct competitor to Google Street View — from initial cloud deployment to eventual repatriation to on-premises infrastructure. Cyril Morcrette examines the economic, operational, and technical factors that drove this decision, providing a framework for evaluating infrastructure choices throughout the application lifecycle. Through detailed cost analysis, performance metrics, and migration case studies, he demonstrates that cloud is an ideal launch platform but often not the optimal long-term home for predictable, high-volume workloads. The session concludes with practical guidance for smooth repatriation and the broader implications for technology strategy in established organizations.

The Immersive Visualization Imperative

Mappy’s strategic pivot toward immersive geographic experiences required capabilities beyond traditional mapping: panoramic street-level imagery, 3D reconstruction, and real-time interaction. The project demanded massive storage (terabytes of high-resolution photos), significant compute for image processing, and low-latency delivery to users.

Initial estimates suggested explosive, unpredictable traffic growth. Marketing teams envisioned viral adoption, while technical teams worried about infrastructure bottlenecks. Procuring sufficient on-premises hardware would require months of lead time and capital approval — unacceptable for a market-moving initiative.

Amazon Web Services offered an immediate solution: spin up instances, store petabytes in S3, process imagery with EC2 spot instances. The cloud’s pay-as-you-go model eliminated upfront investment and provided virtually unlimited capacity.

Cloud-First Development: Speed and Agility

The project launched entirely in AWS. Development teams used EC2 for processing pipelines, S3 for raw and processed imagery, CloudFront for content delivery, and Elastic Load Balancing for web servers. Auto-scaling handled traffic spikes during marketing campaigns.

This environment enabled rapid iteration:
– Photographers uploaded imagery directly to S3 buckets
– Lambda functions triggered processing workflows
– Machine learning models (running on GPU instances) detected business facades and extracted metadata
– Processed panoramas were cached in CloudFront edge locations

Within months, Mappy delivered a functional immersive experience covering major French cities. The cloud’s flexibility absorbed the uncertainty of early adoption while development teams refined algorithms and user interfaces.

The Economics of Maturity

As the product stabilized, usage patterns crystallized. Daily active users grew steadily but predictably. Storage requirements, while large, increased linearly. Processing workloads became batch-oriented rather than real-time.

Cost analysis revealed a stark reality: cloud expenses were dominated by data egress, storage, and compute hours — all now predictable and substantial. Mappy’s existing data center, built for core mapping services, had significant spare capacity with fully amortized hardware.

Cyril presents the tipping point calculation:
Cloud monthly cost: €45,000 (storage, compute, bandwidth)
On-premises equivalent: €12,000 (electricity, maintenance, depreciation)
Break-even: four months

The decision to repatriate was driven by simple arithmetic, but execution required careful planning.

Repatriation Strategy and Execution

The migration followed a phased approach:

  1. Data Transfer: Used AWS Snowball devices to move petabytes of imagery back to on-premises storage. Parallel uploads leveraged Mappy’s high-bandwidth connectivity.

  2. Processing Pipeline: Reimplemented image processing workflows on internal GPU clusters. Custom scripts replaced Lambda functions, achieving equivalent throughput at lower cost.

  3. Web Tier: Deployed Nginx and Varnish caches on existing web servers. CDN integration with Akamai preserved low-latency delivery.

  4. Monitoring and Automation: Migrated CloudWatch metrics to Prometheus/Grafana. Ansible playbooks replaced CloudFormation templates.

Performance remained comparable: page load times stayed under two seconds, and system availability exceeded 99.95%. The primary difference was cost — reduced by seventy-five percent.

Operational Benefits of On-Premises Control

Beyond economics, repatriation delivered strategic advantages:
Data Sovereignty: Full control over sensitive geographic imagery
Performance Predictability: Eliminated cloud provider throttling risks
Integration Synergies: Shared infrastructure with core mapping services reduced operational complexity
Skill Leverage: Existing systems administration expertise applied directly

Cyril notes that while cloud elasticity was lost, the workload’s maturity rendered it unnecessary. Capacity planning became straightforward, with hardware refresh cycles aligned to multi-year budgets.

Lessons for Infrastructure Strategy

Mappy’s experience yields a generalizable framework:
1. Use cloud for uncertainty: Prototyping, viral growth potential, or seasonal spikes
2. Monitor cost drivers: Storage, egress, compute hours
3. Model total cost of ownership: Include migration effort and operational overhead
4. Plan repatriation paths: Design applications with infrastructure abstraction
5. Maintain hybrid capability: Keep cloud skills current for future needs

The cloud is not a destination but a tool — powerful for certain phases, less optimal for others.

Conclusion: Right-Sizing Infrastructure for Business Reality

Mappy’s journey from cloud experimentation to on-premises efficiency demonstrates that infrastructure decisions must evolve with product maturity. The cloud enabled rapid innovation and market entry, but long-term economics favored internal hosting for stable, high-volume workloads. Cyril’s analysis provides a blueprint for technology leaders to align infrastructure with business lifecycle stages, avoiding the trap of cloud religion or on-premises dogma. The optimal stack combines both environments strategically, using each where it delivers maximum value.

Links:

PostHeaderIcon [DevoxxFR2013] Developing Modern Web Apps with Backbone.js: A Live-Coded Journey from Empty Directory to Production-Ready SPA

Lecturer

Sylvain Zimmer represents the rare fusion of hacker spirit and entrepreneurial vision. In 2004, he launched Jamendo, which grew into the world’s largest platform for Creative Commons-licensed music, proving that open content could sustain a viable business model and empower artists globally. He co-founded Joshfire, a Paris-based agency specializing in connected devices and IoT solutions, and TEDxParis, democratizing access to transformative ideas. His competitive prowess shone in 2011 when his team won the Node Knockout competition in the Completeness category with Chess@home — a fully distributed chess AI implemented entirely in JavaScript, showcasing the language’s maturity for complex, real-time systems. Recognized as one of the first Google Developer Experts for HTML5, Sylvain recently solved a cryptographically hidden equation embedded in a Chromebook advertisement, demonstrating his blend of technical depth and puzzle-solving acumen. His latest venture, Pressing, continues his pattern of building elegant, user-centric solutions that bridge technology and human needs.

Abstract

In this intensely practical, code-only presentation, Sylvain Zimmer constructs a fully functional single-page application using Backbone.js from an empty directory to a polished, interactive demo in under thirty minutes. He orchestrates a modern frontend toolchain including Yeoman for project scaffolding, Grunt for task automation, LiveReload for instantaneous feedback, RequireJS for modular dependency management, and a curated selection of Backbone extensions to address real-world complexity. The session is a masterclass in architectural decision-making, demonstrating how to structure code for maintainability, scalability, and testability while avoiding the pitfalls of framework bloat. Attendees witness the evolution of a simple task manager into a sophisticated, real-time collaborative application, learning not just Backbone’s core MVC patterns but the entire ecosystem of best practices that define professional frontend engineering in the modern web era.

The Modern Frontend Development Loop: Zero Friction from Code to Browser

Sylvain initiates the journey with yo backbone, instantly materializing a complete project structure:

app/
  scripts/
    models/      collections/      views/      routers/
  styles/
  index.html
  Gruntfile.js

This scaffold is powered by Yeoman, which embeds Grunt as the task runner and LiveReload for automatic browser refresh. Every file save triggers a cascade of actions — CoffeeScript compilation, Sass preprocessing, JavaScript minification, and live injection into the browser — creating a development feedback loop with near-zero latency. This environment is not a convenience; it is a fundamental requirement for maintaining flow state and rapid iteration in modern web development.

Backbone Core Concepts: Models, Collections, Views, and Routers in Harmony

The application begins with a Task model that encapsulates state and behavior:

var Task = Backbone.Model.extend({
  defaults: {
    title: '',
    completed: false,
    priority: 'medium'
  },
  toggle: function() {
    this.save({ completed: !this.get('completed') });
  },
  validate: function(attrs) {
    if (!attrs.title.trim()) return "Title required";
  }
});

A TaskList collection manages persistence and business logic:

var TaskList = Backbone.Collection.extend({
  model: Task,
  localStorage: new Backbone.LocalStorage('tasks-backbone'),
  completed: function() { return this.where({completed: true}); },
  remaining: function() { return this.where({completed: false}); },
  comparator: 'priority'
});

The TaskView handles rendering and interaction using Underscore templates:

var TaskView = Backbone.View.extend({
  tagName: 'li',
  template: _.template($('#task-template').html()),
  events: {
    'click .toggle': 'toggleCompleted',
    'dblclick label': 'edit',
    'blur .edit': 'close',
    'keypress .edit': 'updateOnEnter'
  },
  initialize: function() {
    this.listenTo(this.model, 'change', this.render);
    this.listenTo(this.model, 'destroy', this.remove);
  },
  render: function() {
    this.$el.html(this.template(this.model.toJSON()));
    this.$el.toggleClass('completed', this.model.get('completed'));
    return this;
  }
});

An AppRouter enables clean URLs and state management:

var AppRouter = Backbone.Router.extend({
  routes: {
    '': 'index',
    'tasks/:id': 'show',
    'filter/:status': 'filter'
  },
  index: function() { /* render all tasks */ },
  filter: function(status) { /* update collection filter */ }
});

RequireJS: Enforcing Modularity and Asynchronous Loading Discipline

Global scope pollution is eradicated through RequireJS, configured in main.js:

require.config({
  paths: {
    'jquery': 'libs/jquery',
    'underscore': 'libs/underscore',
    'backbone': 'libs/backbone',
    'localstorage': 'libs/backbone.localStorage'
  },
  shim: {
    'underscore': { exports: '_' },
    'backbone': { deps: ['underscore', 'jquery'], exports: 'Backbone' }
  }
});

Modules are defined with explicit dependencies:

define(['views/task', 'collections/tasks'], function(TaskView, taskList) {
  return new TaskView({ collection: taskList });
});

This pattern ensures lazy loading, parallel downloads, and clear dependency graphs, critical for performance in large applications.

Backbone Extensions: Scaling from Prototype to Enterprise with Targeted Plugins

Backbone’s minimalism is a feature, not a limitation. Sylvain integrates extensions judiciously:

  • Backbone.LayoutManager: Manages nested views and layout templates, preventing memory leaks
  • Backbone.Paginator: Implements infinite scrolling with server or client pagination
  • Backbone.Relational: Handles one-to-many and many-to-many relationships with cascading saves
  • Backbone.Validation: Enforces model constraints with customizable error messages
  • Backbone.Stickit: Provides declarative two-way data binding for forms
  • Backbone.IOBind: Synchronizes models in real-time via Socket.IO

He demonstrates a live collaboration feature: when one user completes a task, a WebSocket event triggers an immediate UI update for all connected clients, showcasing real-time capabilities without server polling.

Architectural Best Practices: Building for the Long Term

The final application adheres to rigorous principles:

  • Single responsibility principle: Each view manages exactly one DOM element
  • Event-driven architecture: No direct DOM manipulation outside views
  • Separation of concerns: Models handle business logic, views handle presentation
  • Testability: Components are framework-agnostic and unit-testable with Jasmine or Mocha
  • Progressive enhancement: Core functionality works without JavaScript

Sylvain stresses that Backbone is a foundation, not a monolith — choose extensions based on specific needs, not trends.

Ecosystem and Learning Resources

He recommends Addy Osmani’s Backbone Fundamentals as the definitive free guide, the official Backbone.js documentation for reference, and GitHub for discovering community plugins. Tools like Marionette.js (application framework) and Thorax (Handlebars integration) are highlighted for larger projects.

The Broader Implications: Backbone in the Modern Frontend Landscape

While newer frameworks like Angular and React dominate headlines, Backbone remains relevant for its predictability, flexibility, and small footprint. It teaches fundamental MVC patterns that translate to any framework. Sylvain positions it as ideal for teams needing fine-grained control, gradual adoption, or integration with legacy systems.

Conclusion: From Demo to Deployable Reality

In under thirty minutes, Sylvain has built a production-ready SPA with real-time collaboration, offline storage, and modular architecture. He challenges attendees to fork the code, extend it, and ship something real. The tools are accessible, the patterns are proven, and the only barrier is action.

Links

PostHeaderIcon [DevoxxBE2013] Introducing Vert.x 2.0: Taking Polyglot Application Development to the Next Level

Tim Fox, the visionary project lead for Vert.x at Red Hat, charts the course of this lightweight, high-performance application platform for the JVM. With a storied tenure at JBoss and VMware—where he spearheaded HornetQ messaging and RabbitMQ integrations—Tim unveils Vert.x 2.0’s maturation into an independent powerhouse. His session delves into the revamped module system, Maven/Bintray reusability, and enhanced build tool/IDE synergy, alongside previews of Scala, Clojure support, and Node.js compatibility.

Vert.x 2.0 empowers polyglot, reactive applications, blending asynchronous eventing with synchronous legacy APIs via worker verticles. Tim’s live demos illustrate deploying modules dynamically, underscoring Vert.x’s ecosystem for mobile, web, and enterprise scalability.

Core API Refinements and Asynchronous Foundations

Tim highlights Vert.x’s event-driven core, refined in 2.0 with intuitive APIs for non-JVM languages. He demonstrates verticles—lightweight actors—for handling requests asynchronously, avoiding blocking calls.

This reactive model, Tim explains, scales to thousands of connections, ideal for real-time web apps, contrasting traditional thread-per-request pitfalls.

Module System and Ecosystem Expansion

The new module system, Tim showcases, leverages Maven repositories for seamless dependency management. He deploys a web server via module names, pulling artifacts from Bintray—eliminating manual installations.

This reusability fosters a vibrant ecosystem, with core modules for HTTP, MySQL (via reversed-engineered async drivers), and more, enabling rapid composition.

Build Tool and IDE Integration

Vert.x 2.0’s Maven/Gradle plugins streamline development, as Tim demos: configure a pom.xml, run mvn vertx:run, and launch a cluster. IDE support, via plugins, offers hot-reloading and debugging.

These integrations, Tim notes, lower barriers, allowing developers to iterate swiftly without Vert.x-specific tooling.

Polyglot Horizons: Scala, Clojure, and Node.js

Tim previews Scala/Clojure bindings, enabling functional paradigms on Vert.x’s event bus. Node.js compatibility, via drop-in modules, bridges JavaScript ecosystems, allowing polyglot teams to collaborate seamlessly.

This inclusivity, Tim asserts, broadens Vert.x’s appeal, supporting diverse languages without sacrificing performance.

Worker Verticles for Legacy Compatibility

For synchronous APIs like JDBC, Tim introduces worker verticles—executing on thread pools to prevent blocking. He contrasts with pure async MySQL drivers, offering flexibility for hybrid applications.

This pragmatic bridge, Tim emphasizes, integrates existing Java libraries effortlessly.

Links: