You are on page 1of 617

Infinispan 6.

Home

Exported from JBoss Community Documentation Editor at 2015-05-25 10:53:46 EDT


Copyright 2013 JBoss Community contributors.

JBoss Community Documentation

Page 1 of 617

Infinispan 6.0

Table of Contents
1 More Resources ___________________________________________________________________ 17
2 Getting Started Guide _______________________________________________________________ 18
2.1 Introduction ___________________________________________________________________ 19
2.2 Downloading and installing Infinispan _______________________________________________ 20
2.3 Infinispan in action - GUIDemo ____________________________________________________ 20
2.4 Using Infinispan as an embedded cache in Java SE ___________________________________ 20
2.4.1 Creating a new Infinispan project _____________________________________________ 20
2.4.2 Running Infinispan on a single node __________________________________________ 23
2.4.3 Use the default cache _____________________________________________________ 24
2.4.4 Use a custom cache _______________________________________________________ 25
2.5 Using Infinispan as an embedded data grid in Java SE _________________________________ 25
2.5.1 Running Infinispan in a cluster _______________________________________________ 26
2.5.2 Configuring the cluster _____________________________________________________ 30
2.5.3 Configuring a replicated data-grid ____________________________________________ 31
2.5.4 Configuring a distributed data-grid ____________________________________________ 32
2.6 Creating your own Infinispan project ________________________________________________ 32
2.7 Using Infinispan as a second level cache for Hibernate _________________________________ 32
2.8 Accessing an Infinispan data grid remotely ___________________________________________ 33
2.8.1 Using Hot Rod to access an Infinispan data-grid _________________________________ 33
2.8.2 Using REST to access an Infinipsan data-grid ___________________________________ 33
2.8.3 Using memcached to access an Infinispan data-grid ______________________________ 33
2.9 Using Infinispan in JBoss AS 7 ____________________________________________________ 33
2.10 Using Infinispan in servlet containers (such as Tomcat or Jetty) and other application servers (such
as GlassFish) _______________________________________________________________________ 33
2.11 Monitoring Infinispan ____________________________________________________________ 33
2.12 Getting Started Guide - Introduction ________________________________________________ 34
2.13 Getting Started Guide - Downloading, installing and running Infinispan _____________________ 35
2.14 Getting Started Guide - Embedded Cache in Java SE __________________________________ 35
2.14.1 Creating a new Infinispan project _____________________________________________ 35
2.14.2 Running Infinispan on a single node __________________________________________ 38
2.14.3 Use the default cache _____________________________________________________ 39
2.14.4 Use a custom cache _______________________________________________________ 40
2.15 Getting Started Guide - Clustered Cache in Java SE ___________________________________ 40
2.15.1 Running Infinispan in a cluster _______________________________________________ 41
2.15.2 Configuring the cluster _____________________________________________________ 45
2.15.3 Configuring a replicated data-grid ____________________________________________ 46
2.15.4 Configuring a distributed data-grid ____________________________________________ 47
2.16 Infinispan GUI demo ____________________________________________________________ 47
2.16.1 Step 1: Start the demo GUI _________________________________________________ 48
2.16.2 Step 3: Manipulate data ____________________________________________________ 48
2.16.3 Step 4: Start more cache instances ___________________________________________ 48
2.16.4 Step 5: Manipulate more data _______________________________________________ 49

JBoss Community Documentation

Page 2 of 617

Infinispan 6.0
2.17 Getting Started Guide - JBoss AS 7 ________________________________________________ 49
2.17.1 Configuration ____________________________________________________________ 49
2.17.2 Cache container lifecycle ___________________________________________________ 52
2.18 Labs _________________________________________________________________________ 54
2.18.1 A list of the labs developed for Infinispan _______________________________________ 54
2.18.2 Lab - Getting Started with Infinispan __________________________________________ 54
3 User Guide _______________________________________________________________________ 70
3.1 New in Infinispan 4.1.0 __________________________________________________________ 71
3.2 New in Infinispan 4.2.0 __________________________________________________________ 72
3.3 New in Infinispan 5.0.0 __________________________________________________________ 72
3.4 New in Infinispan 5.2.0 __________________________________________________________ 72
3.5 Integration with other frameworks __________________________________________________ 72
3.6 Querying Infinispan _____________________________________________________________ 72
3.6.1 The infinispan-query module ________________________________________________ 73
3.6.2 Simple example __________________________________________________________ 73
3.6.3 Configuration ____________________________________________________________ 76
3.6.4 Cache modes and managing indexes _________________________________________ 78
3.6.5 Sharing the Index _________________________________________________________ 80
3.6.6 Clustering the Index in Infinispan _____________________________________________ 81
3.6.7 Rebuilding the Index ______________________________________________________ 81
3.7 Configuring cache programmatically ________________________________________________ 81
3.7.1 Programmatic Configuration ________________________________________________ 81
3.7.2 ConfigurationBuilder Programmatic Configuration API ______________________________
3.8 Grid File System _______________________________________________________________ 85
3.8.1 WebDAV demo __________________________________________________________ 86
3.9 Asynchronous API ______________________________________________________________ 86
3.9.1 Why use such an API? _____________________________________________________ 87
3.9.2 Which processes actually happen asynchronously? ______________________________ 87
3.9.3 Notifying futures __________________________________________________________ 88
3.9.4 Further reading ___________________________________________________________ 88
3.10 Tree API Module _______________________________________________________________ 88
3.10.1 Introduction _____________________________________________________________ 89
3.10.2 What is Tree API about? ___________________________________________________ 89
3.10.3 Using Tree API ___________________________________________________________ 89
3.10.4 Locking In Tree API _______________________________________________________ 93
3.10.5 Listeners for tree cache events ______________________________________________ 94
3.11 Infinispan as a storage for Lucene indexes ___________________________________________ 94
3.11.1 Additional Links __________________________________________________________ 94
3.11.2 Lucene compatibility _______________________________________________________ 94
3.11.3 How to use it ____________________________________________________________ 95
3.11.4 Limitations ______________________________________________________________ 95
3.11.5 Configuration ____________________________________________________________ 96
3.11.6 Demo __________________________________________________________________ 96
3.11.7 Maven dependencies ______________________________________________________ 96
3.11.8 Using a CacheLoader _____________________________________________________ 97
3.11.9 Architectural limitations ____________________________________________________ 98

JBoss Community Documentation

Page 3 of 617

Infinispan 6.0
3.11.10Suggestions for optimal performance _________________________________________ 98
3.12 Infinispan Server Modules ________________________________________________________ 99
3.12.1 Introduction _____________________________________________________________ 99
3.12.2 Server Modules _________________________________________________________ 102
3.12.3 Server Comparison Summary ______________________________________________ 104
3.13 Management Tooling ___________________________________________________________ 104
3.13.1 Introduction ____________________________________________________________ 104
3.13.2 JMX __________________________________________________________________ 104
3.13.3 RHQ __________________________________________________________________ 110
3.13.4 Writing plugins for other management tools ____________________________________ 113
3.14 Asynchronous Options _________________________________________________________ 113
3.14.1 Introduction ____________________________________________________________ 114
3.14.2 Asynchronous Communications _____________________________________________ 114
3.14.3 Asynchronous Marshalling _________________________________________________ 115
3.14.4 Replication Queue _______________________________________________________ 116
3.14.5 Asynchronous API _______________________________________________________ 116
3.14.6 Return Values __________________________________________________________ 116
3.15 Infinispan as Hibernate 2nd-Level Cache in JBoss AS 5.x ______________________________ 116
3.16 Clustered Configuration QuickStart ________________________________________________ 117
3.16.1 Using an external JGroups file ______________________________________________ 118
3.16.2 Use one of the pre-configured JGroups files ___________________________________ 118
3.16.3 Further reading __________________________________________________________ 120
3.17 Locking and Concurrency _______________________________________________________ 120
3.17.1 MVCC implementation details ______________________________________________ 121
3.17.2 Isolation levels __________________________________________________________ 122
3.17.3 The LockManager _______________________________________________________ 122
3.17.4 Lock striping ____________________________________________________________ 123
3.17.5 Concurrency levels _______________________________________________________ 123
3.17.6 Explicit and implicit distributed eager locking ___________________________________ 124
3.17.7 Locking a single remote node ______________________________________________ 124
3.17.8 Non-transactional caches and concurrent updates ______________________________ 126
3.18 Configuring Cache declaratively __________________________________________________ 127
3.19 Configuration Migration Tools ____________________________________________________ 127
3.20 Consistent Concurrent Updates With Hot Rod Versioned Operations _____________________ 128
3.20.1 Introduction ____________________________________________________________ 129
3.20.2 Data Consistency Problem _________________________________________________ 129
3.21 Cache Loaders and Stores ______________________________________________________ 131
3.21.1 Introduction ____________________________________________________________ 132
3.21.2 Configuration ___________________________________________________________ 132
3.21.3 Cache Passivation _______________________________________________________ 134
3.21.4 File system based cache loaders ____________________________________________ 137
3.21.5 JDBC based cache loaders ________________________________________________ 137
3.21.6 Cloud cache loader ______________________________________________________ 142
3.21.7 Remote cache loader _____________________________________________________ 142
3.21.8 Cassandra cache loader __________________________________________________ 144
3.21.9 Cluster cache loader _____________________________________________________ 144

JBoss Community Documentation

Page 4 of 617

Infinispan 6.0
3.21.10JPA cache store ________________________________________________________ 144
3.21.11LevelDB cache store _____________________________________________________ 147
3.21.12Cache Loaders and transactional caches _____________________________________ 150
3.21.13MongoDB cache loader ___________________________________________________ 150
3.22 Portable Serialization For Hot Rod With Apache Avro _________________________________ 151
3.22.1 Introduction ____________________________________________________________ 152
3.22.2 Languages Supported ____________________________________________________ 152
3.22.3 Object Types Supported __________________________________________________ 153
3.22.4 Java Configuration _______________________________________________________ 154
3.23 The Grouping API _____________________________________________________________ 154
3.23.1 How does it work? _______________________________________________________ 154
3.23.2 How do I use the grouping API? ____________________________________________ 154
3.24 Infinispan transactions __________________________________________________________ 156
3.24.1 JTA Support ____________________________________________________________ 158
3.24.2 Configuring transactions __________________________________________________ 159
3.24.3 Transactional modes _____________________________________________________ 159
3.24.4 Deadlock detection _______________________________________________________ 162
3.24.5 Transaction and exceptions ________________________________________________ 162
3.24.6 Transaction recovery on node failures ________________________________________ 162
3.24.7 Enlisting Synchronization __________________________________________________ 163
3.25 Load Testing Infinispan Server Modules ____________________________________________ 163
3.26 Using Infinispan as JPA-Hibernate Second Level Cache Provider ________________________ 164
3.26.1 Overview ______________________________________________________________ 165
3.26.2 Configuration ___________________________________________________________ 165
3.26.3 Default Configuration Explained _____________________________________________ 167
3.26.4 JTA Transactions Configuration _____________________________________________ 168
3.26.5 Advanced Configuration ___________________________________________________ 171
3.26.6 Integration with JBoss Application Server _____________________________________ 175
3.26.7 Using Infinispan as remote Second Level Cache? ______________________________ 176
3.26.8 Frequently Asked Questions _______________________________________________ 176
3.27 Default Values For Property Based Attributes ________________________________________ 177
3.27.1 asyncListenerExecutor ____________________________________________________ 177
3.27.2 asyncTransportExecutor __________________________________________________ 177
3.27.3 evictionScheduledExecutor ________________________________________________ 177
3.27.4 replicationQueueScheduledExecutor _________________________________________ 177
3.28 Running Infinispan on Amazon Web Services _______________________________________ 177
3.28.1 TCPPing, GossipRouter, S3_PING __________________________________________ 178
3.28.2 GossipRouter ___________________________________________________________ 179
3.28.3 S3_PING ______________________________________________________________ 180
3.28.4 JDBC_PING ____________________________________________________________ 180
3.28.5 Creating a cluster node with distributed cache _________________________________ 181
3.29 Eviction Examples _____________________________________________________________ 181
3.29.1 Introduction ____________________________________________________________ 181
3.29.2 Configuration ___________________________________________________________ 181
3.29.3 Eviction designs _________________________________________________________ 183
3.30 Clustering modes _____________________________________________________________ 183

JBoss Community Documentation

Page 5 of 617

Infinispan 6.0
3.30.1 Introduction ____________________________________________________________ 184
3.30.2 Local Mode _____________________________________________________________ 184
3.30.3 Replicated Mode ________________________________________________________ 184
3.30.4 Invalidation Mode ________________________________________________________ 186
3.30.5 Distribution Mode ________________________________________________________ 186
3.30.6 L1 Caching _____________________________________________________________ 192
3.31 Using Infinispan as a Spring Cache provider ________________________________________ 193
3.32 Note: This page is obsolete. Please refer to Infinispan Distributed Execution Framework . ____ 195
3.33 Per-Invocation Flags ___________________________________________________________ 195
3.33.1 Examples ______________________________________________________________ 196
3.33.2 DecoratedCache ________________________________________________________ 196
3.33.3 Suppressing return values from a put() or remove() _____________________________ 197
3.34 Key affinity service ____________________________________________________________ 197
3.34.1 Introduction ____________________________________________________________ 197
3.34.2 API ___________________________________________________________________ 198
3.34.3 Lifecycle _______________________________________________________________ 198
3.34.4 Topology changes _______________________________________________________ 199
3.35 Transaction recovery ___________________________________________________________ 199
3.35.1 ______________________________________________________________________ 199
3.35.2 When to use recovery ____________________________________________________ 199
3.35.3 How does it work ________________________________________________________ 200
3.35.4 Configuring recovery

____________________________________________________ 201

3.35.5 Integration with the TM ____________________________________________________ 202


3.35.6 Re-conciliate state _______________________________________________________ 202
3.35.7 Want to know more? _____________________________________________________ 203
3.36 Implementing standalone JPA JTA Hibernate application outside J2EE server using Infinispan 2nd
level cache ________________________________________________________________________ 203
3.36.1 Introduction ____________________________________________________________ 204
3.36.2 JBoss Transactions ______________________________________________________ 204
3.36.3 JOTM _________________________________________________________________ 208
3.36.4 Bitronix ________________________________________________________________ 211
3.36.5 Atominkos _____________________________________________________________ 213
3.37 Infinispan Maven Archetypes ____________________________________________________ 216
3.37.1 Starting a new project ____________________________________________________ 217
3.37.2 Writing a test case for Infinispan ____________________________________________ 217
3.37.3 Versions _______________________________________________________________ 218
3.37.4 Source Code ___________________________________________________________ 218
3.38 Accessing data in Infinispan via RESTful interface ____________________________________ 218
3.38.1 Putting data in __________________________________________________________ 219
3.38.2 Getting data back out _____________________________________________________ 220
3.38.3 Removing data __________________________________________________________ 223
3.39 Infinispan Distributed Execution Framework _________________________________________ 223
3.39.1 Introduction ____________________________________________________________ 224
3.39.2 DistributedCallable API ___________________________________________________ 225
3.39.3 Callable and CDI ________________________________________________________ 226
3.39.4 DistributedExecutorService, DistributedTaskBuilder and DistributedTask API _________ 227

JBoss Community Documentation

Page 6 of 617

Infinispan 6.0
3.39.5 Distributed task failover ___________________________________________________ 227
3.39.6 Distributed task execution policy ____________________________________________ 229
3.39.7 Examples ______________________________________________________________ 229
3.40 Listeners and Notifications ______________________________________________________ 230
3.40.1 Cache-level notifications __________________________________________________ 231
3.40.2 Cache manager-level notifications ___________________________________________ 232
3.40.3 Synchronicity ___________________________________________________________ 232
3.40.4 Listeners on RemoteCacheManager _________________________________________ 232
3.41 Eviction _____________________________________________________________________ 232
3.41.1 Eviction in 5.2 ___________________________________________________________ 234
3.41.2 Configuration and defaults in 5.2.x ___________________________________________ 235
3.41.3 Advanced Eviction Internals ________________________________________________ 236
3.41.4 Expiration ______________________________________________________________ 236
3.41.5 Difference between Eviction and Expiration ____________________________________ 236
3.42 ServerHinting _________________________________________________________________ 236
3.42.1 What is server hinting? ____________________________________________________ 237
3.42.2 Version ________________________________________________________________ 237
3.42.3 Configuration ___________________________________________________________ 237
3.42.4 Algorithm ______________________________________________________________ 238
3.43 Java Hot Rod client ____________________________________________________________ 238
3.43.1 Introduction ____________________________________________________________ 238
3.43.2 Basic API ______________________________________________________________ 239
3.43.3 Versioned API __________________________________________________________ 240
3.43.4 Async API ______________________________________________________________ 240
3.43.5 Unsupported methods ____________________________________________________ 241
3.43.6 Return values ___________________________________________________________ 241
3.43.7 Intelligence _____________________________________________________________ 242
3.43.8 Hash-distribution-aware client ______________________________________________ 242
3.43.9 Request Balancing _______________________________________________________ 243
3.43.10Persistent connections ___________________________________________________ 243
3.43.11Marshalling data ________________________________________________________ 244
3.43.12Statistics ______________________________________________________________ 244
3.43.13Configuration ___________________________________________________________ 244
3.43.14Multi-Get Operations _____________________________________________________ 244
3.43.15More info ______________________________________________________________ 244
3.44 Configuring cache _____________________________________________________________ 244
3.44.1 Dynamically Start and Stop Clustered Cache __________________________________ 245
3.45 Write-Through And Write-Behind Caching __________________________________________ 246
3.45.1 Introduction ____________________________________________________________ 247
3.45.2 Write-Through (Synchronous) ______________________________________________ 247
3.45.3 Write-Behind (Asynchronous) ______________________________________________ 248
3.45.4 Unscheduled Write-Behind Strategy _________________________________________ 248
3.45.5 Scheduled Write-Behind Strategy ___________________________________________ 249
3.46 Cassandra CacheStore _________________________________________________________ 249
3.46.1 Version ________________________________________________________________ 249
3.46.2 ______________________________________________________________________ 249

JBoss Community Documentation

Page 7 of 617

Infinispan 6.0
3.47 Infinispan Custom Interceptors ___________________________________________________ 251
3.47.1 Introduction ____________________________________________________________ 251
3.47.2 Adding custom interceptors declaratively ______________________________________ 252
3.47.3 Custom interceptor design _________________________________________________ 252
3.48 Talking To Infinispan Memcached Servers From Non-Java Clients _______________________ 253
3.48.1 Multi Clustered Server Tutorial ______________________________________________ 253
3.49 Plugging Infinispan With User Defined Externalizers __________________________________ 253
3.49.1 Introduction ____________________________________________________________ 254
3.49.2 Benefits of Externalizers __________________________________________________ 254
3.50 Using the Cache API ___________________________________________________________ 261
3.50.1 The Cache interface ______________________________________________________ 261
3.50.2 The AdvancedCache interface ______________________________________________ 264
3.51 Local mode cache _____________________________________________________________ 264
3.52 Infinispan Command-line Console ________________________________________________ 266
3.52.1 What is ispncon ? ________________________________________________________ 268
3.52.2 Installation _____________________________________________________________ 269
3.52.3 Basic usage ____________________________________________________________ 270
3.52.4 Configuration ___________________________________________________________ 271
3.52.5 Cache operations ________________________________________________________ 271
3.52.6 Other commands ________________________________________________________ 276
3.52.7 Interoperability with java clients _____________________________________________ 279
3.53 Server Command Line Options ___________________________________________________ 279
3.54 Interacting With Hot Rod Server From Within Same JVM _______________________________ 281
3.54.1 Introduction ____________________________________________________________ 282
3.54.2 Data Stored Directly Via A Hot Rod Client _____________________________________ 283
3.54.3 Data Stored Via Remote Cache Store ________________________________________ 283
3.55 Multiple Tiers of Caches ________________________________________________________ 285
3.55.1 Introduction ____________________________________________________________ 285
3.55.2 Building blocks __________________________________________________________ 285
3.55.3 Sample architecture/near caching ___________________________________________ 286
3.55.4 Want to know more? _____________________________________________________ 286
3.56 Infinispan REST Server _________________________________________________________ 286
3.56.1 Introduction ____________________________________________________________ 286
3.56.2 Configuration ___________________________________________________________ 287
3.56.3 Accessing Data - via URLs ________________________________________________ 288
3.56.4 Client side code _________________________________________________________ 288
3.56.5 Future: ________________________________________________________________ 291
3.57 CDI Support __________________________________________________________________ 291
3.57.1 Introduction ____________________________________________________________ 292
3.57.2 Maven Dependencies ____________________________________________________ 292
3.57.3 Embedded cache integration _______________________________________________ 292
3.57.4 Remote cache integration _________________________________________________ 296
3.57.5 Use a custom remote/embedded cache manager for one or more cache _____________ 299
3.57.6 Use a JBoss AS 7 configured cache _________________________________________ 300
3.57.7 Use JCache caching annotations ____________________________________________ 300
3.58 Marshalling __________________________________________________________________ 301

JBoss Community Documentation

Page 8 of 617

Infinispan 6.0
3.58.1 Introduction ____________________________________________________________ 302
3.58.2 The Role Of JBoss Marshalling _____________________________________________ 302
3.58.3 Support For Non-Serializable Objects ________________________________________ 302
3.58.4 Advanced Configuration ___________________________________________________ 304
3.59 Batching ____________________________________________________________________ 307
3.59.1 Introduction ____________________________________________________________ 307
3.59.2 Configuring batching _____________________________________________________ 308
3.59.3 Batching API ___________________________________________________________ 308
3.59.4 Advanced: batching and JTA _______________________________________________ 309
3.60 Hot Rod Hash Functions ________________________________________________________ 310
3.61 Hot Rod Protocol ______________________________________________________________ 310
3.61.1 Hot Rod Protocol - Version 1.0 _____________________________________________ 310
3.61.2 Hot Rod Protocol - Version 1.1 _____________________________________________ 322
3.61.3 Hot Rod Protocol - Version 1.2 _____________________________________________ 335
3.62 Cross site replication ___________________________________________________________ 349
3.62.1 Sample deployment ______________________________________________________ 349
3.62.2 Data replication _________________________________________________________ 354
3.62.3 Taking a site offline ______________________________________________________ 356
3.62.4 Reference ______________________________________________________________ 357
3.63 Map Reduce framework ________________________________________________________ 357
3.63.1 Introduction ____________________________________________________________ 357
3.63.2 MapReduce API _________________________________________________________ 357
3.63.3 Mapper and CDI _________________________________________________________ 359
3.63.4 MapReduceTask distributed execution _______________________________________ 359
3.63.5 Examples ______________________________________________________________ 362
3.64 Rolling upgrades for remote clients using Hot Rod ____________________________________ 364
3.64.1 Steps _________________________________________________________________ 365
3.65 Command-Line Interface (CLI) ___________________________________________________ 365
3.65.1 Commands _____________________________________________________________ 367
3.65.2 Data Types _____________________________________________________________ 373
3.65.3 Time Values ____________________________________________________________ 374
3.66 Total Order based commit protocol ________________________________________________ 374
3.66.1 Introduction ____________________________________________________________ 374
3.66.2 Overview ______________________________________________________________ 374
3.66.3 Configuration ___________________________________________________________ 379
3.66.4 Total Order protocols in JGroups. ___________________________________________ 380
3.66.5 Benchmark results _______________________________________________________ 384
3.67 Using Infinispan as a JCache provider _____________________________________________ 387
3.67.1 Dependencies __________________________________________________________ 388
3.67.2 Create a local cache _____________________________________________________ 389
3.67.3 Store and retrieve data ____________________________________________________ 390
3.67.4 Comparing java.util.concurrent.ConcurrentMap and javax.cache.Cache APIs _________ 390
3.67.5 Clustering JCache instances _______________________________________________ 392
3.67.6 Expire cached data ______________________________________________________ 393
3.67.7 Annotations ____________________________________________________________ 393
3.67.8 Atomic compound operations on cache entry __________________________________ 393

JBoss Community Documentation

Page 9 of 617

Infinispan 6.0
3.67.9 Using cache listeners _____________________________________________________ 394
3.67.10Quickstarts ____________________________________________________________ 394
3.68 Infinispan Server ______________________________________________________________ 394
3.68.1 Introduction ____________________________________________________________ 394
3.68.2 Protocols ______________________________________________________________ 394
3.68.3 Getting Started __________________________________________________________ 395
3.68.4 CLI ___________________________________________________________________ 395
3.68.5 Configuration ___________________________________________________________ 395
3.68.6 Hot Rod Server _________________________________________________________ 404
3.68.7 Memcached Server ______________________________________________________ 404
3.68.8 WebSocket Server _______________________________________________________ 406
3.69 Storing objects (e.g. arrays) with custom Equivalence functions _________________________ 410
3.69.1 The Problem of Caching Arrays _____________________________________________ 410
3.69.2 Old workaround: Wrapper Classes __________________________________________ 411
3.69.3 New solution: Plugging Equivalence functions __________________________________ 411
3.70 Interoperability between Embedded and Remote Server Endpoints _______________________ 416
3.70.1 Enable Compatibility Mode ________________________________________________ 416
3.70.2 Code examples _________________________________________________________ 417
3.71 Infinispan for HTTP session clustering and caching ___________________________________ 418
3.71.1 JBoss AS and WildFly ____________________________________________________ 418
3.71.2 Jetty __________________________________________________________________ 418
3.71.3 Other application servers and servlet containers ________________________________ 418
3.72 Design of data versioning in Infinispan _____________________________________________ 418
3.72.1 Overview ______________________________________________________________ 420
3.72.2 Configuration ___________________________________________________________ 421
3.73 Infinispan modules for JBoss AS 7.x _______________________________________________ 422
3.74 Infinispan with Groovy __________________________________________________________ 422
3.74.1 Introduction ____________________________________________________________ 423
3.74.2 Loading the configuration file _______________________________________________ 426
3.74.3 Basic cache configuration ____________________________________________________
3.74.4 Cache with transaction management _________________________________________ 428
3.74.5 Cache with a cache store __________________________________________________ 429
3.74.6 Cache with eviction ______________________________________________________ 432
3.74.7 Cache with eviction and cache store _________________________________________ 433
3.75 Using Infinispan with Scala ______________________________________________________ 433
3.75.1 Introduction ____________________________________________________________ 434
3.75.2 Environment ____________________________________________________________ 434
3.75.3 Testing Setup ___________________________________________________________ 434
3.75.4 Loading the Configuration file ______________________________________________ 435
3.75.5 Basic cache operations ___________________________________________________ 436
3.75.6 Basic cache operations with TTL ____________________________________________ 437
3.75.7 Cache restarts __________________________________________________________ 437
3.75.8 Transactional cache operations _____________________________________________ 437
3.75.9 Persistent stored backed Cache operations ___________________________________ 439
3.75.10Operating against a size bounded cache _____________________________________ 440
3.75.11Size bounded caches with persistent store ____________________________________ 441

JBoss Community Documentation

Page 10 of 617

Infinispan 6.0
Size bounded caches with persistent store ___________________________________ 441
4 Upgrade Guide ___________________________________________________________________ 442
4.1 Upgrading from 5.0 to 5.1 _______________________________________________________ 442
4.1.1 API ___________________________________________________________________ 443
4.1.2 Eviction and Expiration ____________________________________________________ 444
4.1.3 Transactions ____________________________________________________________ 444
4.1.4 State transfer ___________________________________________________________ 444
4.1.5 Configuration ___________________________________________________________ 444
4.1.6 Flags and ClassLoaders __________________________________________________ 446
4.1.7 JGroups Bind Address ____________________________________________________ 446
4.1.8 Configuration changes from 5.0 to 5.1 ________________________________________ 446
4.2 Upgrading from 5.1 to 5.2 _______________________________________________________ 449
4.2.1 Declarative configuration __________________________________________________ 449
4.2.2 Transaction ____________________________________________________________ 449
4.2.3 Cache Loader and Store configuration _______________________________________ 449
4.2.4 Virtual Nodes > Segments _________________________________________________ 449
4.3 Upgrading from 5.2 to 5.3 _______________________________________________________ 450
5 Glossary ________________________________________________________________________ 451
5.1 Glossary ____________________________________________________________________ 451
5.2 2-phase commit _______________________________________________________________ 452
5.2.1 More resources _________________________________________________________ 452
5.3 Atomicity, Consistency, Isolation, Durability (ACID) ___________________________________ 452
5.4 Basically Available, Soft-state, Eventually-consistent (BASE) ___________________________ 452
5.4.1 More resources _________________________________________________________ 452
5.5 Cache Aside _________________________________________________________________ 452
5.6 Consistency, Availability and Partition-tolerance (CAP) Theorem ________________________ 453
5.6.1 More resources _________________________________________________________ 453
5.7 Consistent Hash ______________________________________________________________ 453
5.8 Data grid ____________________________________________________________________ 454
5.8.1 More resources _________________________________________________________ 454
5.9 Deadlock ____________________________________________________________________ 454
5.10 Distributed Hash Table (DHT) ____________________________________________________ 454
5.11 Externalizer __________________________________________________________________ 454
5.11.1 More resources _________________________________________________________ 454
5.12 Hot Rod _____________________________________________________________________ 455
5.12.1 More resources _________________________________________________________ 455
5.13 In-memory data grid ___________________________________________________________ 455
5.14 Isolation level _________________________________________________________________ 455
5.15 JTA synchronization ___________________________________________________________ 455
5.16 Livelock _____________________________________________________________________ 456
5.17 Memcached __________________________________________________________________ 456
5.17.1 More resource __________________________________________________________ 456
5.18 Multiversion Concurrency Control (MVCC) __________________________________________ 456
5.19 Near Cache __________________________________________________________________ 456
5.20 Network partition ______________________________________________________________ 456
5.21 NoSQL ______________________________________________________________________ 456
5.22 Optimistic locking _____________________________________________________________ 457

JBoss Community Documentation

Page 11 of 617

Infinispan 6.0
5.23 Pessimistic locking ____________________________________________________________ 457
5.24 Read Ahead _________________________________________________________________ 457
5.25 READ COMMITTED ___________________________________________________________ 457
5.26 Relational Database Management System (RDBMS) __________________________________ 457
5.27 REPEATABLE READ __________________________________________________________ 458
5.28 Representational State Transfer (REST) ___________________________________________ 458
5.28.1 More resources _________________________________________________________ 458
5.29 Split brain ___________________________________________________________________ 458
5.30 Structured Query Language (SQL) ________________________________________________ 458
5.31 Write-behind _________________________________________________________________ 459
5.31.1 More resources _________________________________________________________ 459
5.32 Write skew ___________________________________________________________________ 459
5.33 Write-through _________________________________________________________________ 459
5.33.1 More resources _________________________________________________________ 459
5.34 XA resource __________________________________________________________________ 459
6 Extending Infinispan _______________________________________________________________ 460
6.1 Custom Commands ____________________________________________________________ 461
6.1.1 Preassigned Custom Command Id Ranges ____________________________________ 461
6.2 Writing custom commands in Infinispan ____________________________________________ 462
6.2.1 Preassigned Custom Command Id Ranges ____________________________________ 462
7 Contributing to Infinispan ____________________________________________________________ 463
7.1 The Basics ___________________________________________________________________ 465
7.1.1 Pre-requisites ___________________________________________________________ 466
7.1.2 Issue Management - JIRA _________________________________________________ 466
7.1.3 Source control - Git ______________________________________________________ 467
7.1.4 Build - Maven ___________________________________________________________ 474
7.1.5 Testing - TestNG ________________________________________________________ 474
7.1.6 Communicating with other Infinispan contributors _______________________________ 474
7.1.7 Style Requirements ______________________________________________________ 475
7.1.8 Configuration ___________________________________________________________ 475
7.1.9 Logging _______________________________________________________________ 475
7.2 Source Control _______________________________________________________________ 478
7.2.1 Pre-requisites ___________________________________________________________ 478
7.2.2 Repositories ____________________________________________________________ 478
7.2.3 Roles _________________________________________________________________ 478
7.2.4 Contributor License Agreement (CLA) ________________________________________ 487
7.2.5 Committing your work ____________________________________________________ 487
7.2.6 Keeping your repo in sync with upstream _____________________________________ 489
7.2.7 Tips on enhancing git _____________________________________________________ 491
7.3 Building Infinispan _____________________________________________________________ 494
7.3.1 Requirements ___________________________________________________________ 494
7.3.2 Quick command reference _________________________________________________ 496
7.3.3 Publishing releases to Maven ______________________________________________ 498
7.3.4 The Maven Archetypes ___________________________________________________ 498
7.4 API, Commons and Core _______________________________________________________ 501
7.4.1 API ___________________________________________________________________ 501

JBoss Community Documentation

Page 12 of 617

Infinispan 6.0
7.4.2 Commons ______________________________________________________________ 501
7.4.3 Core __________________________________________________________________ 501
7.5 Running and Writing Tests ______________________________________________________ 501
7.5.1 Running the tests ________________________________________________________ 502
7.5.2 Test groups ____________________________________________________________ 505
7.5.3 Test permutations _______________________________________________________ 506
7.5.4 The Parallel Test Suite ____________________________________________________ 506
7.6 Helping Others Out ____________________________________________________________ 508
7.7 Adding Configuration ___________________________________________________________ 508
7.7.1 Adding a property ________________________________________________________ 509
7.7.2 Adding a group __________________________________________________________ 510
7.7.3 Don't forget to update the XSD and XSD test __________________________________ 510
7.7.4 Bridging to the old configuration _____________________________________________ 511
7.8 Writing Documentation and FAQs _________________________________________________ 511
7.8.1 Introduction ____________________________________________________________ 511
7.8.2 What goes where? _______________________________________________________ 512
7.8.3 Wiki markup or rich text ___________________________________________________ 512
7.8.4 Markup guide ___________________________________________________________ 512
7.8.5 Voice and grammar guide _________________________________________________ 517
7.8.6 Glossary _______________________________________________________________ 519
7.8.7 Screencasts ____________________________________________________________ 519
7.9 Managing this confluence instance. _______________________________________________ 520
7.10 Contributing - The Basics _______________________________________________________ 520
7.10.1 Pre-requisites ___________________________________________________________ 520
7.10.2 Issue Management - JIRA _________________________________________________ 520
7.10.3 Source control - Git ______________________________________________________ 521
7.10.4 Build - Maven ___________________________________________________________ 529
7.10.5 Testing - TestNG ________________________________________________________ 529
7.10.6 Communicating with other Infinispan contributors _______________________________ 529
7.10.7 Style Requirements ______________________________________________________ 530
7.10.8 Configuration ___________________________________________________________ 530
7.10.9 Logging _______________________________________________________________ 530
7.11 Contributing - Source Control ____________________________________________________ 533
7.11.1 Pre-requisites ___________________________________________________________ 533
7.11.2 Repositories ____________________________________________________________ 533
7.11.3 Roles _________________________________________________________________ 533
7.11.4 Contributor License Agreement (CLA) ________________________________________ 542
7.11.5 Committing your work ____________________________________________________ 542
7.11.6 Keeping your repo in sync with upstream _____________________________________ 544
7.11.7 Tips on enhancing git _____________________________________________________ 546
7.12 Contributing - The build _________________________________________________________ 549
7.12.1 Requirements ___________________________________________________________ 549
7.12.2 Quick command reference _________________________________________________ 551
7.12.3 Publishing releases to Maven ______________________________________________ 553
7.12.4 The Maven Archetypes ___________________________________________________ 553
7.12.5 The Maven Archetypes ___________________________________________________ 556

JBoss Community Documentation

Page 13 of 617

Infinispan 6.0
7.13 Contributing - The test suite _____________________________________________________ 558
7.13.1 Running the tests ________________________________________________________ 559
7.13.2 Test groups ____________________________________________________________ 562
7.13.3 Test permutations _______________________________________________________ 563
7.13.4 The Parallel Test Suite ____________________________________________________ 563
7.14 Contributing - Helping Others Out _________________________________________________ 565
7.15 Contributing - Adding configuration options _________________________________________ 565
7.15.1 Adding a property ________________________________________________________ 566
7.15.2 Adding a group __________________________________________________________ 567
7.15.3 Don't forget to update the XSD and XSD test __________________________________ 567
7.15.4 Bridging to the old configuration _____________________________________________ 568
7.16 Contributing - Documentation and FAQs ___________________________________________ 568
7.16.1 Introduction ____________________________________________________________ 568
7.16.2 What goes where? _______________________________________________________ 569
7.16.3 Wiki markup or rich text ___________________________________________________ 569
7.16.4 Markup guide ___________________________________________________________ 569
7.16.5 Voice and grammar guide _________________________________________________ 574
7.16.6 Glossary _______________________________________________________________ 576
7.16.7 Screencasts ____________________________________________________________ 576
7.16.8 Managing this confluence instance. __________________________________________ 577
7.17 Contributing - API, Commons and Core ____________________________________________ 577
7.17.1 API ___________________________________________________________________ 577
7.17.2 Commons ______________________________________________________________ 577
7.17.3 Core __________________________________________________________________ 577
8 Frequently Asked Questions _________________________________________________________ 578
8.1 Project FAQs _________________________________________________________________ 578
8.2 Technical FAQs _______________________________________________________________ 578
8.3 Project Evaluation FAQs ________________________________________________________ 580
8.3.1 What is Infinispan? _______________________________________________________ 581
8.3.2 What would I use Infinispan for? ____________________________________________ 582
8.3.3 How is Infinispan related to JBoss Cache? ____________________________________ 583
8.3.4 What version of Java does Infinispan need to run? Does Infinispan need an application
server to run? __________________________________________________________________ 583
8.3.5 Will there be a POJO Cache replacement in Infinispan? __________________________ 583
8.3.6 How come Infinispan's first release is 4.0.0? This sounds weird! ___________________ 583
8.3.7 What should I use, JBoss Cache or Infinispan? _________________________________ 583
8.3.8 Where can I get more information on Infinispan? _______________________________ 584
8.3.9 How is this related to JSR 107, the JCACHE specification? _______________________ 584
8.3.10 Can I use Infinispan with Hibernate? _________________________________________ 585
8.4 Technical FAQs _______________________________________________________________ 585
8.4.1 General FAQs __________________________________________________________ 588
8.4.2 Cache Loaders and Cache Store FAQs _______________________________________ 590
8.4.3 Locking FAQs ___________________________________________________________ 592
8.4.4 Transaction FAQs _______________________________________________________ 594
8.4.5 Eviction and Expiration FAQs ______________________________________________ 594
8.4.6 Cache Manager FAQs ____________________________________________________ 596

JBoss Community Documentation

Page 14 of 617

Infinispan 6.0
8.4.7 Cache Mode FAQs _______________________________________________________ 596
8.4.8 Listener FAQs __________________________________________________________ 601
8.4.9 Cloud FAQs ____________________________________________________________ 602
8.4.10 Demo FAQs ____________________________________________________________ 602
8.4.11 Query Module FAQs _____________________________________________________ 603
8.4.12 JBoss Application Server Integration FAQs ____________________________________ 604
8.4.13 Logging FAQs __________________________________________________________ 605
8.4.14 Third Party Container FAQs ________________________________________________ 605
8.4.15 Language FAQs _________________________________________________________ 606
8.4.16 Marshalling & Unmarshalling _______________________________________________ 606
8.4.17 Tuning FAQs ___________________________________________________________ 610
8.4.18 JNDI FAQs _____________________________________________________________ 611
8.4.19 Hibernate 2nd Level Cache FAQs ___________________________________________ 612
8.4.20 Cache Server FAQs ______________________________________________________ 613
8.4.21 Debugging FAQs ________________________________________________________ 614
8.4.22 Clustering Transport FAQs ________________________________________________ 614
8.4.23 CLI FAQs ______________________________________________________________ 615
9 Videos __________________________________________________________________________ 616
9.1 Monitoring ___________________________________________________________________ 616
9.2 Geographic failover ____________________________________________________________ 616
10 Contributor Dashboard _____________________________________________________________ 617

JBoss Community Documentation

Page 15 of 617

Infinispan 6.0

Welcome to the Infinispan Documentation.


Here you can find:
Getting Started Guide
User Guide
Videos
Glossary
Guide to Extending Infinispan
Guide to Contributing to Infinispan
Frequently Asked Questions

JBoss Community Documentation

Page 16 of 617

Infinispan 6.0

1 More Resources
DZone Refcard on Infinispan (Cheat sheet for developers)

JBoss Community Documentation

Page 17 of 617

Infinispan 6.0

2 Getting Started Guide


AuthorsDouglas Campos , Galder Zamarreo , Libor Krzyanek , Manik Surtani , Mircea Markus , Pete Muir
, Sanne Grinovero , Vlastimil Eli

Target Audience
This guide shows you how to get started using Infinispan. It covers the common uses of Infinispan,
and shows you how to get off the ground. It also introduces to some of the essential concepts of
Infinispan.

Under development
This guide is still under development. The content you will find here is correct, but there are some
missing sections.

Introduction
Downloading and installing Infinispan
Infinispan in action - GUIDemo
Using Infinispan as an embedded cache in Java SE
Creating a new Infinispan project
Running Infinispan on a single node
Use the default cache
Use a custom cache
Using Infinispan as an embedded data grid in Java SE
Running Infinispan in a cluster
clustered-cache quickstart architecture
Configuring the cluster
Tweaking the cluster configuration for your network
Configuring a replicated data-grid
Configuring a distributed data-grid
Creating your own Infinispan project
Using Infinispan as a second level cache for Hibernate
Accessing an Infinispan data grid remotely
Using Hot Rod to access an Infinispan data-grid
Using REST to access an Infinipsan data-grid
Using memcached to access an Infinispan data-grid
Using Infinispan in JBoss AS 7
Using Infinispan in servlet containers (such as Tomcat or Jetty) and other application servers (such as
GlassFish)
Monitoring Infinispan

JBoss Community Documentation

Page 18 of 617

Infinispan 6.0

2.1 Introduction
This guide will walk you through downloading, installing and running Infinispan for the first time. It will then
introduce to some of the key features of Infinispan.
Infinispan can be used in a variety of runtimes:
Java SE, started by your application
an application server which provides Infinispan as a service (such as JBoss AS)
bundled as a library in your application, deployed to an application server, and started on by your
application (for example, you could use Infinispan with Tomcat or GlassFish)
Infinispan offers four modes of operation, which determine how and where the data is stored:
Local, where entries are stored on the local node only, regardless of whether a cluster has formed. In
this mode Infinispan is typically operating as a local cache
Invalidation, where all entries are stored into a cache store (such as a database) only, and
invalidated from all nodes. When a node needs the entry it will load it from a cache store. In this mode
Infinispan is operating as a distributed cache, backed by a canonical data store such as a database
Replication, where all entries are replicated to all nodes. In this mode Infinispan is typically operating
as a data grid or a temporary data store, but doesn't offer an increased heap space
Distribution, where entries are distributed to a subset of the nodes only. In this mode Infinispan is
typically operating as a data grid providing an increased heap space
Invalidation, Replication and Distribution can all use synchronous or asynchronous communication.
Infinispan offers two access patterns, both of which are available in any runtime:
Embedded into your application code
As a Remote server accessed by a client (REST, memcached or Hot Rod)
This guide will introduce to each of the runtime options, access patterns and modes of operations by walking
you through simple applications for each. All these applications are available in the Infinispan Quickstart
distribution.

JBoss Community Documentation

Page 19 of 617

Infinispan 6.0

2.2 Downloading and installing Infinispan


To run the Infinispan, you'll need
Java 1.6
Maven 3, if you wish to use the quickstart examples or create a new project using the Infinispan
archetype
the Infinispan distribution zip, if you wish to use Infinispan in server mode, or want to use the jars in
an ant project
the Infinispan Quickstart zip, if you want to follow along with the projects discussed in the guide

If you already have any of these pieces of software, there is no need to install them again!

Choose your Java runtime, and follow their installation instructions. For example, you could choose one of:
OpenJDK
Oracle Java SE
Oracle JRockit
Follow the official Maven installation guide if you don't already have Maven 3 installed. You can check which
version of Maven you have installed (if any) by running mvn --version. If you see a version newer than
3.0.0, you are ready to go.

You can also deploy the examples using your favorite IDE. We provide instructions for using
Eclipse only.

Finally, download Infinispan and the Infinispan Quickstart from the download page.

2.3 Infinispan in action - GUIDemo


TODO

2.4 Using Infinispan as an embedded cache in Java SE


Running Infinispan in embedded mode is very easy. First, we'll set up a project, and then we'll run Infinispan,
and start adding data.

embedded-cache quickstart
All the code discussed in this tutorial is available in the embedded-cache quickstart.

JBoss Community Documentation

Page 20 of 617

Infinispan 6.0

2.4.1 Creating a new Infinispan project


The only thing you need to set up Infinispan is add it's dependencies to your project. If you are using Maven
(or another build system like Gradle or Ivy which can use Maven dependencies), then this is easy. Just add:
pom.xml snippet
053.
054.
055.
056.
057.

<dependency>
<groupId>org.infinispan</groupId>
<artifactId>infinispan-embedded</artifactId>
<version>${infinispan.version}</version>
</dependency>

to your <dependencies> section of the POM. You'll need to substitute ${infinispan.version} for the
version of Infinispan you wish to use.

Which version of Infinispan should I use?


We recommend using the latest final version of Infinispan. All releases are displayed on the
downloads page.

You'll also need to enable the JBoss Maven repository. We recommend adding a profile:

JBoss Community Documentation

Page 21 of 617

Infinispan 6.0

pom.xml snippet
076.
077.
078.
079.
080.
081.
082.
083.
084.
085.
086.
087.
088.
089.
090.
091.
092.
093.
094.
095.
096.
097.
098.
099.
100.
101.
102.
103.
104.
105.
106.
107.
108.
109.
110.
111.
112.
113.
114.

<executions>
<execution>
<goals>
<goal>java</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
<profiles>
<profile>
<id>jboss-public-repository</id>
<activation>
<property>
<name>jboss-public-repository</name>
<value>!false</value>
</property>
</activation>
<repositories>
<repository>
<id>jboss-public-repository-group</id>
<name>JBoss Public Maven Repository Group</name>
<url>http://repository.jboss.org/nexus/content/groups/public</url>
<releases>
<enabled>true</enabled>
<updatePolicy>never</updatePolicy>
</releases>
<snapshots>
<enabled>true</enabled>
<updatePolicy>never</updatePolicy>
</snapshots>
</repository>
</repositories>
<pluginRepositories>
<pluginRepository>
<id>jboss-public-repository-group</id>
<name>JBoss Public Maven Repository Group</name>

Alternatively, you can use the POM from the quickstart that accompanies this tutorial.
If you are using Ant, or another build system which doesn't provide declarative dependency management,
then the Infinispan distribution zip contains a lib/ directory. Add the contents of this to the build classpath.

JBoss Community Documentation

Page 22 of 617

Infinispan 6.0

2.4.2 Running Infinispan on a single node


In order to run Infinispan, we're going to create a main method in the Quickstart class. Infinispan comes
configured to run out of the box; once you have set up your dependencies, all you need to do to start using
Infinispan is to create a new cache manager and get a handle on the default cache.
Quickstart.java
28. public class Quickstart {
29.
30.
public static void main(String args[]) throws Exception {
31.
Cache<Object, Object> c = new DefaultCacheManager().getCache();
32.
}

We now need a way to run the main method! If you are using Maven, the best approach is to copy all the
project dependencies to a directory, and at the same time compile the java classes from our project:

$> mvn clean compile dependency:copy-dependencies -DstripVersion

Having done that, we can run the main method:

$> java -cp target/classes/:target/dependency/* Quickstart

You should see Infinispan start up, and the version in use logged to the console.
Congratulations, you now have Infinispan running as a local cache!

JBoss Community Documentation

Page 23 of 617

Infinispan 6.0

2.4.3 Use the default cache


Infinispan exposes a Map-like, JSR-107-esque interface for accessing and mutating the data stored in the
cache. For example:
DefaultCacheQuickstart.java
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.

// Add a entry
cache.put("key", "value");
// Validate the entry is now in the cache
assertEqual(1, cache.size());
assertTrue(cache.containsKey("key"));
// Remove the entry from the cache
Object v = cache.remove("key");
// Validate the entry is no longer in the cache
assertEqual("value", v);

Infinispan offers a thread-safe data-structure:


DefaultCacheQuickstart.java
48.
49.
50.
51.
52.
53.

// Add an entry with the key "key"


cache.put("key", "value");
// And replace it if missing
cache.putIfAbsent("key", "newValue");
// Validate that the new value was not added

By default entries are immortal but you can override this on a per-key basis and provide lifespans.
DefaultCacheQuickstart.java
58.
59.
//By default entries are immortal but we can override this on a per-key basis and
provide lifespans.
60.
cache.put("key", "value", 5, SECONDS);
61.
assertTrue(cache.containsKey("key"));
62.
Thread.sleep(10000);

JBoss Community Documentation

Page 24 of 617

Infinispan 6.0

2.4.4 Use a custom cache


Each cache in Infinispan can offer a different set of features (for example transaction support, different
replication modes or support for eviction), and you may want to use different caches for different classes of
data in your application. To get a custom cache, you need to register it with the manager first:
CustomCacheQuickstart.java
33.
34.
35.
36.
37.
38.
39.

public static void main(String args[]) throws Exception {


EmbeddedCacheManager manager = new DefaultCacheManager();
manager.defineConfiguration("custom-cache", new ConfigurationBuilder()
.eviction().strategy(LIRS).maxEntries(10)
.build());
Cache<Object, Object> c = manager.getCache("custom-cache");

The example above uses Infinispan's fluent configuration, which offers the ability to configure your cache
programmatically. However, should you prefer to use XML, then you may. We can create an identical cache
to the one created with a programmatic configuration:
infinispan.xml
24. <infinispan
25.
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
26.
xsi:schemaLocation="urn:infinispan:config:7.0
http://www.infinispan.org/schemas/infinispan-config-7.0.xsd"
27.
xmlns="urn:infinispan:config:7.0">
28.
29.
<cache-container default-cache="default">
30.
<local-cache name="xml-configured-cache">
31.
<eviction strategy="LIRS" max-entries="10" />
32.
</local-cache>
33.
</cache-container>

We then need to load the configuration file, and use the programmatically defined cache:
XmlConfiguredCacheQuickstart.java
29.
30.
public static void main(String args[]) throws Exception {
31.
Cache<Object, Object> c = new
DefaultCacheManager("infinispan.xml").getCache("xml-configured-cache");

JBoss Community Documentation

Page 25 of 617

Infinispan 6.0

2.5 Using Infinispan as an embedded data grid in Java


SE
Clustering Infinispan is simple. Under the covers, Infinispan uses JGroups as a network transport, and
JGroups handles all the hard work of forming a cluster.

Sharing JGroups channels


By default all caches created from a single CacheManager share the same JGroups channel and
multiplex RPC messages over it. In this example caches 1, 2 and 3 all use the same JGroups
channel:

EmbeddedCacheManager cm = //
Cache<Object, Object> cache1
Cache<Object, Object> cache2
Cache<Object, Object> cache3

get CacheManager from somewhere


= cm.getCache("replSyncCache");
= cm.getCache("replAsyncCache");
= cm.getCache("invalidationSyncCache");

clustered-cache quickstart
All the code discussed in this tutorial is available in the clustered-cache quickstart.

2.5.1 Running Infinispan in a cluster


It is easy set up a clustered cache. This tutorial will show you how to create two nodes in different processes
on the same local machine. The quickstart follows the same structure as the embedded-cache quickstart,
using Maven to compile the project, and a main method to launch the node.
If you are following along with the quickstarts, you can try the examples out. First, compile the project:

$> mvn clean compile dependency:copy-dependencies -DstripVersion

The quickstart contains two examples of a clustered cache, one in replication mode and one distribution
mode. To run the replication mode example, we need to launch both nodes from different consoles. For the
first node:

$> java -cp target/classes/:target/dependency/*


org.infinispan.quickstart.clusteredcache.replication.Node0

And for the second node:

JBoss Community Documentation

Page 26 of 617

Infinispan 6.0

$> java -cp target/classes/:target/dependency/*


org.infinispan.quickstart.clusteredcache.replication.Node1

You should see JGroups and Infinispan start up on both consoles, and after about 15s the cache entry log
message appear on the console of the first node.
To run the distribution mode example, we need to launch three nodes from different consoles. For the first
node:

$> java -cp target/classes/:target/dependency/*


org.infinispan.quickstart.clusteredcache.distribution.Node0

And for the second node:

$> java -cp target/classes/:target/dependency/*


org.infinispan.quickstart.clusteredcache.distribution.Node1

And for the third node:

$> java -cp target/classes/:target/dependency/*


org.infinispan.quickstart.clusteredcache.distribution.Node2

You should see JGroups and Infinispan start up on both consoles, and after about 15s see the 10 entries
added by third node distributed to the first and second nodes.

JBoss Community Documentation

Page 27 of 617

Infinispan 6.0

clustered-cache quickstart architecture


Logging changes to the cache
An easy way to see what is going on with your cache is to log mutated entries. An Infinispan
listener is notified of any mutations:

import
import
import
import
import
import
import

org.infinispan.notifications.Listener;
org.infinispan.notifications.cachelistener.annotation.CacheEntryCreated;
org.infinispan.notifications.cachelistener.annotation.CacheEntryRemoved;
org.infinispan.notifications.cachelistener.event.CacheEntryCreatedEvent;
org.infinispan.notifications.cachelistener.event.CacheEntryRemovedEvent;
org.infinispan.util.logging.Log;
org.infinispan.util.logging.LogFactory;

/**
* An Infinispan listener that simply logs cache entries being created and
* removed
*
* @author Pete Muir
*/
@Listener
public class LoggingListener {
private Log log = LogFactory.getLog(LoggingListener.class);
@CacheEntryCreated
public void observeAdd(CacheEntryCreatedEvent<?, ?> event) {
if (!event.isPre()) // So that message is only logged after operation succeeded
log.infof("Cache entry with key %s added in cache %s", event.getKey(),
event.getCache());
}
@CacheEntryRemoved
public void observeRemove(CacheEntryRemovedEvent<?, ?> event) {
log.infof("Cache entry with key %s removed in cache %s", event.getKey(),
event.getCache());
}
}

Listeners methods are declared using annotations, and receive a payload which contains metadata
about the notification. Listeners are notified of any changes. Here, the listeners simply log any
entries added or removed.

The replication mode example contains two nodes, each of which are started in a separate process. The
nodes are very simple, Node0 starts up, registers a listener that logs any changes, and waits for the cluster
to form. Node1 starts up, waits for the cluster to form, and then adds an entry. The interesting work happens
in the common super class, examined in Configuring a replicated data-grid.

JBoss Community Documentation

Page 28 of 617

Infinispan 6.0

Waiting for the cluster to form


Infinispan only replicates data to nodes which are already in the cluster. If a node is added to the
cluster after an entry is added, it won't be replicated there. In order to see replication take effect, we
need to wait until Both nodes make use of the utility class ClusterValidation, calling it's
waitForClusterToForm to achieve this. We won't dig into how this works here, but if you are
interested take a look at the code.

The distribution mode example contains three nodes, each of which are started in a separate process. The
nodes are very simple, Node0 and Node1 start up, register listeners that logs any changes, and wait for the
cluster to form. Node2 starts up, waits for the cluster to form, and then adds 20 entries. Each entry get's
distributed to it's owners, and you will see some entries add on Node0 and some on Node1. You'll notice
that Node2 gets notified of all adds - this is just because it is the node which adds the entry, it doesn't
reflect that the fact that all these entries are stored there! The interesting work happens in the common super
class, examined in Configuring a distributed data-grid.

JBoss Community Documentation

Page 29 of 617

Infinispan 6.0

2.5.2 Configuring the cluster


First, we need to ensure that Infinispan is cluster aware. Infinispan provides a default configuration for a
clustered cache:

new ConfigurationBuilder()
.clustering().cacheMode(CacheMode.REPL_SYNC)
.build()

GlobalConfiguration.getClusteredDefault() is a quick way to get a preconfigured,


cluster-aware GlobalConfiguration and can be used as a starting point to fine tuning the
configuration.

Tweaking the cluster configuration for your network


Depending on your network setup, you may need to tweak your JGroups set up. JGroups is configured via
an XML file; the file to use can be specified via the GlobalConfiguration:

GlobalConfigurationBuilder.defaultClusteredBuilder()
.transport().addProperty("configurationFile", "jgroups.xml")
.build()

The JGroups documentation provides extensive advice on getting JGroups working on your
network. If you are new to configuring JGroups, you may get a little lost, so you might want to try
tweaking these configuration parameters:
Using the system property -Djgroups.bind_addr="127.0.0.1" causes JGroups to
bind only to your loopback interface, meaning any firewall you may have configured won't
get in the way. Very useful for testing a cluster where all nodes are on one machine.
TODO - add more tips!

You can also configure the JGroups properties to use in Infinispan's XML configuration:

<global>
<transport>
<properties>
<property name="configurationFile" value="jgroups.xml"/>
</properties>
</transport>
</global>

JBoss Community Documentation

Page 30 of 617

Infinispan 6.0

2.5.3 Configuring a replicated data-grid


In replicated mode, Infinispan will store every entry on every node in the grid. This offers high durability and
availability of data, but means the storage capacity is limited by the available heap space on the node with
least memory.
The cache should be configured to work in replication mode (either synchronous or asynchronous), and can
otherwise be configured as normal. For example, if you want to configure the cache programatically:

private static EmbeddedCacheManager createCacheManagerProgramatically() {


return new DefaultCacheManager(
GlobalConfigurationBuilder.defaultClusteredBuilder()
.transport().addProperty("configurationFile", "jgroups.xml")
.build(),
new ConfigurationBuilder()
.clustering().cacheMode(CacheMode.REPL_SYNC)
.build()
);
}

You can configure an identical cache using XML:


cfg.xml:

<infinispan xsi:schemaLocation="urn:infinispan:config:5.1
http://www.infinispan.org/schemas/infinispan-config-5.1.xsd"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="urn:infinispan:config:5.1">
<global>
<transport>
<properties>
<property name="configurationFile" value="jgroups.xml"/>
</properties>
</transport>
</global>
<default>
<!-- Configure a synchronous replication cache -->
<clustering mode="replication">
<sync/>
</clustering>
</default>
</infinispan>

private static EmbeddedCacheManager createCacheManagerFromXml() throws IOException {


return new DefaultCacheManager("infinispan-replication.xml");
}

JBoss Community Documentation

Page 31 of 617

Infinispan 6.0

2.5.4 Configuring a distributed data-grid


In distributed mode, Infinispan will store every entry on a subset of the nodes in the grid (controlled by the
parameter numOwners, which controls how many owners each entry will have). Compared to replication,
distribution offers increased storage capacity, but with reduced availability (increased latency to access data)
and durability. Adjusting the number of owners allows you to obtain the trade off between space, durability
and availability.
Infinispan also offers a topology aware consistent hash which will ensure that the owners of entries are
located in different data centers, racks and nodes to offer improved durability in case of node or network
outages.
The cache should be configured to work in distibuted mode (either synchronous or asynchronous), and can
otherwise be configured as normal. For example, if you want to configure the cache programatically:

new ConfigurationBuilder()
.clustering()
.cacheMode(CacheMode.DIST_SYNC)
.hash().numOwners(2)
.build()

You can configure an identical cache using XML:


cfg.xml:

<default>
<!-- Configure a synchronous replication cache -->
<clustering mode="distribution">
<sync/>
<hash numOwners="2"/>
</clustering>
</default>

2.6 Creating your own Infinispan project


TODO

2.7 Using Infinispan as a second level cache for


Hibernate
TODO

JBoss Community Documentation

Page 32 of 617

Infinispan 6.0

2.8 Accessing an Infinispan data grid remotely


2.8.1 Using Hot Rod to access an Infinispan data-grid
TODO

2.8.2 Using REST to access an Infinipsan data-grid


TODO

2.8.3 Using memcached to access an Infinispan data-grid


TODO

2.9 Using Infinispan in JBoss AS 7


TODO

2.10 Using Infinispan in servlet containers (such as


Tomcat or Jetty) and other application servers (such as
GlassFish)
TODO

2.11 Monitoring Infinispan

JBoss Community Documentation

Page 33 of 617

Infinispan 6.0

2.12 Getting Started Guide - Introduction


This guide will walk you through downloading, installing and running Infinispan for the first time. It will then
introduce to some of the key features of Infinispan.
Infinispan can be used in a variety of runtimes:
Java SE, started by your application
an application server which provides Infinispan as a service (such as JBoss AS)
bundled as a library in your application, deployed to an application server, and started on by your
application (for example, you could use Infinispan with Tomcat or GlassFish)
Infinispan offers four modes of operation, which determine how and where the data is stored:
Local, where entries are stored on the local node only, regardless of whether a cluster has formed. In
this mode Infinispan is typically operating as a local cache
Invalidation, where all entries are stored into a cache store (such as a database) only, and
invalidated from all nodes. When a node needs the entry it will load it from a cache store. In this mode
Infinispan is operating as a distributed cache, backed by a canonical data store such as a database
Replication, where all entries are replicated to all nodes. In this mode Infinispan is typically operating
as a data grid or a temporary data store, but doesn't offer an increased heap space
Distribution, where entries are distributed to a subset of the nodes only. In this mode Infinispan is
typically operating as a data grid providing an increased heap space
Invalidation, Replication and Distribution can all use synchronous or asynchronous communication.
Infinispan offers two access patterns, both of which are available in any runtime:
Embedded into your application code
As a Remote server accessed by a client (REST, memcached or Hot Rod)
This guide will introduce to each of the runtime options, access patterns and modes of operations by walking
you through simple applications for each. All these applications are available in the Infinispan Quickstart
distribution.

JBoss Community Documentation

Page 34 of 617

Infinispan 6.0

2.13 Getting Started Guide - Downloading, installing


and running Infinispan
To run the Infinispan, you'll need
Java 1.6
Maven 3, if you wish to use the quickstart examples or create a new project using the Infinispan
archetype
the Infinispan distribution zip, if you wish to use Infinispan in server mode, or want to use the jars in
an ant project
the Infinispan Quickstart zip, if you want to follow along with the projects discussed in the guide

If you already have any of these pieces of software, there is no need to install them again!

Choose your Java runtime, and follow their installation instructions. For example, you could choose one of:
OpenJDK
Oracle Java SE
Oracle JRockit
Follow the official Maven installation guide if you don't already have Maven 3 installed. You can check which
version of Maven you have installed (if any) by running mvn --version. If you see a version newer than
3.0.0, you are ready to go.

You can also deploy the examples using your favorite IDE. We provide instructions for using
Eclipse only.

Finally, download Infinispan and the Infinispan Quickstart from the download page.

2.14 Getting Started Guide - Embedded Cache in Java


SE
Running Infinispan in embedded mode is very easy. First, we'll set up a project, and then we'll run Infinispan,
and start adding data.

embedded-cache quickstart
All the code discussed in this tutorial is available in the embedded-cache quickstart.

JBoss Community Documentation

Page 35 of 617

Infinispan 6.0

2.14.1 Creating a new Infinispan project


The only thing you need to set up Infinispan is add it's dependencies to your project. If you are using Maven
(or another build system like Gradle or Ivy which can use Maven dependencies), then this is easy. Just add:
pom.xml snippet
053.
054.
055.
056.
057.

<dependency>
<groupId>org.infinispan</groupId>
<artifactId>infinispan-embedded</artifactId>
<version>${infinispan.version}</version>
</dependency>

to your <dependencies> section of the POM. You'll need to substitute ${infinispan.version} for the
version of Infinispan you wish to use.

Which version of Infinispan should I use?


We recommend using the latest final version of Infinispan. All releases are displayed on the
downloads page.

You'll also need to enable the JBoss Maven repository. We recommend adding a profile:

JBoss Community Documentation

Page 36 of 617

Infinispan 6.0

pom.xml snippet
076.
077.
078.
079.
080.
081.
082.
083.
084.
085.
086.
087.
088.
089.
090.
091.
092.
093.
094.
095.
096.
097.
098.
099.
100.
101.
102.
103.
104.
105.
106.
107.
108.
109.
110.
111.
112.
113.
114.

<executions>
<execution>
<goals>
<goal>java</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
<profiles>
<profile>
<id>jboss-public-repository</id>
<activation>
<property>
<name>jboss-public-repository</name>
<value>!false</value>
</property>
</activation>
<repositories>
<repository>
<id>jboss-public-repository-group</id>
<name>JBoss Public Maven Repository Group</name>
<url>http://repository.jboss.org/nexus/content/groups/public</url>
<releases>
<enabled>true</enabled>
<updatePolicy>never</updatePolicy>
</releases>
<snapshots>
<enabled>true</enabled>
<updatePolicy>never</updatePolicy>
</snapshots>
</repository>
</repositories>
<pluginRepositories>
<pluginRepository>
<id>jboss-public-repository-group</id>
<name>JBoss Public Maven Repository Group</name>

Alternatively, you can use the POM from the quickstart that accompanies this tutorial.
If you are using Ant, or another build system which doesn't provide declarative dependency management,
then the Infinispan distribution zip contains a lib/ directory. Add the contents of this to the build classpath.

JBoss Community Documentation

Page 37 of 617

Infinispan 6.0

2.14.2 Running Infinispan on a single node


In order to run Infinispan, we're going to create a main method in the Quickstart class. Infinispan comes
configured to run out of the box; once you have set up your dependencies, all you need to do to start using
Infinispan is to create a new cache manager and get a handle on the default cache.
Quickstart.java
28. public class Quickstart {
29.
30.
public static void main(String args[]) throws Exception {
31.
Cache<Object, Object> c = new DefaultCacheManager().getCache();
32.
}

We now need a way to run the main method! If you are using Maven, the best approach is to copy all the
project dependencies to a directory, and at the same time compile the java classes from our project:

$> mvn clean compile dependency:copy-dependencies -DstripVersion

Having done that, we can run the main method:

$> java -cp target/classes/:target/dependency/* Quickstart

You should see Infinispan start up, and the version in use logged to the console.
Congratulations, you now have Infinispan running as a local cache!

JBoss Community Documentation

Page 38 of 617

Infinispan 6.0

2.14.3 Use the default cache


Infinispan exposes a Map-like, JSR-107-esque interface for accessing and mutating the data stored in the
cache. For example:
DefaultCacheQuickstart.java
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.

// Add a entry
cache.put("key", "value");
// Validate the entry is now in the cache
assertEqual(1, cache.size());
assertTrue(cache.containsKey("key"));
// Remove the entry from the cache
Object v = cache.remove("key");
// Validate the entry is no longer in the cache
assertEqual("value", v);

Infinispan offers a thread-safe data-structure:


DefaultCacheQuickstart.java
48.
49.
50.
51.
52.
53.

// Add an entry with the key "key"


cache.put("key", "value");
// And replace it if missing
cache.putIfAbsent("key", "newValue");
// Validate that the new value was not added

By default entries are immortal but you can override this on a per-key basis and provide lifespans.
DefaultCacheQuickstart.java
58.
59.
//By default entries are immortal but we can override this on a per-key basis and
provide lifespans.
60.
cache.put("key", "value", 5, SECONDS);
61.
assertTrue(cache.containsKey("key"));
62.
Thread.sleep(10000);

JBoss Community Documentation

Page 39 of 617

Infinispan 6.0

2.14.4 Use a custom cache


Each cache in Infinispan can offer a different set of features (for example transaction support, different
replication modes or support for eviction), and you may want to use different caches for different classes of
data in your application. To get a custom cache, you need to register it with the manager first:
CustomCacheQuickstart.java
33.
34.
35.
36.
37.
38.
39.

public static void main(String args[]) throws Exception {


EmbeddedCacheManager manager = new DefaultCacheManager();
manager.defineConfiguration("custom-cache", new ConfigurationBuilder()
.eviction().strategy(LIRS).maxEntries(10)
.build());
Cache<Object, Object> c = manager.getCache("custom-cache");

The example above uses Infinispan's fluent configuration, which offers the ability to configure your cache
programmatically. However, should you prefer to use XML, then you may. We can create an identical cache
to the one created with a programmatic configuration:
infinispan.xml
24. <infinispan
25.
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
26.
xsi:schemaLocation="urn:infinispan:config:7.0
http://www.infinispan.org/schemas/infinispan-config-7.0.xsd"
27.
xmlns="urn:infinispan:config:7.0">
28.
29.
<cache-container default-cache="default">
30.
<local-cache name="xml-configured-cache">
31.
<eviction strategy="LIRS" max-entries="10" />
32.
</local-cache>
33.
</cache-container>

We then need to load the configuration file, and use the programmatically defined cache:
XmlConfiguredCacheQuickstart.java
29.
30.
public static void main(String args[]) throws Exception {
31.
Cache<Object, Object> c = new
DefaultCacheManager("infinispan.xml").getCache("xml-configured-cache");

2.15 Getting Started Guide - Clustered Cache in Java SE


Clustering Infinispan is simple. Under the covers, Infinispan uses JGroups as a network transport, and
JGroups handles all the hard work of forming a cluster.

JBoss Community Documentation

Page 40 of 617

Infinispan 6.0

Sharing JGroups channels


By default all caches created from a single CacheManager share the same JGroups channel and
multiplex RPC messages over it. In this example caches 1, 2 and 3 all use the same JGroups
channel:

EmbeddedCacheManager cm = //
Cache<Object, Object> cache1
Cache<Object, Object> cache2
Cache<Object, Object> cache3

get CacheManager from somewhere


= cm.getCache("replSyncCache");
= cm.getCache("replAsyncCache");
= cm.getCache("invalidationSyncCache");

clustered-cache quickstart
All the code discussed in this tutorial is available in the clustered-cache quickstart.

2.15.1 Running Infinispan in a cluster


It is easy set up a clustered cache. This tutorial will show you how to create two nodes in different processes
on the same local machine. The quickstart follows the same structure as the embedded-cache quickstart,
using Maven to compile the project, and a main method to launch the node.
If you are following along with the quickstarts, you can try the examples out. First, compile the project:

$> mvn clean compile dependency:copy-dependencies -DstripVersion

The quickstart contains two examples of a clustered cache, one in replication mode and one distribution
mode. To run the replication mode example, we need to launch both nodes from different consoles. For the
first node:

$> java -cp target/classes/:target/dependency/*


org.infinispan.quickstart.clusteredcache.replication.Node0

And for the second node:

$> java -cp target/classes/:target/dependency/*


org.infinispan.quickstart.clusteredcache.replication.Node1

You should see JGroups and Infinispan start up on both consoles, and after about 15s the cache entry log
message appear on the console of the first node.

JBoss Community Documentation

Page 41 of 617

Infinispan 6.0
To run the distribution mode example, we need to launch three nodes from different consoles. For the first
node:

$> java -cp target/classes/:target/dependency/*


org.infinispan.quickstart.clusteredcache.distribution.Node0

And for the second node:

$> java -cp target/classes/:target/dependency/*


org.infinispan.quickstart.clusteredcache.distribution.Node1

And for the third node:

$> java -cp target/classes/:target/dependency/*


org.infinispan.quickstart.clusteredcache.distribution.Node2

You should see JGroups and Infinispan start up on both consoles, and after about 15s see the 10 entries
added by third node distributed to the first and second nodes.

JBoss Community Documentation

Page 42 of 617

Infinispan 6.0

clustered-cache quickstart architecture


Logging changes to the cache
An easy way to see what is going on with your cache is to log mutated entries. An Infinispan
listener is notified of any mutations:

import
import
import
import
import
import
import

org.infinispan.notifications.Listener;
org.infinispan.notifications.cachelistener.annotation.CacheEntryCreated;
org.infinispan.notifications.cachelistener.annotation.CacheEntryRemoved;
org.infinispan.notifications.cachelistener.event.CacheEntryCreatedEvent;
org.infinispan.notifications.cachelistener.event.CacheEntryRemovedEvent;
org.infinispan.util.logging.Log;
org.infinispan.util.logging.LogFactory;

/**
* An Infinispan listener that simply logs cache entries being created and
* removed
*
* @author Pete Muir
*/
@Listener
public class LoggingListener {
private Log log = LogFactory.getLog(LoggingListener.class);
@CacheEntryCreated
public void observeAdd(CacheEntryCreatedEvent<?, ?> event) {
if (!event.isPre()) // So that message is only logged after operation succeeded
log.infof("Cache entry with key %s added in cache %s", event.getKey(),
event.getCache());
}
@CacheEntryRemoved
public void observeRemove(CacheEntryRemovedEvent<?, ?> event) {
log.infof("Cache entry with key %s removed in cache %s", event.getKey(),
event.getCache());
}
}

Listeners methods are declared using annotations, and receive a payload which contains metadata
about the notification. Listeners are notified of any changes. Here, the listeners simply log any
entries added or removed.

The replication mode example contains two nodes, each of which are started in a separate process. The
nodes are very simple, Node0 starts up, registers a listener that logs any changes, and waits for the cluster
to form. Node1 starts up, waits for the cluster to form, and then adds an entry. The interesting work happens
in the common super class, examined in Configuring a replicated data-grid.

JBoss Community Documentation

Page 43 of 617

Infinispan 6.0

Waiting for the cluster to form


Infinispan only replicates data to nodes which are already in the cluster. If a node is added to the
cluster after an entry is added, it won't be replicated there. In order to see replication take effect, we
need to wait until Both nodes make use of the utility class ClusterValidation, calling it's
waitForClusterToForm to achieve this. We won't dig into how this works here, but if you are
interested take a look at the code.

The distribution mode example contains three nodes, each of which are started in a separate process. The
nodes are very simple, Node0 and Node1 start up, register listeners that logs any changes, and wait for the
cluster to form. Node2 starts up, waits for the cluster to form, and then adds 20 entries. Each entry get's
distributed to it's owners, and you will see some entries add on Node0 and some on Node1. You'll notice
that Node2 gets notified of all adds - this is just because it is the node which adds the entry, it doesn't
reflect that the fact that all these entries are stored there! The interesting work happens in the common super
class, examined in Configuring a distributed data-grid.

JBoss Community Documentation

Page 44 of 617

Infinispan 6.0

2.15.2 Configuring the cluster


First, we need to ensure that Infinispan is cluster aware. Infinispan provides a default configuration for a
clustered cache:

new ConfigurationBuilder()
.clustering().cacheMode(CacheMode.REPL_SYNC)
.build()

GlobalConfiguration.getClusteredDefault() is a quick way to get a preconfigured,


cluster-aware GlobalConfiguration and can be used as a starting point to fine tuning the
configuration.

Tweaking the cluster configuration for your network


Depending on your network setup, you may need to tweak your JGroups set up. JGroups is configured via
an XML file; the file to use can be specified via the GlobalConfiguration:

GlobalConfigurationBuilder.defaultClusteredBuilder()
.transport().addProperty("configurationFile", "jgroups.xml")
.build()

The JGroups documentation provides extensive advice on getting JGroups working on your
network. If you are new to configuring JGroups, you may get a little lost, so you might want to try
tweaking these configuration parameters:
Using the system property -Djgroups.bind_addr="127.0.0.1" causes JGroups to
bind only to your loopback interface, meaning any firewall you may have configured won't
get in the way. Very useful for testing a cluster where all nodes are on one machine.
TODO - add more tips!

You can also configure the JGroups properties to use in Infinispan's XML configuration:

<global>
<transport>
<properties>
<property name="configurationFile" value="jgroups.xml"/>
</properties>
</transport>
</global>

JBoss Community Documentation

Page 45 of 617

Infinispan 6.0

2.15.3 Configuring a replicated data-grid


In replicated mode, Infinispan will store every entry on every node in the grid. This offers high durability and
availability of data, but means the storage capacity is limited by the available heap space on the node with
least memory.
The cache should be configured to work in replication mode (either synchronous or asynchronous), and can
otherwise be configured as normal. For example, if you want to configure the cache programatically:

private static EmbeddedCacheManager createCacheManagerProgramatically() {


return new DefaultCacheManager(
GlobalConfigurationBuilder.defaultClusteredBuilder()
.transport().addProperty("configurationFile", "jgroups.xml")
.build(),
new ConfigurationBuilder()
.clustering().cacheMode(CacheMode.REPL_SYNC)
.build()
);
}

You can configure an identical cache using XML:


cfg.xml:

<infinispan xsi:schemaLocation="urn:infinispan:config:5.1
http://www.infinispan.org/schemas/infinispan-config-5.1.xsd"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="urn:infinispan:config:5.1">
<global>
<transport>
<properties>
<property name="configurationFile" value="jgroups.xml"/>
</properties>
</transport>
</global>
<default>
<!-- Configure a synchronous replication cache -->
<clustering mode="replication">
<sync/>
</clustering>
</default>
</infinispan>

private static EmbeddedCacheManager createCacheManagerFromXml() throws IOException {


return new DefaultCacheManager("infinispan-replication.xml");
}

JBoss Community Documentation

Page 46 of 617

Infinispan 6.0

2.15.4 Configuring a distributed data-grid


In distributed mode, Infinispan will store every entry on a subset of the nodes in the grid (controlled by the
parameter numOwners, which controls how many owners each entry will have). Compared to replication,
distribution offers increased storage capacity, but with reduced availability (increased latency to access data)
and durability. Adjusting the number of owners allows you to obtain the trade off between space, durability
and availability.
Infinispan also offers a topology aware consistent hash which will ensure that the owners of entries are
located in different data centers, racks and nodes to offer improved durability in case of node or network
outages.
The cache should be configured to work in distibuted mode (either synchronous or asynchronous), and can
otherwise be configured as normal. For example, if you want to configure the cache programatically:

new ConfigurationBuilder()
.clustering()
.cacheMode(CacheMode.DIST_SYNC)
.hash().numOwners(2)
.build()

You can configure an identical cache using XML:


cfg.xml:

<default>
<!-- Configure a synchronous replication cache -->
<clustering mode="distribution">
<sync/>
<hash numOwners="2"/>
</clustering>
</default>

2.16 Infinispan GUI demo


This document walks you through using the Infinispan GUI demo that ships with Infinispan, and assumes
that you have downloaded the latest version of Infinispan and unzipped the archive. I will refer to the
Infinispan directory created by unzipping the archive as ${INFINISPAN_HOME}.

NOTE: You will need either the -bin.zip or -all.zip version for this demo.

JBoss Community Documentation

Page 47 of 617

Infinispan 6.0

2.16.1 Step 1: Start the demo GUI


$ cd ${INFINISPAN_HOME}
$ bin/runGuiDemo.sh

An equivalent runGuiDemo.bat file is also provided for Windows users.

Step 2: Start the cache


Start the cache in the GUI that starts up, using the Start Cache button.

2.16.2 Step 3: Manipulate data


In the Manipulate Data tab, add entries, generate random data, etc.

2.16.3 Step 4: Start more cache instances


Repeat steps 1 and 2 to launch and start up more caches. Watch cluster formation in the Cluster View tab.

JBoss Community Documentation

Page 48 of 617

Infinispan 6.0

2.16.4 Step 5: Manipulate more data


Add and remove data on any of the nodes, and watch state being distributed. Shut nodes down as well to
witness data durability.

2.17 Getting Started Guide - JBoss AS 7


JBoss AS 7 bundles Infinispan, and will start the Infinispan service when required. The Infinispan service
provides a CacheManager in JNDI which you can use in your application. JBoss AS 7 provides unified
configuration for all services, so the configuration format (but not semantics) is different than the native
Infinispan configuration.
This tutorial will show you how to create a simple, clustered, cache on JBoss AS 7, and deploy to the server.
It will also outline the configuration differences to the native Infinispan format.

2.17.1 Configuration
Unlike previous releases of JBoss AS, JBoss AS 7 centralizes all server configuration into one location. This
include Infinispan cache configurations, which are defined by the Infinispan subsystem:
$JBOSS_HOME/domain/configuration/domain.xml

if you are using JBoss AS 7 in


the managed domain mode

$JBOSS_HOME/standalone/configuration/standalone-ha.xml if you are using JBoss AS 7 in


standalone mode (similar to
previous versions of JBoss AS)

The complete schema for the Infinispan subsystem is included in the AS7 binary distribution
$JBOSS_HOME/docs/schema/jboss-infinispan.xsd.

If you are familiar with Infinispan's native configuration file format or the corresponding configuration file from
JBoss AS 6, you'll notice some obvious similarities, but some noteworthy differences.
While a native Infinispan configuration file contains cache configurations for a single cache managers, like
JBoss AS 6, the Infinispan subsystem configuration defines multiple cache managers, each identified by a
name. As with AS6, cache managers can have 1 or more aliases.

JBoss Community Documentation

Page 49 of 617

Infinispan 6.0

Being concise
The Infinispan subsystem's configuration schema attempts to be more concise than the equivalent
configuration in JBoss AS 6. This is a direct result of the following changes:

Where is <global/> ?
Much of the global configuration contains references to other JBoss AS services. In JBoss AS 7, these
services are auto-injected behind the scenes. This includes things like thread pools (described below), the
JGroups transport (also described below), and the mbean server.

Configuration default values


JBoss AS 7 supplies a set of custom default values for various configuration properties. These defaults differ
depending on the cache mode. The complete set of default values can be found in

https://github.com/jbossas/jboss-as/blob/master/clustering/infinispan/src/main/resources/i
.

File-based cache store


Because clustering services use the file-based cache store frequently, we've simplified its definition(by using
a distinctive element you no longer need to specify the class name). The location of the store is defined by 2
attributes <file-store relative-to="..." path="..."/>. The relative-to attribute defines a named
path, and defaults to the server's data directory; whereas the path attribute specifies the directory within
relative-to, and defaults to the cache container name.

Specifying cache mode


Instead of defining the cache mode via a separate <clustering mode="..."/> attribute, each cache
mode uses it's own element, the child elements of which are specific to that cache mode. For example,
rehashing properties are only available within the <distributed-cache/> element.

Where is <default/> ?
The semantics of the default cache of a cache container are different in JBoss AS 7 than in native Infinispan.
In native Infinispan, the configuration within <default/> defines the cache returned by calls to
CacheContainer.getCache(), while <namedCache/> entries inherit the configuration from the default
cache.
In JBoss AS 7, all caches defined in the Infinispan subsystem are named caches. The default-cache
attribute identifies which named cache should be returned by calls to CacheContainer.getCache(). This
lets you easily modify the default cache of a cache container, without having to worry about rearranging
configuration property inheritance.

JBoss Community Documentation

Page 50 of 617

Infinispan 6.0

Specifying a transport
The Infinispan subsystem uses with the JGroups subsystem to provide it's JGroups channel. By default,
cache containers use the default-stack as defined by the JGroups subsystem.

<subsystem xmlns="urn:jboss:domain:jgroups:1.0" default-stack="udp">


<stack name="udp">
<!-- ... -->
</stack>
<stack name="tcp">
<!-- ... -->
</stack>
</subsystem>

Changing the default stack for all clustering services is a simple as changing the default-stack attribute
defined in the JGroups subsystem. An individual cache-container can opt to use a particular stack by
specifying a stack attribute within its transport element. For example:

<cache-container name="web" default-cache="repl">


<transport stack="tcp"/>
<replicated-cache name="repl" mode="ASYNC" batching="true">
<locking isolation="REPEATABLE_READ"/>
<file-store/>
</replicated-cache>
</cache-container>

JGroups channels are named using the cache container name.

JBoss Community Documentation

Page 51 of 617

Infinispan 6.0

Defining thread pools


Cache containers defined by the Infinispan subsystem can reference thread pools defined by the threading
subsystem. Externalizing thread pool in this way has the additional advantage of being able to manage the
thread pools via native JBoss AS management mechanisms, and allows you to share thread pools across
cache containers. For example:

<cache-container name="web" default-cache="repl" listener-executor="infinispan-listener"


eviction-executor="infinispan-eviction" replication-queue-executor="infinispan-repl-queue">
<transport executor="infinispan-transport"/>
<replicated-cache name="repl" mode="ASYNC" batching="true">
<locking isolation="REPEATABLE_READ"/>
<file-store/>
</replicated-cache>
</cache-container>
<subsystem xmlns="urn:jboss:domain:threads:1.0">
<thread-factory name="infinispan-factory" priority="1"/>
<bounded-queue-thread-pool name="infinispan-transport"/>
<core-threads count="1"/>
<queue-length count="100000"/>
<max-threads count="25"/>
<thread-factory name="infinispan-factory"/>
</bounded-queue-thread-pool>
<bounded-queue-thread-pool name="infinispan-listener"/>
<core-threads count="1"/>
<queue-length count="100000"/>
<max-threads count="1"/>
<thread-factory name="infinispan-factory"/>
</bounded-queue-thread-pool>
<scheduled-thread-pool name="infinispan-eviction"/>
<max-threads count="1"/>
<thread-factory name="infinispan-factory"/>
</scheduled-thread-pool>
<scheduled-thread-pool name="infinispan-repl-queue"/>
<max-threads count="1"/>
<thread-factory name="infinispan-factory"/>
</scheduled-thread-pool>
</subsystem>

JBoss Community Documentation

Page 52 of 617

Infinispan 6.0

2.17.2 Cache container lifecycle


During JBoss AS 6 server startup, the CacheContainerRegistry service would create and start all cache
containers defined within its infinispan-configs.xml file. Individual caches were started and stopped as
needed. Lifecycle control of a cache was the complete responsibility of the application or service that used it.
Instead of a separate CacheContainerRegistry, JBoss AS 7 uses the generic ServiceRegistry from
JBoss MSC (JBoss Modular Service Container). When JBoss AS 7 starts, it creates on-demand services for
each cache and cache container defined in the Infinispan subsystem. A service or deployment that needs to
use a given cache or cache container simply adds a dependency on the relevant service name. When the
service or deployment stops, dependent services are stopped as well, provided they are not still demanded
by some other service or deployment. In this way, JBoss AS 7 handles cache and cache container lifecycle
for you.
There may be an occasion where you'd like a cache to start eagerly when the server starts, without requiring
a dependency from some service or deployment. This can be achieve by using the start attribute of a cache.
For example:

<cache-container name="cluster" default-cache="default">


<alias>ha-partition</alias>
<replicated-cache name="default" mode="SYNC" batching="true" start="EAGER">
<locking isolation="REPEATABLE_READ"/>
</replicated-cache>
</cache-container>

Using an Infinispan cache directly


AS7 adds the ability to inject an Infinispan cache into your application using Java EE resource injection. This
is perhaps best explained by an example:

@ManagedBean
public class MyBean<K, V> {
@Resource(lookup="java:jboss/infinispan/my-container-name")
private org.infinispan.manager.CacheContainer container;
private org.infinispan.Cache<K, V> cache;
@PostConstruct
public void start() {
this.cache = this.container.getCache();
}
}

That's it! No JBoss specific classes required - only standard annotations. Pretty neat, no?
There's only one catch - due to the JBoss AS's use of modular classloading, Infinispan classes are not
available to deployments by default. You need to explicitly tell the AS to import the Infinispan API into your
application. This is most easily done by adding the following line to your application's
META-INF/MANIFEST.MF:

JBoss Community Documentation

Page 53 of 617

Infinispan 6.0

Dependencies: org.infinispan export

If you're using maven you can achieve that simply by adding this configuration to you pom.xml:

<build>
<plugins>
<plugin>
<artifactId>maven-war-plugin</artifactId>
<version>2.1.1</version>
<configuration>
<!-- Java EE 6 doesn't require web.xml, Maven needs to catch up! -->
<failOnMissingWebXml>false</failOnMissingWebXml>
<archive>
<manifestEntries>
<Dependencies>org.infinispan export</Dependencies>
</manifestEntries>
</archive>
</configuration>
</plugin>
</plugins>
</build>

So, how does it all work? If you recall, during server startup, JBoss AS creates and registers an on-demand
service for every Infinispan cache container defined in the Infinispan subsystem. For every cache container,
the Infinispan subsystem also creates and registers a JNDI binding service that depends on the associated
cache container service. When the JBoss AS deployer encounters the @Resource annotation, it
automatically adds a dependency to the application on the JNDI binding service associated with the
specified JNDI name. In the case of the Infinispan JNDI binding, the binding itself already depends on the
relevant Infinispan cache container service. The net effect is, your application will include a dependency on
the requested cache container. Consequently, the cache container will automatically start on deploy, and
stop (including all caches) on undeploy.

2.18 Labs
2.18.1 A list of the labs developed for Infinispan

JBoss Community Documentation

Page 54 of 617

Infinispan 6.0

2.18.2 Lab - Getting Started with Infinispan


Introduction
This lab was developed for Devoxx 2011, by Pete Muir, Mircea Markus and Sanne Grinovero. It is designed
to last around 1h 45m, and has an accompanying introduction and conclusion. Full slide deck is attached.
The lab has been updated by Galder Zamarreo for Infinispan 5.1 and has been featured in the Neuchatel
JBUG and JUDCon India 2012

Setup
Getting setup to run the lab
presented by Pete
5 minutes
Using Infinispan 5.1.0.FINAL
Download the lab zip from
[...]
Unzip the lab to your disk to a location of your choice
If you are a git user, you can clone the repository:

git clone git://github.com/infinispan/infinispan-labs.git

each stage of this lab has a checkpoint which is a branch, you can check out the code for each
Checkpoint using. Checkpoints are mentioned in these instructions:

git checkout -b checkpointX checkpointX

Download JBoss AS 7.1.0.CR1b from http://jboss.org/jbossas/downloads


Unzip JBoss AS to your disk to a location of your choice

Introduction
Use cases, key features and benefits of Infinispan
slides, presented by Pete
20 minutes

JBoss Community Documentation

Page 55 of 617

Infinispan 6.0

Sample project
Explanation of sample project architecture
presented by Pete
5 minutes
The lab is a simple ticket allocation and booking system
lab1 contains a project skeleton with the relevant dependencies available. It is a war, that can be
deployed on JBoss AS 7. It also use CDI to wire together the app, and JSF for the view layer. JMS is
used to provide messaging and EJB to provide a listener for messages we send via JMS.
In another console, start JBoss AS - $JBOSS_HOME/bin/standalone.sh
Deploy the project to JBoss AS 7 using mvn clean package jboss-as:deploy
visit http://localhost:8080/lab1
All cache operations hidden by service layer to allow us to swap out caching impls
Starts with a HashMap and builds on that
Import the project into your IDE, we use Eclipse with m2eclipse installed.
Show project
Checkpoint 1

Interlude - Caching in Java EE


107 (JCACHE) and JSR-347 (Datagrids for Java)
presented by Pete
5 minutes
Topics covered include:
TODO

JBoss Community Documentation

Page 56 of 617

Infinispan 6.0

JGroups & Networks


presented by Sanne
10 minutes

Make sure your nodes can see each other


In LAB_HOME/nic_test there is the the test-network script. Run it.
If all goes well, you'll get two windows in which you can draw up on your screen. Draw on one, see it
in both.

How does JGroups work? Why do you need it?


Topics covered include:
what is JGroups? library for reliable multicasting ...
main features: fragmentation, retransmission, flow control, reordering, group membership
(notifications)
LAN/WAN based: multicast or TCP for transport

Infinispan as a local cache and JMX


presented by Sanne
10 minutes

Adding Infinispan to the demo


Use Case: Take advantage of the features of Infinispan
Uncomment the Infinispan dependencies in pom.xml
Copy in Resources.java and TicketAllocationCache.java and explain what they are doing;
you will find them in LAB_HOME/lab1/src/samples/java
Explain about configuring caches programmatically with qualifier
Copy SimpleTicketService to InfinispanTicketService
Make SimpleTicketService an alternative

private final List<TicketAllocation> tickets = new ArrayList<TicketAllocation>();

with

@Inject @TicketAllocationCache
private Cache<String, TicketAllocation> tickets;

to inject the Infinispan cache. Change the allocateTicket method to:

JBoss Community Documentation

Page 57 of 617

Infinispan 6.0

TicketAllocation allocation = new TicketAllocation(allocatedTo, event);


tickets.put(allocation.getId(), allocation);

and change the getAllocatedTickets() method to

return new ArrayList<TicketAllocation>(tickets.values());

and change the getTicketAllocation(String id) method to:

return tickets.get(id);

Implement getNodeId() properly:

if (tickets.getConfiguration().getCacheMode() != CacheMode.LOCAL)
return tickets.getAdvancedCache().getCacheManager().getAddress().toString();
else
return "local cache";

Implement getOwners() properly:

if (tickets.getConfiguration().getCacheMode() != CacheMode.LOCAL) {
return asCommaSeparatedList(tickets.getAdvancedCache().getDistributionManager().locate(key));
} else {
return "local";
}

Show Infinispan in use with basic monitoring


Use Case: Can see how our cache is performing
Enable JMX - add .jmxStatistics().enable() to the fluent configuration in Resources.
Redeploy, and use the app
We can see the cache starting in the console
Run jconsole or jvisualvm, and select the "jboss-modules" process
Open up the Infinispan statistics (via MBeans tab in jvisualvm - you might need to install the
MBeans plugin first)
Allocate a ticket, show the stores change
Checkpoint 2

JBoss Community Documentation

Page 58 of 617

Infinispan 6.0

Expiration & Eviction


presented by Mircea
10 minutes

Interlude - What is expiration? What is eviction?


Topics covered include:
API
Configuration
Use cases
Available eviction mechanisms

Demo
Use Case: Have ticket allocations freed up after a period of time*
Add expiration to allocateTicket(), so you end up with

tickets.put(allocation.getId(), allocation, 10, TimeUnit.SECONDS);

Run the demo, and you can see that entries disappear after 10s
Checkpoint 3

JBoss Community Documentation

Page 59 of 617

Infinispan 6.0

6. Listeners
presented by Mircea
10 minutes
Use case: Prevent known ticket touts from using the system
First, copy in the AbuseListener in
Now, we need to register it
Add

@Inject
public void registerAbuseListener(@New AbuseListener abuseListener) {
tickets.addListener(abuseListener);
}

to the InfinispanTicketService.
this code simply creates a new abuse listener (injected by CDI with a logger!) and registers it with
Infinispan. It will do it automatically when the InfinispanTicketService is created
Increase expiration to 3 minutes, otherwise the demo will get tiresome!
Checkpoint 4

Interlude. What can you listen to in Infinispan?

Transactions with Infinispan


presented by Mircea
15 minutes

Transactions in action
Use Case: When ticket is booked, need to atomically take payment and book ticket, and rollback if
any errors
The webapp collects all the data from the user to process the booking, and then sends the booking to
the backend using JMS.
JBoss comes with a "test" queue, we'll abuse that so we don't have to configure messaging (not what
we are here to talk about).
Go to the pom.xml and uncomment JMS dependency
Copy the PaymentProcessor into .services
Inject JMS into InfinispanTicketService

JBoss Community Documentation

Page 60 of 617

Infinispan 6.0

@Resource(mappedName="/ConnectionFactory")
private ConnectionFactory cf;
@Resource(mappedName = "queue/test")
private Queue queue;

Implement the bookTicket method

try {
Connection connection = cf.createConnection();
Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
MessageProducer publisher = session.createProducer(queue);
connection.start();
TextMessage message = session.createTextMessage("Book ticket for " + id);
publisher.send(message);
connection.close();
session.close();
} catch (JMSException e) {
throw new RuntimeException(e);
}

This code is in bookTicket.txt in the samples


Run the example, show it in action.
Checkpoint 5a
Use case: Introduce XA transactions
Add to the configuration (Resources.configureCache):

.transaction().transactionMode(TransactionMode.TRANSACTIONAL)
.transaction().transactionManagerLookup(new GenericTransactionManagerLookup())

Replace the injection of the Connection Factory with

@Resource(mappedName="/JmsXA")
private XAConnectionFactory cf;
@Resource(mappedName = "java:jboss/TransactionManager")
private TransactionManager tm;

finally, upgrade the bookTicket method:

JBoss Community Documentation

Page 61 of 617

Infinispan 6.0

try {
XAConnection connection = null;
try {
connection = cf.createXAConnection();
connection.start();
XASession xaSession = connection.createXASession();
Session session = xaSession.getSession();
MessageProducer publisher = session.createProducer(queue);
TextMessage message = session.createTextMessage("Book ticket for " + id);
tm.begin();
tm.getTransaction().enlistResource(xaSession.getXAResource());
//following two ops need to be atomic (XA)
tickets.remove(id);
publisher.send(message);
tm.commit();
} finally {
if (connection != null) connection.close();
}
} catch (Throwable e) {
// ignore - don't do this at home :)
e.printStackTrace();
}

Interlude - Transactions deep dive


Topics discussed include
Transaction types
Locking
Deadlock detection

Break
15 minutes

JBoss Community Documentation

Page 62 of 617

Infinispan 6.0

Distribution
presented by Sanne
15 minutes
Use case: we have so many tickets being allocated we've run out of heap on one machine, so add
some more!
During the break we added support for distribution. Take you through the changes now
Enable distribution mode in Resources

.clustering()
.mode(CacheMode.DIST_SYNC)
.l1().disable()

Make JGroups use the loopback interface to avoid network problems! Add

@Produces @ApplicationScoped
public EmbeddedCacheManager configureCacheManager() {
return new DefaultCacheManager(
GlobalConfigurationBuilder.defaultClusteredBuilder()
.transport()
.addProperty("configurationFile", "jgroups.xml")
.build());
}

Add jgroups.xml from src/sample to src/main/resources (directory needs creating)


Explain that this JGroups file is exactly as normal for UDP, except that the jgroups.bind_addr is
set to the loopback interface

Interlude - JBoss AS 7
Topics discussed include:
Introduce AS7
Cover domain mode vs standalone
Domain mode a great way to stand up a cluster of nodes!
Explain management options (CLI, web, maven plugin, XML, filesystem)
Talk about Infinispan as managed service in AS7 vs embedded - we could have used either, but to
get started quickly it's easy to embed!
Show 5 servers configured in $JBOSS_HOME/domain/configuration/host.xml - explain about
port bindings. If you are following along, add only these servers

JBoss Community Documentation

Page 63 of 617

Infinispan 6.0

$JBOSS_HOME/domain/configuration/host.xml
<servers>
<server name="server-one" group="main-server-group">
<!-- server-one inherits the default socket-group declared in the server-group -->
</server>
<server name="server-two" group="main-server-group" auto-start="true">
<!-- server-two avoids port conflicts by incrementing the ports in
the default socket-group declared in the server-group -->
<socket-binding-group ref="standard-sockets" port-offset="100"/>
</server>
<server name="server-three" group="main-server-group" auto-start="true">
<!-- server-two avoids port conflicts by incrementing the ports in
the default socket-group declared in the server-group -->
<socket-binding-group ref="standard-sockets" port-offset="200"/>
</server>
<server name="server-four" group="main-server-group" auto-start="true">
<!-- server-two avoids port conflicts by incrementing the ports in
the default socket-group declared in the server-group -->
<socket-binding-group ref="standard-sockets" port-offset="300"/>
</server>
<server name="server-five" group="rest-server-group" auto-start="true">
<!-- server-two avoids port conflicts by incrementing the ports in
the default socket-group declared in the server-group -->
<socket-binding-group ref="standard-sockets" port-offset="1000"/>
</server>
</servers>

Now, define the server groups. We'll also add server group for the REST interface which we'll see in a
minute:
$JBOSS_HOME/domain/configuration/domain.xml
<server-groups>
<server-group name="main-server-group" profile="default">
<jvm name="default">
<heap size="64m" max-size="512m"/>
<permgen size="128m"/>
</jvm>
<socket-binding-group ref="standard-sockets"/>
</server-group>
<server-group name="rest-server-group" profile="default">
<jvm name="default">
<heap size="64m" max-size="512m"/>
<permgen size="128m"/>
</jvm>
<socket-binding-group ref="standard-sockets"/>
</server-group>
</server-groups>

JBoss Community Documentation

Page 64 of 617

Infinispan 6.0

Note that nodes don't get much memory by default, we need to increase it

Show the cache running in distributed mode


Start up 4 JBoss AS 7 nodes with domain.sh. Why? See the JBoss 7 Getting Started guide
Build latest using mvn package and in another terminal change into the project and bring up JBoss
AS CLI $JBOSS_HOME/bin/jboss-admin.sh --connect
Deploy app from console using deploy target/lab1.war
--server-groups=main-server-group
App now deployed to each node
bring up all 4 nodes in a web browser (port offset 100)
show each node starting in the console log
the contents list now just shows whats locally in the cache
explain that as each node comes up, the entries are rehashed to distribute the contents, so we see
entries disappear from a node
show that we can still find any entry, it's just not local any more
show that we can put an entry, and then find it in one of the caches in Infinispan (10 mins)

Interlude - What modes can Infinispan run in? When would you want to use them?
Topics discussed include:
What are the different modes?
When would you use the modes?
How does distribution work?
Explain CH, benefits and problems
Talk about vnodes to even distribution

JBoss Community Documentation

Page 65 of 617

Infinispan 6.0

L1 cache
presented by Sanne
5 minutes
Explain benefits (TODO)
Start up 4 JBoss AS 7 nodes with $JBOSS_HOME/bin/domain.sh
Build latest using mvn package and in another terminal change into the project and bring up JBoss
AS CLI jboss-admin.sh --connect
Deploy app from console using deploy target/lab1.war
--server-groups=main-server-group
App now deployed to each node
bring up all 4 nodes in a web browser (port offset 100)
Just like before, except that nodes 1 & 2 are still showing all entries locally (they kept them in their
cache)
Find a node that doesn't have all entries, and query for an entry that isn't on that node. Then hit
refresh. Show that this time it's now local (L1 cache)
Show the same for putting a new entry - keep adding until you get one that isn't owned by the current
node - show that it is in the local node still.
Checkpoint 6

JBoss Community Documentation

Page 66 of 617

Infinispan 6.0

Client Server Modes


presented by Mircea
10 minutes
We have a server group set up in JBoss AS 7 that contains a single server. We'll use this for the rest
server - no need to have one on each node!
Enter jboss admin console and connect to the local server: $JBOSS_HOME/bin/jboss-admin.sh. The
type "connect".
Deploy infinispan-server-rest.war from the lab to JBoss AS 7 using the JBoss AS 7 CLI
deploy <path/to/>infinispan-server-rest.war
--server-groups=rest-server-group
REST server actually joins the Infinispan cluster as a node, and it needs to know which caches to
use, so we added this to the war, and we also needed to add the domain class* * * Visit a couple of
the UIs to seed data and start caches
check that connection REST is correctly deployed: http://localhost:8080/infinispan-server-rest/
Use a rest client to GET
http://localhost:9080/infinispan-server-rest/rest/ticketAllocationCache/manik-Best%20of%20Abba

Interlude - what client-server modes does Infinispan offer?


Topics discussed include:
various server endpoints
benefits of Hot Rod

CacheStores
presented by Mircea
10 minutes
Use case: Persist your data to disk in case of node restart
paste the JDBC cache config method from src/sample/java/jdbc.txt
Walk through the JDBC cache store set up code
Add this to the configuration:

JBoss Community Documentation

Page 67 of 617

Infinispan 6.0

.loaders()
.shared(true)
.addCacheLoader()
.cacheLoader(new JdbcStringBasedCacheStore())
.addProperty("connectionFactoryClass",
"org.infinispan.loaders.jdbc.connectionfactory.ManagedConnectionFactory")
.addProperty("datasourceJndiLocation", "java:jboss/datasources/ExampleDS")
.addProperty("idColumnType", "VARCHAR(255)")
.addProperty("idColumnName", "ID_COLUMN")
.addProperty("dataColumnType", "BINARY")
.addProperty("dataColumnName", "DATA_COLUMN")
.addProperty("timestampColumnName", "TIMESTAMP_COLUMN")
.addProperty("timestampColumnType", "BIGINT")
.addProperty("stringsTableNamePrefix", "persistentStore")
.addProperty("userName", "sa")
.addProperty("password", "sa")
.async().threadPoolSize(10)

Run mvn clean package


Deploy the app using deploy lab1/target/lab1.war
--server-groups=main-server-group
Explain we are using the JBoss AS 7 built in example data source for H2 - configuration found in
domain.xml.
Vist a node or two to setup some caches and data
Explain we are using the h2console.war. Needed a couple of changes to make it run, documentation
coming soon
Deploy it using deploy h2console.war --server-groups=main-server-group - each node
in the cluster owns some data, each h2 database will back that up
Visit http://localhost:9080/h2console/
Log in sa with password sa
execute select * from persistentstore_ticketallocationcache
Checkpoint 7

Interlude - What Cache Stores are available? In what scenarios can they be used?
Topics discussed include:
Modes of cache store usage
CacheStores available as built in

JBoss Community Documentation

Page 68 of 617

Infinispan 6.0

Bonus topics
Querying Infinispan
presented by Sanne
8 minutes
Topics discussed include:
TODO

Hibernate OGM
presented by Sanne
2 minutes
Topics discussed include:
TODO

Reduce
presented by Pete
5 minutes
Topics discussed include:
TODO

Benchmarking data girds - Radargun


Introducing project Radargun
presented by Mircea
5 minutes

Conclusion
presented by Pete
10 minutes

JBoss Community Documentation

Page 69 of 617

Infinispan 6.0

3 User Guide
1. What is Infinispan, and why would you use it?
1. [Project Roadmap]
2. [Public Articles on Infinispan]
3. Cheat Sheet on using Infinispan, for Developers
2. Configuring and creating a cache
1. Programmatically
2. Declaratively
3. Configuration migration tools
4. Clustered Configuration QuickStart
3. Using the Cache API
1. Storing and retrieving data
2. Listeners and Notifications
3. The Asynchronous API
4. Using per-invocation flags
5. The Grouping API
4. Eviction
1. Configuring eviction and the eviction thread
2. Expiration
3. Examples
5. Cache Loaders
1. Configuring cache loaders
2. Passivation
3. Cache loaders shipped with Infinispan
4. Write-Through And Write-Behind Caching
5. Cache loaders and transactional caches
6. JTA transactions
1. Configuring your cache to work with JTA
2. Deadlock detection
3. Batching API
4. Recovery
7. Locking and concurrency
1. Data Versioning
2. MVCC: Infinispan's concurrency model
3. Tuning concurrency level and lock striping
4. Explicit locking and the lock() methods
8. Clustering modes
1. Replication and invalidation
2. Distribution
1. L1 caching
2. Generating keys mapped to specific cluster nodes
3. Asynchronous options
9. Non-clustered, LOCAL mode

JBoss Community Documentation

Page 70 of 617

Infinispan 6.0
10. Marshalling
1. Lazy deserialization (storeAsBinary)
11. CDI Support
12. Management tooling
1. JMX
2. RHQ
3. Writing plugins for other management tools
13. The REST server
1. Accessing data in Infinispan via RESTful interface
14. Infinispan as a Directory for Lucene
15. Running Infinispan on Amazon Web Services
16. Querying Infinispan
1. [SQL-like querying of Infinispan]
17. Writing custom interceptors
18. Using Tree API module
19. Infinispan and Grails
20. Configuration reference
1. Default values for property based configuration attributes
21. JMX attributes and operations
22. API docs (Javadocs)
23. Infinispan command-line console
24. Infinispan for HTTP session clustering and caching

3.1 New in Infinispan 4.1.0


1. Grid File System using on Infinispan
2. Server modules
1. Hot Rod
1. Protocol specification (version 1)
2. Using the Hot Rod server module
3. Java Hot Rod client
4. Consistent concurrent updates with Hot Rod versioned operations
5. Multiple layers of caches
6. Interacting With Hot Rod Server From Within Same JVM
2. Memcached
1. Using Infinispan Memcached server
1. Talking to Memcached from non-Java clients
3. WebSocket
1. Infinispan Websocket server
4. Load testing server modules
5. Command line options
3. Key affinity service
4. Configuration Reference
5. JMX attributes and operations
6. API docs (javadocs)

JBoss Community Documentation

Page 71 of 617

Infinispan 6.0

3.2 New in Infinispan 4.2.0


1. Distribution
1. Server Hinting
2. Starting a new project with Infinispan - check out Infinispan Maven Archetypes
3. Configuration Reference
4. JMX attributes and operations
5. API docs (javadocs)

3.3 New in Infinispan 5.0.0


1. Generating keys mapped to specific cluster nodes
2. Portable Serialization for Hot Rod with Apache Avro
3. Plugging Infinispan with user defined Externalizers
4. Distributed Executors Framework
5. MapReduce Framework
6. Fluent Programmatic Configuration
7. Configuration Reference
8. JMX attributes and operations
9. API docs (javadocs)

3.4 New in Infinispan 5.2.0


1. Cross-site replication
2. Rolling upgrades
3. Command-Line Interface (CLI)

3.5 Integration with other frameworks


1. Using Infinispan as JPA/Hibernate Second Level Cache Provider
1. Standalone JTA for JPA/Hibernate using Infinispan as 2LC
2. Infinispan as Hibernate 2nd-Level Cache in JBoss AS 5.x
2. Using Infinispan in JBoss Application Server 6
3. Using Infinispan as Spring Cache provider

JBoss Community Documentation

Page 72 of 617

Infinispan 6.0

3.6 Querying Infinispan


The infinispan-query module
Configuration
Simple example
Notable differences with Hibernate Search
Requirements for the Key: @Transformable and @ProvidedId
Registering a Transformer via annotations
Registering a Transformer programmatically
@ProvidedId
Configuration
Configuration via XML
Lucene Directory
Using programmatic configuration and index mapping
Cache modes and managing indexes
LOCAL
REPLICATION
DISTRIBUTION
INVALIDATION
Sharing the Index
Clustering the Index in Infinispan
Rebuilding the Index

3.6.1 The infinispan-query module


This module adds querying capabilities to Infinispan. It uses Hibernate Search and Apache Lucene to index
and search objects in the cache. It allows users to obtain objects within the cache without needing to know
the keys to each object that they want to obtain, so you can search your objects basing on some of it's
properties, for example to retrieve all red cars (exact metadata match), or all books about a specific topic (full
text search and relevance scoring).

Configuration
Indexing must be enabled in the configuration (as explained in XML Configuration or Programmatic
configuration).
This will trigger automatic indexing of objects stored in the cache; there are several different ways to specify
how these objects need to be indexed explained in the following paragraphs.
To run queries you use the SearchManager which exposes all necessary methods to get started.

JBoss Community Documentation

Page 73 of 617

Infinispan 6.0

3.6.2 Simple example


We're going to store Book instances in Infinispan; each Book will be defined as in the following example; we
have to choose which properties are indexed, and for each property we can optionally choose advanced
indexing options using the annotations defined in the Hibernate Search project.

// example values stored in the cache and indexed:


import org.hibernate.search.annotations.*;
//Values you want to index need to be annotated with @Indexed, then you pick which fields and
how they are to be indexed:
@Indexed
public class Book {
@Field String title;
@Field String description;
@Field @DateBridge(resolution=Resolution.YEAR) Date publicationYear;
@IndexedEmbedded Set<Author> authors = new HashSet<Author>();
}
public class Author {
@Field String name;
@Field String surname;
// hashCode() and equals() omitted
}

Now assuming we stored several Book instances in our Infinispan Cache, we can search them for any
matching field as in the following example.

// get the search manager from the cache:


SearchManager searchManager = org.infinispan.query.Search.getSearchManager(cache);
// create any standard Lucene query, via Lucene's QueryParser or any other means:
org.apache.lucene.search.Query fullTextQuery = //any Apache Lucene Query
// convert the Lucene query to a CacheQuery:
CacheQuery cacheQuery = searchManager.getQuery( fullTextQuery );
// get the results:
List<Object> found = cacheQuery.list();

A Lucene Query is often created by parsing a query in text format such as "title:infinispan AND
authors.name:sanne", or by using the query builder provided by Hibernate Search.

JBoss Community Documentation

Page 74 of 617

Infinispan 6.0

// get the search manager from the cache:


SearchManager searchManager = org.infinispan.query.Search.getSearchManager( cache );
// you could make the queries via Lucene APIs, or use some helpers:
QueryBuilder queryBuilder = searchManager.buildQueryBuilderForClass(Book.class).get();
// the queryBuilder has a nice fluent API which guides you through all options.
// this has some knowledge about your object, for example which Analyzers
// need to be applied, but the output is a failry standard Lucene Query.
org.apache.lucene.search.Query luceneQuery = queryBuilder.phrase()
.onField("description")
.andField("title")
.sentence("a book on highly scalable query engines")
.createQuery();
// the query API itself accepts any Lucene Query, and on top of that
// you can restrict the result to selected class types:
CacheQuery query = searchManager.getQuery(luceneQuery, Book.class);
// and there are your results!
List objectList = query.list();
for (Object book : objectList) {
System.out.println(book);
}

A part from list() you have the option for streaming results, or use pagination.
This barely scratches the surface of all what is possible to do: see the Hibernate Search reference
documentation to learn about sorting, numeric fields, declarative filters, caching filters, complex object graph
indexing, custom types and the powerful faceting search API.

Notable differences with Hibernate Search


Using @DocumentId to mark a field as identifier does not apply to Infinispan values; in Infinispan Query the
identifier for all @Indexed objects is the key used to store the value. You can still customize how the key is
indexed using a combination of @Transformable, @ProvidedId, custom types and custom FieldBridge
implementations.

JBoss Community Documentation

Page 75 of 617

Infinispan 6.0

Requirements for the Key: @Transformable and @ProvidedId


The key for each value needs to be indexed as well, and the key instance must be transformed in a String.
Infinispan includes some default transformation routines to encode common primitivies, but to use a custom
key you must provide an implementation of org.infinispan.query.Transformer.

Registering a Transformer via annotations


You can annotate your key type with org.infinispan.query.Transformable:

@Transformable(transformer = CustomTransformer.class)
public class CustomKey {
...
}
public class CustomTransformer implements Transformer {
@Override
public Object fromString(String s) {
...
return new CustomKey(...);
}
@Override
public String toString(Object customType) {
CustomKey ck = (CustomKey) customType;
return ...
}
}

Registering a Transformer programmatically


Using this technique, you don't have to annotated your custom key type:

org.infinispan.query.SearchManager.registerKeyTransformer(Class<?>, Class<? extends


Transformer>)

@ProvidedId
The org.hibernate.search.annotations.ProvidedId annotation lets you apply advanced indexing options to the
key field: the field name to be used, and/or specify a custom FieldBridge.

JBoss Community Documentation

Page 76 of 617

Infinispan 6.0

3.6.3 Configuration
Configuration via XML
To enable indexing via XML, you need to add the <indexing ... /> element to your cache configuration, and
optionally pass additional properties to the embedded Hibernate Search engine:

<?xml version="1.0" encoding="UTF-8"?>


<infinispan
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="urn:infinispan:config:5.2
http://www.infinispan.org/schemas/infinispan-config-5.2.xsd"
xmlns="urn:infinispan:config:5.2">
<default>
<indexing enabled="true" indexLocalOnly="true">
<properties>
<property name="default.directory_provider" value="ram" />
</properties>
</indexing>
</default>
</infinispan>

In this example the index is stored in memory, so when this nodes is shutdown the index is lost: good for a
quick demo, but in real world cases you'll want to use the default (store on filesystem) or store the index in
Infinispan as well. For the complete reference of properties to define, refer to the Hibernate Search
documentation.

Lucene Directory
Infinispan Query isn't aware of where you store the indexes, it just passes the configuration of which Lucene
Directory implementation you want to use to the Hibernate Search engine. There are several Lucene
Directory implementations bundled, and you can plug your own or add third party implementations: the
Directory is the IO API for Lucene to store the indexes.
The most common Lucene Directory implementations used with Infinispan Query are:
Ram - stores the index in a local map to the node. This index can't be shared.
Filesystem - stores the index in a locally mounted filesystem. This could be a network shared FS, but
sharing this way is generally not recommended.
Infinispan - stores the index in a different dedicated Infinispan cache. This cache can be configured as
replicated or distributed, to share the index among nodes. See also Infinispan as a storage for Lucene
indexes.
Of course having a shared index vs. an independent index on each node directly affects behaviour of the
Query module; some combinations might not make much sense.

JBoss Community Documentation

Page 77 of 617

Infinispan 6.0

Using programmatic configuration and index mapping


In the following example we start Infinispan programmatically, avoiding XML configuration files, and also
map an object Author which is to be stored in the grid and made searchable on two properties but without
annotating the class.

SearchMapping mapping = new SearchMapping();


mapping.entity(Author.class).indexed().providedId()
.property("name", ElementType.METHOD).field()
.property("surname", ElementType.METHOD).field();
Properties properties = new Properties();
properties.put(org.hibernate.search.Environment.MODEL_MAPPING, mapping);
properties.put("hibernate.search.[other options]", "[...]");
Configuration infinispanConfiguration = new ConfigurationBuilder()
.indexing()
.enable()
.indexLocalOnly(true)
.withProperties(properties)
.build();
DefaultCacheManager cacheManager = new DefaultCacheManager(infinispanConfiguration);
Cache<Long, Author> cache = cacheManager.getCache();
SearchManager sm = Search.getSearchManager(cache);
Author author = new Author(1, "Manik", "Surtani");
cache.put(author.getId(), author);
QueryBuilder qb = sm.buildQueryBuilderForClass(Author.class).get();
Query q = qb.keyword().onField("name").matching("Manik").createQuery();
CacheQuery cq = sm.getQuery(q, Author.class);
Assert.assertEquals(cq.getResultSize(), 1);

3.6.4 Cache modes and managing indexes


Index management is currently controlled by the Configuration.setIndexLocalOnly() setter, or the <indexing
indexLocalOnly="true" /> XML element. If you set this to true, only modifications made locally on each node
are considered in indexing. Otherwise, remote changes are considered too.
Regarding actually configuring a Lucene directory, refer to the Hibernate Search documentation on how to
pass in the appropriate Lucene configuration via the Properties object passed to QueryHelper.

LOCAL
In local mode, you may use any Lucene Directory implementation. Also the option indexLocalOnly isn't
meaningful.

JBoss Community Documentation

Page 78 of 617

Infinispan 6.0

REPLICATION
In replication mode, each node can have it's own local copy of the index. So indexes can either be stored
locally on each node (RAMDirectory, FSDirectory, etc) but you need to set indexLocalOnly to false , so that
each node will apply needed updates it receives from other nodes in addition to the updates started locally.
Any Directory implementation can be used, but you have to make sure that when a new node is started it
receives an up to date copy of the index; typically rsync is well suited for this task, but being an external
operation you might end up with a slightly out-of-sync index, especially if updates are very frequent.
Alternately, if you use some form of shared storage for indexes (see Sharing the Index ), you then have to
set indexLocalOnly to true so that each node will apply only the changes originated locally; in this case
there's no risk in having an out-of-sync index, but to avoid write contention on the index you should make
sure that a single node is "in charge" of updating the index. Again, the Hibernate Search reference
documentation describes means to use a JMS queue or JGroups to send indexing tasks to a master node.
The diagram below shows a replicated deployment, in which each node has a local index.

JBoss Community Documentation

Page 79 of 617

Infinispan 6.0

DISTRIBUTION
For these 2 cache modes, you need to use a shared index and set indexLocalOnly to true.
The diagram below shows a deployment with a shared index. Note that while not mandatory, a shared index
can be used for replicated (vs. distributed) caches as well.

INVALIDATION
Indexing or searching of elements under INVALIDATION mode is not supported.

3.6.5 Sharing the Index


The most simple way to share an index is to use some form of shared storage for the indexes, like an
FSDirectory on a shared disk; however this form is problematic as the FSDirectory relies on specific locking
semantics which are often incompletely implemented on network filesystems, or not reliable enough; if you
go for this approach make sure to search for potential problems on the Lucene mailing lists for other
experiences and workarounds. Good luck, test well.
There are many alternative Directory implementations you can find, one of the most suited approaches when
working with Infinispan is of course to store the index in an Infinispan cache: have a look at the
InfinispanDirectoryProvider, as all Infinispan based layers it can be combined with persistent CacheLoaders
to keep the index on a shared filesystem without the locking issues, or alternatively in a database, cloud
storage, or any other CacheLoader implementation; you could backup the index in the same store used to
backup your values.
For full documentation on clustering the Lucene engine, refer to the Hibernate Search documentation to
properly configure it clustered.

JBoss Community Documentation

Page 80 of 617

Infinispan 6.0

3.6.6 Clustering the Index in Infinispan


Again the configuration details are in the Hibernate Search reference, in particular in the
infinispan-directories section. This backend will by default start a secondary Infinispan CacheManager, and
optionally take another Infinispan configuration file: don't reuse the same configuration or you will start grids
recursively!
It is currently not possible to share the same CacheManager.

3.6.7 Rebuilding the Index


Occasionally you might need to rebuild the Lucene index by reconstructing it from the data stored in the
Cache. You need to rebuild the index if you change the definition of what is indexed on your types, or if you
change for example some Analyzer parameter, as Analyzers affect how the index is defined. Also, you might
need to rebuild the index if you had it destroyed by some system administration mistake.
To rebuild the index just get a reference to the MassIndexer and start it; beware if might take some time as it
needs to reprocess all data in the grid!

SearchManager searchManager = Search.getSearchManager(cache);


searchManager.getMassIndexer().start();

This is also available as a JMX operation.

There is currently one limitation: the MassIndexer is implemented using Map/Reduce, which in
Infinispan 5.2 requires the underlying caches to use distribution. In other words, the MassIndexer
isn't currently functional in LOCAL and REPL cache modes.

3.7 Configuring cache programmatically


Programmatic Configuration
ConfigurationBuilder Programmatic Configuration API
Advanced programmatic configuration

3.7.1 Programmatic Configuration


Programmatic Infinispan configuration is centered around CacheManager and ConfigurationBuilder API.
Although every single aspect of Infinispan configuration could be set programmatically, the most usual
approach is to create a starting point in a form of XML configuration file and then in runtime, if needed,
programmatically tune a specific configuration to suit the use case best.

JBoss Community Documentation

Page 81 of 617

Infinispan 6.0

EmbeddedCacheManager manager = new DefaultCacheManager("my-config-file.xml");


Cache defaultCache = manager.getCache();

Let assume that a new synchronously replicated cache is to be configured programmatically. First, a fresh
instance of Configuration object is created using ConfigurationBuilder helper object, and the cache mode is
set to synchronous replication. Finally, the configuration is defined/registered with a manager.

Configuration c = new
ConfigurationBuilder().clustering().cacheMode(CacheMode.REPL_SYNC).build();
String newCacheName = "repl";
manager.defineConfiguration(newCacheName, c);
Cache<String, String> cache = manager.getCache(newCacheName);

The default cache configuration (or any other cache configuration) can be used as a starting point for
creation of a new cache. For example, lets say that infinispan-config-file.xml specifies a replicated
cache as a default and that a distributed cache is desired with a specific L1 lifespan while at the same time
retaining all other aspects of a default cache. Therefore, the starting point would be to read an instance of a
default Configuration object and use ConfigurationBuilder to construct and modify cache mode and L1
lifespan on a new Configuration object. As a final step the configuration is defined/registered with a
manager.

EmbeddedCacheManager manager = new DefaultCacheManager("infinispan-config-file.xml");


Configuration dcc = cacheManager.getDefaultCacheConfiguration();
Configuration c = new
ConfigurationBuilder().read(dcc).clustering().cacheMode(CacheMode.DIST_SYNC).l1().lifespan(60000L).build(); St
newCacheName = "distributedWithL1";
manager.defineConfiguration(newCacheName, c);
Cache<String, String> cache = manager.getCache(newCacheName);

As long as the based configuration is the default named cache, the previous code works perfectly fine.
However, other times the base configuration might be another named cache. So, how can new
configurations be defined based on other defined caches? Take the previous example and imagine that
instead of taking the default cache as base, a named cache called "replicatedCache" is used as base. The
code would look something like this:

EmbeddedCacheManager manager = new DefaultCacheManager("infinispan-config-file.xml");


Configuration rc = cacheManager.getCacheConfiguration("replicatedCache");
Configuration c = new
ConfigurationBuilder().read(rc).clustering().cacheMode(CacheMode.DIST_SYNC).l1().lifespan(60000L).build(); Str
newCacheName = "distributedWithL1";
manager.defineConfiguration(newCacheName, c);
Cache<String, String> cache = manager.getCache(newCacheName);

Refer to CacheManager, ConfigurationBuilder, Configuration, and GlobalConfiguration javadocs for more


details.

JBoss Community Documentation

Page 82 of 617

Infinispan 6.0

3.7.2 ConfigurationBuilder Programmatic Configuration API


However, users do not have to first read an XML based configuration and then modify it in runtime; they can
start from scratch using only programmatic API. This is where powerful ConfigurationBuilder API comes to
shine. The aim of this API is to make it easier to chain coding of configuration options in order to speed up
the coding itself and make the configuration more readable. This new configuration can be used for both the
global and the cache level configuration. GlobalConfiguration objects are constructed using
GlobalConfigurationBuilder while Configuration objects are built using ConfigurationBuilder. Let's look at
some examples on configuring both global and cache level options with this new API:
One of the most commonly configured global option is the transport layer, where you indicate how an
Infinispan node will discover the others:

GlobalConfiguration globalConfig = new GlobalConfigurationBuilder().transport()


.clusterName("qa-cluster")
.addProperty("configurationFile", "jgroups-tcp.xml")
.machineId("qa-machine").rackId("qa-rack")
.build();

Sometimes you might also want to get global JMX statistics and information about the transport, or the
cache manager in general. To enable global JMX statistics simply do:

GlobalConfiguration globalConfig = new GlobalConfigurationBuilder()


.globalJmxStatistics()
.build();

Further options at the global JMX statistics level allows you for example to configure the cache manager
name which comes handy when you have multiple cache managers running on the same system, or how to
locate the JMX MBean Server:

GlobalConfiguration globalConfig = new GlobalConfigurationBuilder()


.globalJmxStatistics()
.cacheManagerName("SalesCacheManager")
.mBeanServerLookupClass(JBossMBeanServerLookup.class)
.build();

Some of the Infinispan features are powered by a group of the thread pool executors which can also be
tweaked at this global level. For example:

GlobalConfiguration globalConfig = new GlobalConfigurationBuilder()


.replicationQueueScheduledExecutor()
.factory(DefaultScheduledExecutorFactory.class)
.addProperty("threadNamePrefix", "RQThread")
.build();

JBoss Community Documentation

Page 83 of 617

Infinispan 6.0
You can not only configure global, cache manager level, options, but you can also configure cache level
options such as the cluster mode:

Configuration config = new ConfigurationBuilder()


.clustering()
.cacheMode(CacheMode.DIST_SYNC)
.sync()
.l1().lifespan(25000L)
.hash().numOwners(3)
.build();

Or you can configure eviction/expiration settings to:

Configuration config = new ConfigurationBuilder()


.eviction()
.maxEntries(20000).strategy(EvictionStrategy.LIRS).expiration()
.wakeUpInterval(5000L)
.maxIdle(120000L)
.build();

An application might also want to interact with an Infinispan cache within the boundaries of JTA and to do
that you need to configure the transaction layer and optionally tweak the locking settings. When interacting
with transactional caches, you might want to enable recovery to deal with transactions that finished with an
heuristic outcome and if you do that, you will often want to enable JMX management and statistics gathering
too:

Configuration config = new ConfigurationBuilder()


.locking()
.concurrencyLevel(10000).isolationLevel(IsolationLevel.REPEATABLE_READ)
.lockAcquisitionTimeout(12000L).useLockStriping(false).writeSkewCheck(true)
.transaction()
.recovery()
.transactionManagerLookup(new GenericTransactionManagerLookup())
.jmxStatistics()
.build();

Configuring Infinispan with one or several chained persistent stores is simple too:

Configuration config = new ConfigurationBuilder()


.loaders()
.shared(false).passivation(false).preload(false)
.addFileCacheStore().location("/tmp").streamBufferSize(1800).async().enable().threadPoolSize(20).build();

JBoss Community Documentation

Page 84 of 617

Infinispan 6.0

Advanced programmatic configuration


The fluent configuration can also be used to configure more advanced or exotic options, such as advanced
externalizers:

GlobalConfiguration globalConfig = new GlobalConfigurationBuilder()


.serialization()
.addAdvancedExternalizer(PersonExternalizer.class)
.addAdvancedExternalizer(999, AddressExternalizer.class)
.build();

Or, add custom interceptors:

Configuration config = new ConfigurationBuilder()


.customInterceptors().interceptors()
.add(new FirstInterceptor()).first()
.add(new LastInterceptor()).last()
.add(new FixPositionInterceptor()).atIndex(8)
.add(new AfterInterceptor()).after(LockingInterceptor.class)
.add(new BeforeInterceptor()).before(CallInterceptor.class)
.build();

For information on the individual configuration options, please check the configuration guide.

3.8 Grid File System


Infinispan's GridFileSystem is a new, experimental API that exposes an Infinispan-backed data grid as a file
system. This API is available in Infinispan 4.1.0 (from 4.1.0.ALPHA2 onwards).
Specifically, the API works as an extension to the JDK's File, InputStream and OutputStream classes:
specifically, GridFile, GridInputStream and GridOutputStream. A helper class, GridFilesystem, is also
included.
Essentially, the GridFilesystem is backed by 2 Infinispan caches - one for metadata (typically replicated)
and one for the actual data (typically distributed). The former is replicated so that each node has metadata
information locally and would not need to make RPC calls to list files, etc. The latter is distributed since this
is where the bulk of storage space is used up, and a scalable mechanism is needed here. Files themselves
are chunked and each chunk is stored as a cache entry, as a byte array.
Here is a quick code snippet demonstrating usage:

JBoss Community Documentation

Page 85 of 617

Infinispan 6.0

Cache<String,byte[]> data = cacheManager.getCache("distributed");


Cache<String,GridFile.Metadata> metadata = cacheManager.getCache("replicated");
GridFilesystem fs = new GridFilesystem(data, metadata);
// Create directories
File file=fs.getFile("/tmp/testfile/stuff");
fs.mkdirs(); // creates directories /tmp/testfile/stuff
// List all files and directories under "/usr/local"
file=fs.getFile("/usr/local");
File[] files=file.listFiles();
// Create a new file
file=fs.getFile("/tmp/testfile/stuff/README.txt");
file.createNewFile();

Copying stuff to the grid file system:

InputStream in=new FileInputStream("/tmp/my-movies/dvd-image.iso");


OutputStream out=fs.getOutput("/grid-movies/dvd-image.iso");
byte[] buffer=new byte[20000];
int len;
while((len=in.read(buffer, 0, buffer.length)) != -1) out.write(buffer, 0, len);
in.close();
out.close();

Reading stuff from the grid:

InputStream in=in.getInput("/grid-movies/dvd-image.iso");
OutputStream out=new FileOutputStream("/tmp/my-movies/dvd-image.iso");
byte[] buffer=new byte[200000];
int len;
while((len=in.read(buffer, 0, buffer.length)) != -1) out.write(buffer, 0, len);
in.close();
out.close();

3.8.1 WebDAV demo


Infinispan 4.1.0 also ships with a demo WebDAV application that makes use of the grid file system APIs.
This demo app is packaged as a WAR file which can be deployed in a servlet container, such as JBoss AS
or Tomcat, and exposes the grid as a file system over WebDAV. This could then be mounted as a remote
drive on your operating system.
Here is a short video clip showcasing this demo:

JBoss Community Documentation

Page 86 of 617

Infinispan 6.0

3.9 Asynchronous API


In addition to synchronous API methods like Cache.put(), Cache.remove(), etc., Infinispan also has an
asynchronous, non-blocking API where you can achieve the same results in a non-blocking fashion.
These methods are named in a similar fashion to their blocking counterparts, with "Async" appended. E.g.,
Cache.putAsync(), Cache.removeAsync(), etc. These asynchronous counterparts return a Future containing
the actual result of the operation.
For example, in a cache paramerized as Cache<String, String>, Cache.put(String key, String value) returns
a String. Cache.putAsync(String key, String value) would return a Future<String>.

3.9.1 Why use such an API?


Non-blocking APIs are powerful in that they provide all of the guarantees of synchronous communications with the ability to handle communication failures and exceptions - with the ease of not having to block until a
call completes. This allows you to better harness parallelism in your system. For example:

Set<Future<?>> futures = new HashSet<Future<?>>();


futures.add(cache.putAsync(key1, value1)); // does not block
futures.add(cache.putAsync(key2, value2)); // does not block
futures.add(cache.putAsync(key3, value3)); // does not block
//
//
//
//

the remote calls for the 3 puts will effectively be executed


in parallel, particularly useful if running in distributed mode
and the 3 keys would typically be pushed to 3 different nodes
in the cluster

// check that the puts completed successfully


for (Future<?> f: futures) f.get();

3.9.2 Which processes actually happen asynchronously?


There are 4 things in Infinispan that can be considered to be on the critical path of a typical write operation.
These are, in terms of cost, network calls, marshalling, writing to a cache store (optional), and locking. As of
Infinispan 4.0, using the async methods will take the network calls and marshalling off the critical path. For
various technical reasons, writing to a cache store and acquiring locks, however, still happens in the caller's
thread. In future, we plan to take these offline as well. See this developer mail list thread about this topic.

JBoss Community Documentation

Page 87 of 617

Infinispan 6.0

3.9.3 Notifying futures


Strictly, these methods do not return JDK Futures, but rather a sub-interface known as a NotifyingFuture.
The main difference is that you can attach a listener to a NotifyingFuture such that you could be notified
when the future completes. Here is an example of making use of a notifying future:

FutureListener futureListener = new FutureListener() {


public void futureDone(Future future) {
try {
future.get();
} catch (Exception e) {
// Future did not complete successfully
System.out.println("Help!");
}
}
};
cache.putAsync("key", "value").attachListener(futureListener);

3.9.4 Further reading


The Javadocs on the Cache interface has some examples on using the asynchronous API, as does this
article by Manik Surtani introducing the API.

3.10 Tree API Module


Introduction
What is Tree API about?
Using Tree API
Dependencies
Creating a Tree Cache
Manipulating data in a Tree Cache
Common Operations
Locking In Tree API
Listeners for tree cache events

JBoss Community Documentation

Page 88 of 617

Infinispan 6.0

3.10.1 Introduction
Infinispan's tree API module offers clients the possibility of storing data using a tree-structure like API. This
API is similar to the one provided by JBoss Cache, hence the tree module is perfect for those users wanting
to migrate their applications from JBoss Cache to Infinispan, who want to limit changes their codebase as
part of the migration. Besides, it's important to understand that Infinispan provides this tree API much more
efficiently than JBoss Cache did, so if you're a user of the tree API in JBoss Cache, you should consider
migrating to Infinispan.

3.10.2 What is Tree API about?


The aim of this API is to store information in a hierarchical way. The hierarchy is defined using paths
represented as Fqn or fully qualified names, for example: /this/is/a/fqn/path or /another/path . In the
hierarchy, there's an special path called root which represents the starting point of all paths and it's
represented as: /
Each FQN path is represented as a node where users can store data using a key/value pair style API (i.e. a
Map). For example, in /persons/john , you could store information belonging to John, for example:
surname=Smith, birthdate=05/02/1980...etc.
Please remember that users should not use root as a place to store data. Instead, users should define their
own paths and store data there. The following sections will delve into the practical aspects of this API.

3.10.3 Using Tree API


Dependencies
For your application to use the tree API, you need to import infinispan-tree.jar which can be located
in the Infinispan binary distributions, or you can simply add a dependency to this module in your pom.xml:

<dependencies>
...
<dependency>
<groupId>org.infinispan</groupId>
<artifactId>infinispan-tree</artifactId>
<version>$put-infinispan-version-here</version>
</dependency>
...
</dependencies>

JBoss Community Documentation

Page 89 of 617

Infinispan 6.0

Creating a Tree Cache


The first step to use the tree API is to actually create a tree cache. To do so, you need to create an
Infinispan Cache as you'd normally do, and using the TreeCacheFactory, create an instance of TreeCache.
A very important note to remember here is that the Cache instance passed to the factory must be configured
with invocation batching. For example:

import org.infinispan.config.Configuration;
import org.infinispan.tree.TreeCacheFactory;
import org.infinispan.tree.TreeCache;
...
Configuration config = new Configuration();
config.setInvocationBatchingEnabled(true);
Cache cache = new DefaultCacheManager(config).getCache();
TreeCache treeCache = TreeCacheFactory.createTreeCache(cache);

Manipulating data in a Tree Cache


The Tree API effectively provides two ways to interact with the data:
1. Via TreeCache convenience methods: These methods are located within the TreeCache interface
and enable users to store, retrieve, move, remove...etc data with a single call that takes the Fqn, in
String or Fqn format, and the data involved in the call. For example:

treeCache.put("/persons/john", "surname", "Smith");

Or:

import org.infinispan.tree.Fqn;
...
Fqn johnFqn = Fqn.fromString("persons/john");
Calendar calendar = Calendar.getInstance();
calendar.set(1980, 5, 2);
treeCache.put(johnFqn, "birthdate", calendar.getTime()));

JBoss Community Documentation

Page 90 of 617

Infinispan 6.0
2. Via Node API: It allows finer control over the individual nodes that form the FQN, allowing
manipulation of nodes relative to a particular node. For example:

import org.infinispan.tree.Node;
...
TreeCache treeCache = ...
Fqn johnFqn = Fqn.fromElements("persons", "john");
Node<String, Object> john = treeCache.getRoot().addChild(johnFqn);
john.put("surname", "Smith");

Or:

Node persons = treeCache.getRoot().addChild(Fqn.fromString("persons"));


Node<String, Object> john = persons.addChild(Fqn.fromString("john"));
john.put("surname", "Smith");

Or even:

Fqn personsFqn = Fqn.fromString("persons");


Fqn johnFqn = Fqn.fromRelative(personsFqn, Fqn.fromString("john"));
Node<String, Object> john = treeCache.getRoot().addChild(johnFqn);
john.put("surname", "Smith");

A node also provides the ability to access its parent or children. For example:

Node<String, Object> john = ...


Node persons = john.getParent();

Or:

Set<Node<String, Object>> personsChildren = persons.getChildren();

JBoss Community Documentation

Page 91 of 617

Infinispan 6.0

Common Operations
In the previous section, some of the most used operations, such as addition and retrieval, have been shown.
However, there are other important operations that are worth mentioning, such as remove:
You can for example remove an entire node, i.e. /persons/john , using:

treeCache.removeNode("/persons/john");

Or remove a child node, i.e. persons that a child of root, via:

treeCache.getRoot().removeChild(Fqn.fromString("persons"));

You can also remove a particular key/value pair in a node:

Node john = treeCache.getRoot().getChild(Fqn.fromElements("persons", "john"));


john.remove("surname");

Or you can remove all data in a node with:

Node john = treeCache.getRoot().getChild(Fqn.fromElements("persons", "john"));


john.clearData();

Another important operation supported by Tree API is the ability to move nodes around in the tree. Imagine
we have a node called "john" which is located under root node. The following example is going to show how
to we can move "john" node to be under "persons" node:
Current tree structure:

/persons
/john

Moving trees from one FQN to another:

Node john = treeCache.getRoot().addChild(Fqn.fromString("john"));


Node persons = treeCache.getRoot().getChild(Fqn.fromString("persons"));
treeCache.move(john.getFqn(), persons.getFqn());

Final tree structure:

/persons/john

JBoss Community Documentation

Page 92 of 617

Infinispan 6.0

3.10.4 Locking In Tree API


Understanding when and how locks are acquired when manipulating the tree structure is important in order
to maximise the performance of any client application interacting against the tree, while at the same time
maintaining consistency.
Locking on the tree API happens on a per node basis. So, if you're putting or updating a key/value under a
particular node, a write lock is acquired for that node. In such case, no write locks are acquired for parent
node of the node being modified, and no locks are acquired for children nodes.
If you're adding or removing a node, the parent is not locked for writing. In JBoss Cache, this behaviour was
configurable with the default being that parent was not locked for insertion or removal.
Finally, when a node is moved, the node that's been moved and any of its children are locked, but also the
target node and the new location of the moved node and its children. To understand this better, let's look at
an example:
Imagine you have a hierarchy like this and we want to move c/ to be underneath b/:

/
--|-/
a
|
b
|
d

\
c
|
e

The end result would be something like this:

/
|
a
|
b
--|-/
d

\
c
|
e

To make this move, locks would have been acquired on:


/a/b - because it's the parent underneath which the data will be put
/c and /c/e - because they're the nodes that are being moved
/a/b/c and /a/b/c/e - because that's new target location for the nodes being moved

JBoss Community Documentation

Page 93 of 617

Infinispan 6.0

3.10.5 Listeners for tree cache events


The current Infinispan listeners have been designed with key/value store notifications in mind, and hence
they do not map to tree cache events correctly. Tree cache specific listeners that map directly to tree cache
events (i.e. adding a child...etc) are desirable but these are not yet available. If you're interested in this type
of listeners, please follow this issue to find out about any progress in this area.

3.11 Infinispan as a storage for Lucene indexes


Infinispan is including a highly scalable distributed Apache Lucene Directory implementation.
This directory closely mimicks the same semantics of the traditional filesystem and RAM-based directories,
being able to work as a drop-in replacement for existing applications using Lucene and providing reliable
index sharing and other features of Infinispan like node autodiscovery, automatic failover and rebalancing,
optionally transactions, and can be backed by traditional storage solutions as filesystem, databases or cloud
store engines.
The implementation extends Lucene's org.apache.lucene.store.Directory so it can be used to store the index
in a cluster-wide shared memory, making it easy to distribute the index. Compared to rsync-based replication
this solution is suited for use cases in which your application makes frequent changes to the index and you
need them to be quickly distributed to all nodes, having configurable consistency levels, synchronicity and
guarantees, total elasticity and autodiscovery; also changes applied to the index can optionally participate in
a JTA transaction; since version 5 supporting XA transactions with recovery.
Two different LockFactory implementations are provided to guarantee only one IndexWriter at a time will
make changes to the index, again implementing the same semantics as when opening an index on a local
filesystem. As with other Lucene Directories, you can override the LockFactory if you prefer to use an
alternative implementation.

3.11.1 Additional Links


Javadoc: http://docs.jboss.org/infinispan/6.0/apidocs/org/infinispan/lucene/InfinispanDirectory.html
Issue tracker: https://jira.jboss.org/browse/ISPN/component/12312732
Source code: http://www.jboss.org/infinispan/sourcecode.html

3.11.2 Lucene compatibility


Current version was developed and compiled against both Lucene 3.6.2 and Lucene 4.4.0 (separately and
then assembled in a single jar for your convenience as most code is shared). It is also tested to work with
Lucene versions from 3.0.x to 3.5.0, version 2.9.x, the older 2.4.1 and newer version 4.0, 4.1, 4.2, 4.3.

JBoss Community Documentation

Page 94 of 617

Infinispan 6.0

3.11.3 How to use it


To create a Directory instance:

import org.apache.lucene.store.Directory;
import org.infinispan.lucene.directory.DirectoryBuilder;
import org.infinispan.Cache;
Cache cache = // create an Infinispan cache, configured as you like
Directory indexDir = DirectoryBuilder.newDirectoryInstance(cache, cache, cache, indexName)
.create();

The indexName is a unique key to identify your index. It takes the same role as the path did on filesystem
based indexes: you can create several different indexes giving them different names. When you use the
same indexName in another instance connected to the same network (or instantiated on the same machine,
useful for testing) they will join, form a cluster and share all content. Using a different indexName allows you
to store different indexes in the same set of Caches.
The cache is passed three times in this example, as that is ok for a quick demo, but as the API suggests it's
a good idea to tune each cache separately as they will be used in different ways. More details provided
below.
New nodes can be added or removed dynamically, making the service administration very easy and also
suited for cloud environments: it's simple to react to load spikes, as adding more memory and CPU power to
the search system is done by just starting more nodes.

3.11.4 Limitations
As when using an IndexWriter on a filesystem based Directory, even on the clustered edition only one
IndexWriter can be opened across the whole cluster.
As an example, Hibernate Search, which includes integration with this Lucene Directory since version 3.3,
sends index change requests across a JMS queue, or a JGroups channel. Other valid approaches are to
proxy the remote IndexWriter or just design your application in such a way that only one node attempts to
write it.
Reading (searching) is of course possible in parallel, from any number of threads on each node; changes
applied to the single IndexWriter are affecting results of all threads on all nodes in a very short time, or
guaranteed to be visible after a commit when using transactions.

JBoss Community Documentation

Page 95 of 617

Infinispan 6.0

3.11.5 Configuration
Infinispan can be configured as LOCAL clustering mode, in which case it will disable clustering features and
serve as a cache for the index, or any clustering mode.
A transaction manager is not mandatory, but when enabled the changes to the index can participate in
transactions.
Batching was required in previous versions, it's not strictly needed anymore.
As better explained in the javadocs of org.infinispan.lucene.InfinispanDirectory, it's possible for it to use more
than a single cache, using specific configurations for different purposes. When using readlocks, make sure
to not enable transactions on this cache.
Any Infinispan configuration should work fine as long as caches are not configured to remove entries after
thresholds.

3.11.6 Demo
There is a simple command-line demo of it's capabilities distributed with Infinispan under
demos/lucene-directory; make sure you grab the "Binaries, server and demos" package from download page
, which contains all demos.
Start several instances, then try adding text in one instance and searching for it on the other. The
configuration is not tuned at all, but should work out-of-the box without any changes. If your network
interface has multicast enabled, it will cluster across the local network with other instances of the demo.

3.11.7 Maven dependencies


All you need is org.infinispan:infinispan-lucene-directory :

<dependency>
<groupId>org.infinispan</groupId>
<artifactId>infinispan-lucene-directory</artifactId>
<version>5.3.0.Beta1</version>
</dependency>

JBoss Community Documentation

Page 96 of 617

Infinispan 6.0

3.11.8 Using a CacheLoader


Using a CacheLoader you can have the index content backed up to a permanent storage; you can use a
shared store for all nodes or one per node, see Cache Loaders and Stores for more details.
When using a CacheLoader to store a Lucene index, to get best write performance you would need to
configure the CacheLoader with async=true.

Storing the index in a database


It might be useful to store the Lucene index in a relational database; this would be very slow but Infinispan
can act as a cache between the application and the JDBC interface, making this configuration useful in both
clustered and non-clustered configurations.
When storing indexes in a JDBC database, it's suggested to use the JdbcStringBasedCacheStore, which will
need this attribute:

<property name="key2StringMapperClass" value="org.infinispan.lucene.LuceneKey2StringMapper" />

Loading an existing Lucene Index


The org.infinispan.lucene.cachestore.LuceneCacheLoader is an Infinispan CacheLoader able to have
Infinispan directly load data from an existing Lucene index into the grid. Currently this supports reading only.
Property

Description

Default

location

The path where the indexes are stored. Subdirectories (of first level only)

none

should contain the indexes to be loaded, each directory matching the index

(mandatory)

name attribute of the InfinispanDirectory constructor.


autoChunkSize A threshold in bytes: if any segment is larger than this, it will be

32MB

transparently chunked in smaller cache entries up to this size.


It's worth noting that the IO operations are delegated to Lucene's standard
org.apache.lucene.store.FSDirectory, which will select an optimal approach for the running platform.
Implementing write-through should not be hard: you're welcome to try implementing it.

JBoss Community Documentation

Page 97 of 617

Infinispan 6.0

3.11.9 Architectural limitations


This Directory implementation makes it possible to have almost real-time reads across multiple nodes. A
fundamental limitation of the Lucene design is that only a single IndexWriter is allowed to make changes on
the index: a pessimistic lock is acquired by the writer; this is generally ok as a single IndexWriter instance is
very fast and accepts update requests from multiple threads. When sharing the Directory across Infinispan
nodes the IndexWriter limitation is not lifted: since you can have only one instance, that reflects in your
application as having to apply all changes on the same node.
There are several strategies to write from multiple nodes on the same index:
One node writes, the other delegate to it sending messages
Each node writes on turns
You application makes sure it will only ever apply index writes on one node
The Infinispan Lucene Directory protects its content by implementing a distributed locking strategy, though
this is designed as a last line of defense and is not to be considered an efficient mechanism to coordinate
multiple writes: if you don't apply one of the above suggestions and get high write contention from multiple
nodes you will likely get timeout exception.

3.11.10 Suggestions for optimal performance


JGroups & Neworking stack
JGroups manages all network IO and as such it is a critical component to tune for your specific environment.
Make sure to read the JGroups reference documentation, and play with the performance tests included in
JGroups to make sure your network stack is setup appropriately.
Don't forget to check also operating system level parameters, for example buffer sizes dedicated for
networking. JGroups will log warning when it detects something wrong, but there is much more you can look
into.

Using a CacheStore
Currently all CacheStore implementations provided by Infinispan have a significant slowdown; we hope to
resolve that soon but for the time being if you need high performance on writes with the Lucene Directory the
best option is to disable any CacheStore; the second best option is to configure the CacheStore as async.
If you only need to load a Lucene index from read-only storage, see the above description for
org.infinispan.lucene.cachestore.LuceneCacheLoader.

Apply standard Lucene tuning


All known options of Lucene apply to the Infinispan Lucene Directory as well; of course the effect might be
less significant in some cases, but you should definitely read the Apache Lucene documentation.

JBoss Community Documentation

Page 98 of 617

Infinispan 6.0

Disable batching and transactions


Early versions required Infinispan to have batching or transactions enabled. This is no longer a requirement,
and in fact disabling them should provide little improvement in performance.

Set the right chunk size


The chunk size is an optional parameter to be passed to the Directory builder. While it's optional, its default
is suited only for testing and small demos, while setting a larger size can have a dramatic effect on
performance especially when running on multiple nodes. To correctly set this variable you need to estimate
what the expected size of your segments is; generally this is trivial by looking at the file size of the index
segments generated by your application when it's using the standard FSDirectory.
You then have to consider:
The chunk size affects the size of internally created buffers, so you don't want an outrageously large
array as you're going to waste precious JVM memory. Also consider that during index writing such
arrays are frequently allocated.
If a segment doesn't fit in the chunk size, it's going to be fragmented. When searching on a
fragmented segment performance can't peak.
Using the org.apache.lucene.index.IndexWriterConfig you can tune your index writing to approximately keep
your segment size to a reasonable level, from there then tune the chunksize, after having defined the
chunksize you might want to revisit your network configuration settings.

Use dedicated Cache instances


When constructing the Directory instance you have the option to specify different caches. The
metadataCache is going to be accessed frequently by all nodes and its content is very small, so it's best to
use REPL_SYNC. The chunksCache contains the raw byte arrays of your index segments otherwise stored
on filesystem, so - assuming your system is read-mostly - you might also want to use replication on this
cache, but you have to consider if you have enough memory to store all the data replicated on all nodes; if
not, you might be better off using DIST_SYNC, optionally enabling L1. The distLocksCache cache is similar
to the chunksCache, just that it doesn't need a CacheStore even if you want to persist the index.

3.12 Infinispan Server Modules


Introduction
Client-Server over Peer-to-Peer
Peer-to-Peer over Client-Server
Server Modules
REST Server Module
Memcached Server Module
Hot Rod Server Module
WebSocket Server Module
Server Comparison Summary

JBoss Community Documentation

Page 99 of 617

Infinispan 6.0

3.12.1 Introduction
Traditionally, clients have interacted with Infinispan in a peer-to-peer (p2p) fashion where Infinispan and the
client code that accessed it lived within the same VM. When Infinispan is queried in this way, it is considered
to be accessed in an embedded fashion, as shown in the screenshot below

Client-Server over Peer-to-Peer


However, there are situations when accessing Infinispan in a client-server mode might make more sense
than accessing it via p2p. For example, when trying to access Infinispan from a non-JVM environment .
Since Infinispan is written in Java, if someone had a C++ application that wanted to access it, it couldn't just
do it in a p2p way. On the other hand, client-server would be perfectly suited here assuming that a language
neutral protocol was used and the corresponding client and server implementations were available.

In other situations, Infinispan users want to have an elastic application tier where you start/stop business
processing servers very regularly. Now, if users deployed Infinispan configured with distribution or state
transfer, startup time could be greatly influenced by the shuffling around of data that happens in these
situations. So in the following diagram, assuming Infinispan was deployed in p2p mode, the app in the
second server could not access Infinispan until state transfer had completed.

JBoss Community Documentation

Page 100 of 617

Infinispan 6.0
This effectively means that bringing up new application-tier servers is impacted by things like state transfer
because applications cannot access Infinispan until these processes have finished and if the state being
shifted around is large, this could take some time. This is undesirable in an elastic environment where you
want quick application-tier server turnaround and predictable startup times. Problems like this can be solved
by accessing Infinispan in a client-server mode because starting a new application-tier server is just a matter
of starting a lightweight client that can connect to the backing data grid server. No need for rehashing or
state transfer to occur and as a result server startup times can be more predictable which is very important
for modern cloud-based deployments where elasticity in your application tier is important.

Other times, it's common to find multiple applications needing access to data storage. In this cases, you
could in theory deploy an Infinispan instance per each of those applications but this could be wasteful and
difficult to maintain. Thing about databases here, you don't deploy a database alongside each of your
applications, do you? So, alternatively you could deploy Infinispan in client-server mode keeping a pool of
Infinispan data grid nodes acting as a shared storage tier for your applications .

Deploying Infinispan in this way also allows you to manage each tier independently, for example, you can
upgrade you application or app server without bringing down your Infinispan data grid nodes.

JBoss Community Documentation

Page 101 of 617

Infinispan 6.0

Peer-to-Peer over Client-Server


Before talking about individual Infinispan server modules, it's worth mentioning that in spite of all the
benefits, client-server Infinispan still has disadvantages over p2p. Firstly, p2p deployments are simpler than
client-server ones because in p2p, all peers are equals to each other and hence this simplifies deployment.
So, if this is the first time you're using Infinispan, p2p is likely to be easier for you to get going compared to
client-server.
Client-server Infinispan requests are likely to take longer compared to p2p requests, due to the serialization
and network cost in remote calls. So, this is an important factor to take in account when designing your
application. For example, with replicated Infinispan caches, it might be more performant to have lightweight
HTTP clients connecting to a server side application that accesses Infinispan in p2p mode, rather than
having more heavyweight client side apps talking to Infinispan in client-server mode, particularly if data size
handled is rather large. With distributed caches, the difference might not be so big because even in p2p
deployments, you're not guaranteed to have all data available locally.
Environments where application tier elasticity is not so important, or where server side applications access
state-transfer-disabled, replicated Infinispan cache instances are amongst scenarios where Infinispan p2p
deployments can be more suited than client-server ones.

3.12.2 Server Modules


So, now that it's clear when it makes sense to deploy Infinispan in client-server mode, what are available
solutions? All Infinispan server modules are based on the same pattern where the server backend creates
an embedded Infinispan instance and if you start multiple backends, they can form a cluster and
share/distribute state if configured to do so. The server types below primarily differ in the type of listener
endpoint used to handle incoming connections. Here's a brief look at each of them:

REST Server Module


This module, which is distributed as a WAR file, can be deployed in any servlet container to allow
Infinispan to be accessed via a RESTful HTTP interface.
To connect to it, you can use any HTTP client out there and there're tons of different client
implementations available out there for pretty much any language or system.
This module is particularly recommended for those environments where HTTP port is the only access
method allowed between clients and servers.
Clients wanting to load balance or failover between different Infinispan REST servers can do so using
any standard HTTP load balancer such as mod_cluster. It's worth noting though these load balancers
maintain a static view of the servers in the backend and if a new one was to be added, it would
require manual update of the load balancer.

JBoss Community Documentation

Page 102 of 617

Infinispan 6.0

Memcached Server Module


This module is an implementation of the Memcached text protocol backed by Infinispan.
To connect to it, you can use any of the existing Memcached clients which are pretty diverse.
As opposed to Memcached servers, Infinispan based Memcached servers can actually be clustered
and hence they can replicate or distribute data using consistent hash algorithms around the cluster.
So, this module is particularly of interest to those users that want to provide failover capabilities to the
data stored in Memcached servers.
In terms of load balancing and failover, there're a few clients that can load balance or failover given a
static list of server addresses (perl's Cache::Memcached for example) but any server addition or
removal would require manual intervention.

Hot Rod Server Module


This module is an implementation of the Hot Rod binary protocol backed by Infinispan which allows
clients to do dynamic load balancing and failover and smart routing.
So far, a single Java client, which is the reference implementation, has been fully developed. A beta
version of the Python client is available, and a JRuby and pure Ruby clients are in the making.
If you're clients are running Java, this should be your defacto server module choice because it allows
for dynamic load balancing and failover. This means that Hot Rod clients can dynamically detect
changes in the topology of Hot Rod servers as long as these are clustered, so when new nodes join
or leave, clients update their Hot Rod server topology view. On top of that, when Hot Rod servers are
configured with distribution, clients can detect where a particular key resides and so they can route
requests smartly.
Load balancing and failover is dynamically provided by Hot Rod client implementations using
information provided by the server.

WebSocket Server Module


This module enables Infinispan to be exposed over a Websocket interface via a Javascript API.
This module is very specifically designed for Javascript clients and so that is the only client
implementation available.
This module is particularly suited for developers wanting to enable access to Infinispan instances from
their Javascript codebase.
Since websockets work on the same HTTP port, any HTTP load balancer would do to load balance
and failover.

JBoss Community Documentation

Page 103 of 617

Infinispan 6.0

3.12.3 Server Comparison Summary


Here's a table comparing and summarizing the capabilities of distinct server modules:

3.13 Management Tooling


Introduction
JMX
Enabling JMX Statistics
Understanding The MBeans
Infinispan 4.1 or earlier
Infinispan 4.2 or later
Multiple JMX Domains
Infinispan 4.1 or earlier
Infinispan 4.2 or later
Registering MBeans In Non-Default MBean Servers
MBean additions in Infinispan 5.0
RHQ
RHQ monitoring tips
Writing plugins for other management tools

3.13.1 Introduction
Management of Infinispan instances is all about exposing as much relevant statistical information that allows
administrators to get view of the state of each Infinispan instance. Taking in account that a single installation
could be made up of several tens or hundreds Infinispan instances, providing clear and concise information
in an efficient manner is imperative. The following sections dive into the range of management tooling that
Infinispan provides.

3.13.2 JMX
Over the years, JMX has become the de facto standard for management and administration of middleware
and as a result, the Infinispan team has decided to standarize on this technology for the exposure of
management or statistical information.

JBoss Community Documentation

Page 104 of 617

Infinispan 6.0

Enabling JMX Statistics


JMX reporting can be enabled at 2 different levels:
1. CacheManager level: The CacheManager is the entity that governs all the cache instances that have been
created from it. Details on the information exposed at the CacheManager level can be found below. For the
moment, let's just focus on how to enable the CacheManager to report management data via JMX.
If configuring the CacheManager via XML, make sure you add the following XML under the <global>
element:

<globalJmxStatistics enabled="true"/>

If configuring the CacheManager programmatically, simply add the following code:

GlobalConfiguration globalConfiguration = ...


globalConfiguration.setExposeGlobalJmxStatistics(true);

2. Cache level: At this level, you will receive management information generated by individual cache
instances. Details on the information exposed at the Cache level are explained below. For the
moment, let's just focus on how to enable the Cache to report management data via JMX:
If configuring the Cache via XML, make sure you add the following XML under the either <default>, if
you're configuring the default Cache instance, or under the corresponding <namedCache>:

<jmxStatistics enabled="true"/>

If configuring the Cache programmatically, simply add the following code:

Configuration configuration = ...


configuration.setExposeJmxStatistics(true);

Understanding The MBeans


Once you have enabled JMX reporting at either the CacheManager or Cache level, you should be able to
connect to VM(s) where Infinispan is running using a standard JMX GUI such as JConsole or VisualVM, and
you should find the following MBeans:

JBoss Community Documentation

Page 105 of 617

Infinispan 6.0

Infinispan 4.1 or earlier


If you enabled CacheManager level JMX statistics, you should see an MBean called
infinispan:cache-name=[global],jmx-resource=CacheManager with properties specified by the
CacheManager MBean.
If you enabled Cache level JMX statistics, you should see several different MBeans depending on
which configuration options have been enabled. For example, if you have configured a write behind
cache store, you should see an MBean exposing properties belonging to the cache store component.
All Cache level MBeans will follow the same format though which is the following:
infinispan:cache-name=<name-of-cache>(<cache-mode>),jmx-resource=<component-name> where:
<name-of-cache> has been substituted by the actual cache name. If this cache represents the
default cache, its name will be "___defaultcache".
<cache mode> has been substituted by the cache mode of the cache. The cache mode is
represented by the lower case version of the possible enumeration values shown here.
<component-name> has been substituted by one of the JMX component names in the JMX
reference documentation.
For example, the cache store JMX component MBean for a default cache configured with synchronous
distribution would have the following
name:infinispan:cache-name=___defaultcache(dist_sync),jmx-resource=CacheStore
Please note that any cache names that contain ':' or '=' characters will be substituted by '_' character.
Infinispan does this because ':' and '=' are control characters for JMX object names.

JBoss Community Documentation

Page 106 of 617

Infinispan 6.0

Infinispan 4.2 or later


If you enabled CacheManager level JMX statistics, without further configuration, you should see an
MBean called org.infinispan:type=CacheManager,name="DefaultCacheManager" with properties
specified by the CacheManager MBean.
Using the cacheManagerName attribute in globalJmxStatistics XML element, or using the
corresponding GlobalConfiguration.setCacheManagerName() call, you can name the cache manager
in such way that the name is used as part of the JMX object name. So, if the name had been
"Hibernate2LC", the JMX name for the cache manager would have been:
org.infinispan:type=CacheManager,name="Hibernate2LC" . This offers a nice and clean way to
manage environments where multiple cache managers are deployed, which follows JMX best
practices.
If you enabled Cache level JMX statistics, you should see several different MBeans depending on
which configuration options have been enabled. For example, if you have configured a write behind
cache store, you should see an MBean exposing properties belonging to the cache store component.
All Cache level MBeans follow the same format though which is the following:

org.infinispan:type=Cache,name="<name-of-cache>(<cache-mode>)",manager="<name-of-cache-manager>",comp
where:
<name-of-cache> has been substituted by the actual cache name. If this cache represents the
default cache, it's name will be "_defaultCache" .
<cache-mode> has been substituted by the cache mode of the cache. The cache mode is
represented by the lower case version of the possible enumeration values shown here.
<name-of-cache-manager> has been substituted by the name of the cache manager to which
this cache belongs. The name is derived from the cacheManagerName attribute value in
globalJmxStatistics element.
<component-name> has been substituted by one of the JMX component names in the JMX
reference documentation.
For example, the cache store JMX component MBean for a default cache configured with synchronous
distribution would have the following name: org.infinispan:type=Cache,name="_defaultcache(dist_sync)",
manager="DefaultCacheManager",component=CacheStore
Please note that cache and cache manager names are quoted to protect against illegal characters being
used in these user-defined names.

Multiple JMX Domains


There can be situations where several CacheManager instances are created in a single VM, or Cache
names belonging to different CacheManagers under the same VM clash.

JBoss Community Documentation

Page 107 of 617

Infinispan 6.0

Infinispan 4.1 or earlier


In order to cope with such situations, Infinispan enabled users to define a particular JMX domain prefix for
their MBeans. For example, either of these two options could be used to configure a JMX domain prefix
called "myInfinispan" for the CacheManager JMX statistics:
Via XML:

<globalJmxStatistics enabled="true" jmxDomain="myInfinispan"/>

Programmatically:

GlobalConfiguration globalConfiguration = ...


globalConfiguration.setExposeGlobalJmxStatistics(true);
globalConfiguration.setJmxDomain("myInfinispan");

Using either of these options should result on the CacheManager MBean name being:
myInfinispan:cache-name=[global],jmx-resource=CacheManager
As you probably have guessed by now, the default JMX domain prefix is called " infinispan ".
Another related configuration option for both CacheManager and Cache JMX statistics allows for duplicate
JMX domains to be discovered. Internally, when duplicates are allowed, Infinispan takes the duplicating JMX
domain prefix, adds an index that starts at number 2 to the existing prefix and uses that JMX prefix from then
onwards. So, for example, if two CacheManagers were started with global JMX statistics enabled, no
particular JMX domain was configured, and JMX domain duplicates were allowed, the first CacheManager
would be registered under "infinispan... ", whereas the second one would be registered under: " infinispan2...
". To allow JMX duplicate domains, do the following:
Via XML:

<globalJmxStatistics enabled="true" allowDuplicateDomains="true"/>

Programmatically:

GlobalConfiguration globalConfiguration = ...


globalConfiguration.setExposeGlobalJmxStatistics(true);
globalConfiguration.setAllowDuplicateDomains(true)

Remember that by default, duplicate domains are disallowed.

JBoss Community Documentation

Page 108 of 617

Infinispan 6.0

Infinispan 4.2 or later


Using different JMX domains for multi cache manager environments should be last resort. Instead, as
mentioned in previous section, it's now possible to name a cache manager in such way that it can easily be
identified and used by monitoring tools such as RHQ. For example:
Via XML:

<globalJmxStatistics enabled="true" cacheManagerName="Hibernate2LC"/>

Programmatically:

GlobalConfiguration globalConfiguration = ...


globalConfiguration.setExposeGlobalJmxStatistics(true);
globalConfiguration.setCacheManagerName("Hibernate2LC");

Using either of these options should result on the CacheManager MBean name being:
org.infinispan:type=CacheManager,name="Hibernate2LC"
Please note as well that since 4.2, the default domain names has changed from "infinispan" to
"org.infinispan", as per JMX best practices.
For the time being, you can still set your own jmxDomain if you need to and we also allow duplicate
domains, or rather duplicate JMX names, but these should be limited to very special cases where different
cache managers within the same JVM are named equally.

JBoss Community Documentation

Page 109 of 617

Infinispan 6.0

Registering MBeans In Non-Default MBean Servers


To finish up with this JMX section, let's quickly discuss where Infinispan registers all these MBeans. By
default, Infinispan registers them in the standard JVM MBeanServer plattform. However, users might want to
register these MBeans in a different MBeanServer instance. For example, an application server might work
with a different MBeanServer instance to the default plattform one. In such cases, users should implement
the MBeanServerLookup interface provided by Infinispan so that the getMBeanServer() method returns the
MBeanServer under which Infinispan should register the management MBeans. You can find an example in
the default PlatformMBeanServerLookup class used by Infinispan. So, once you have your implementation
ready, simply configure Infinispan with the fully qualified name of this class. For example:
Via XML:

<globalJmxStatistics enabled="true" mBeanServerLookup="com.acme.MyMBeanServerLookup"/>

Programmatically:

GlobalConfiguration globalConfiguration = ...


globalConfiguration.setExposeGlobalJmxStatistics(true);
globalConfiguration.setMBeanServerLookup("com.acme.MyMBeanServerLookup")

MBean additions in Infinispan 5.0


There has been a couple of noticeable additions in Infinispan 5.0 in terms of MBean exposed:
1. MBeans related to Infinispan servers are now available that for the moment focus on the transport
layer. So, if the Infinispan servers are configured with global JMX statistics, a brand new MBean in
org.infinispan:type=Server,name=<Memcached|Hotrod>,component=Transport is now available
which offers information such as: host name, port, bytes read, byte written, number of worker
threads...etc.
2. When global JMX statistics are enabled, JGroups MBeans are also registered automatically, so you
can get key information of the group communication transport layer that's used to cluster Infinispan
instances. To find out more about the information provided, check the JGroups JMX documentation.

3.13.3 RHQ
The preferred way to manage multiple Infinispan instances spread accross different servers is to use RHQ,
which is JBoss' enterprise management solution. Thanks to RHQ's agent and auto discovery capabilities,
monitoring both Cache Manager and Cache instances is a very simple task. With RHQ, administrators have
access to graphical views of key runtime parameters or statistics and can also be notified be these exceed
or go below certain limits. The Infinispan specific statistics shown by RHQ are a reflection of the JMX
information exposed by Infinispan which has been formatted for consumption by RHQ. Please follow these
steps to get started with RHQ and have Infinispan instances monitored with it:

JBoss Community Documentation

Page 110 of 617

Infinispan 6.0

1. Firstly, download and install an RHQ server and install and start at least one RHQ agent. The job of
the RHQ agent is to send information about the Infinispan instance back to the server which is the
one that shows the information via a nice GUI. You can find detailed information on the installation
process in RHQ's installation guide and you can find information on how to run an agent in the RHQ
agent guide.

Careful with H2 database installation


If you're just building a demo or testing RHQ server, you can avoid the need to install a fully
fledged database and use an in-memory H2 database instead. However, you might
encounter issues after testing database connection as shown here. Simply repeating the
installation avoiding testing the connection should work.

Where do I install the RHQ agent?


The most common set up is to have the RHQ agent installed in the same machine where
Infinispan is running. If you have multiple machines, an agent can be installed in each
machine.

2. By now, you should have an RHQ server and agent running. It's time now to download the latest
Infinispan binary distribution (*-bin.zip or *-all.zip should do) from the downloads section and locate
the RHQ plugin jar file which should be named something like infinispan-rhq-plugin.jar. This
is located under the modules/rhq-plugin directory.
3. The adding and updating plugins section on the RHQ guide contains some more detailed information
on how to update both RHQ servers and agents with new plugins, but essentially, this process
involves uploading a new plugin to the RHQ server and then pushing the plugin to one, or several,
RHQ agents.

Speeding up plugin installation


If you're simply demoing or testing and you only have a single agent, once the plugin has
been uploaded to the server, simply go to the agent command line interface and type:
plugins update .This will force the agent to retrieve the latest plugins from the server.
Doing this can be considerably faster than some of the other alternatives.

JBoss Community Documentation

Page 111 of 617

Infinispan 6.0
4. At this point, RHQ is ready to start monitoring Infinispan instances, but before firing them up, make
sure you start them with the following system properties so that RHQ agents can discover them:

-Dcom.sun.management.jmxremote.port=6996 -Dcom.sun.management.jmxremote.ssl=false
-Dcom.sun.management.jmxremote.authenticate=false

Remote JMX port value


The actual port value used does not really matter here, but what matters is that a port is
given, otherwise Infinispan instances cannot be located. So, you can easily start multiple
Infinispan instances in a single machine, each with a different remote JMX port, and a locally
running agent will be able to discover them all without any problems.

5. Once Infinispan instances have been discovered, you should see a new resource for each of the
cache manager running appearing in the Inventory/Discovery Queue of the RHQ server. Simply
import it now and you should see each cache manager appearing with as many child cache resources
as caches are running in each cache manager. You're now ready to monitor Infinispan!

JBoss Community Documentation

Page 112 of 617

Infinispan 6.0

RHQ monitoring tips


This section focuses on the lessons learned while developing the Infinispan RHQ plugin that are likely to be
useful to anyone using RHQ.
By default, at least in version 2.3.1 of RHQ, the RHQ agent sends an availability report of any
managed resources every 5 minutes. The problem with this is that if you're testing whether your
Infinispan instance is automatically discovered by the RHQ server, it can take up to 5 minutes to do
so! Also, it can take 5 minutes for the RHQ server to figure out that you've shutdown your Infinispan
instance. You can change this setting by the following property (default value is 300 seconds) in
rhq-agent/conf/agent-configuration.xml. For example, if you wanted the availability to be sent every 1
minute, simply change the value to 60:

<entry key="rhq.agent.plugins.availability-scan.period-secs" value="60"/>

Careful with agent configuration changes


Please bear in mind the instructions given in the RHQ agent installation and more
specifically the paragraph below with regards to changes made to properties in
agent-configuration.xml:
Once the agent is configured, it persists its configuration in the Java Preferences
backing store. Once this happens, agent-configuration.xml is no longer needed or
used. Editing agent-configuration.xml will no longer have any effect on the agent,
even if you restart the agent. If you want the agent to pick up changes you make to
agent-configuration.xml, you must either restart the agent with the "--cleanconfig"
command line option or use the "config --import" agent prompt command.

3.13.4 Writing plugins for other management tools


As mentioned in the previous section, RHQ consumes the JMX data exposed by Infinispan, and in similar
fashion, plugins could be written for other 3rd party management tools that were able to transform these data
into the correct representation in these tools, for example graphs,...etc.

JBoss Community Documentation

Page 113 of 617

Infinispan 6.0

3.14 Asynchronous Options


Introduction
Asynchronous Communications
Asynchronous Marshalling
Replication Queue
Asynchronous API
Return Values

3.14.1 Introduction
When Infinispan instances are clustered, regardless of the clustering mode, data can be propagated to other
nodes in a synchronous or asynchronous way. When synchronous, the sender waits for replies from the
receivers and when asynchronous, the sender sends the data and does not wait for replies from other nodes
in the cluster.
With asynchronous modes, speed is more important than consistency and this is particularly advantageous
in use cases such as HTTP session replication with sticky sessions enabled. In these scenarios, data, or in
this case a particular session, is always accessed on the same cluster node and only in case of failure is
data accessed in a different node. This type of architectures allow consistency to be relaxed in favour of
increased performance.
In order to choose the asynchronous configuration that best suits your application, it's important to
understand the following configuration settings:

3.14.2 Asynchronous Communications


Whenever you add <async> element within <clustering>, you're telling the underlying JGroups layer in
Infinispan to use asynchronous communication. What this means is that JGroups will send any
replication/distribution/invalidation request to the wire but will not wait for a reply from the receiver.

JBoss Community Documentation

Page 114 of 617

Infinispan 6.0

3.14.3 Asynchronous Marshalling


This is a configurable boolean property of <async> element that indicates whether the actual call from
Infinispan to the JGroups layer is done on a separate thread or not. When set to true, once Infinispan has
figured out that a request needs to be sent to another node, it submits it to the async transport executor so
that it can talk to the underlying JGroups layer.
With asynchronous marshalling, Infinispan requests can return back to the client quicker compared to when
async marshalling is set to false. The downside though is that client requests can be reordered before they
have reached the JGroups layer. In other words, JGroups provides ordering guarantees even for async
messages but with async marshalling turned on, requests can reach the JGroups in a different order in
which they're called. This can effectively lead to data consistency issues in applications making multiple
modifications on the same key/value pair. For example, with async marshalling turned on:
App calls:

cache.put("car", "bmw");
cache.remove("car");

Other nodes could receive these operations in this order:

cache.remove("car");
cache.put("car", "bmw");

The end result is clearly different which is often not desirable. So, if your application makes multiple
modifications on the same key, you should either: turned off asynchronous marshalling, or set
<asyncTransportExecutor> element's maxThreads to 1. The first modification only applies to a particular
named cache, whereas the second option affects all named caches in configuration file that are configured
with async marshalling. It's worth noting though that having this type of executor configured with a single
thread would defeat its purpose adding unnecessary contention point. It'd be better to simply switch off
async marshalling.
On the contrary, if your application only ever makes one modification per key/value pair and there's no
happens-before relationship between them, then async marshalling is a very valid optimization that can
increase performance of your application without data consistency risks.
If you have async marshalling turned on and see exceptions related to
java.util.concurrent.RejectedExecutionException, as explained in the technical faq page, you
should also consider switching off async marshalling.
Back in Infinispan 4.0, when <async> element was used, this property was set to true by default. However
due to reordering risks mentioned earlier, the default has changed to false from Infinispan 4.1 onwards.

JBoss Community Documentation

Page 115 of 617

Infinispan 6.0

3.14.4 Replication Queue


The aim of the replication queue is to batch the individual cache operations and send them as one, as
opposed to sending each cache operation individually. As a result, replication queue enabled configurations
perform generally better compared to those that have it switched off because less RPC messages are sent,
fewer envelopes are used...etc. The only real trade off to the replication queue is that the queue is flushed
periodically (based on time or queue size) and hence it might take longer for the
replication/distribution/invalidation to be realised across the cluster. When replication queue is turned off,
data is placed directly on the wire and hence it takes less for data to arrive to other nodes.
Until Infinispan 4.1.0.CR2, replication queue always flushed data with async marshalling turned on, which
meant that there was a small gap where flush calls could be reordered. Since 4.1.0.CR3, async marshalling
configuration is taken into account, and decides whether the flush calls goes directly to the JGroups layer, or
whether an intermediate handing over to a different thread occurs. The advantages of using async
marshalling with replication queue are less than clear because replication queue itself already makes client
requests return faster, so it's generally recommended to have async marshalling turned off, or
<asyncTransportExecutor> element's maxThreads set to 1, when replication queue is turned on.

3.14.5 Asynchronous API


Finally, the asynchronous API can be used to emulate non-blocking APIs, whereby calls are handed over to
a different thread and asynchronous API calls return to the client immediately. Similar to async marshalling,
using this API can lead to reordering, so you should avoid calling modifying asynchronous methods on the
same keys.

3.14.6 Return Values


Regardless of the asynchronous option used, the return values of cache operations are reliable. If talking
about return values of cache operations that return previous value, the correctness of these returns are
guaranteed as well regardless of the clustering mode. With replication, the previous value is already
available locally, and with distribution, regardless of whether it's asynchronous or synchronous, Infinispan
sends a synchronous request to get the previous value if not present locally. If on the other hand the
asynchronous API is used, client code needs to get hold of the NotifiyngFuture returned by the async
operation in order to be able to query the previous value.

3.15 Infinispan as Hibernate 2nd-Level Cache in JBoss


AS 5.x
A JBoss AS 5.x application can be configured to use Infinispan 4.x as the Hibernate 2nd-level cache,
replacing JBoss Cache.

JBoss Community Documentation

Page 116 of 617

Infinispan 6.0

1. Add the attached jar files to the ear lib directory. These include the core 4.1.0.GA Infinispan jar
(infinispan-core.jar), the Hibernate/Infinispan integration jar back-ported from Hibernate 3.5
(hibernate-infinispan-3.3.2.GA_CP03.jar), the JGroups jar required by Infinispan 4.1.0
(jgroups-2.10.0.GA.jar), and other required 3rd party jars (river-1.2.3.GA.jar,
marshalling-api-1.2.3.GA.jar)
2. Isolate the classloading to be ear-scoped by adding META-INF/jboss-classloading.xml
3. <classloading xmlns="urn:jboss:classloading:1.0" domain="simple-scoped"
parent-first="false" />

4. Configure persistence.xml to use Infinispan instead of JBoss Cache:

<?xml version="1.0" encoding="UTF-8"?>


<persistence xmlns="http://java.sun.com/xml/ns/persistence"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/persistence
http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd"
version="1.0">
<persistence-unit name="jpa-test">
<jta-data-source>java:/PostgresDS</jta-data-source>
<properties>
<property name="hibernate.dialect" value="org.hibernate.dialect.HSQLDialect"
/>
<property name="hibernate.session_factory_name"
value="SessionFactories/infinispan" />
<property
<property
<property
<property

name="hibernate.cache.use_query_cache" value="true" />


name="hibernate.cache.use_second_level_cache" value="true" />
name="hibernate.generate_statistics" value="true" />
name="hibernate.cache.use_structured_entries" value="true" />

<property name="hibernate.cache.region_prefix" value="infinispan" />


<property name="hibernate.show_sql" value="true" />
<property name="hibernate.hbm2ddl.auto" value="validate" />
<!-- Infinispan second level cache configuration -->
<property name="hibernate.cache.region.factory_class"
value="org.hibernate.cache.infinispan.InfinispanRegionFactory" />
</properties>
</persistence-unit>
</persistence>

JBoss Community Documentation

Page 117 of 617

Infinispan 6.0

3.16 Clustered Configuration QuickStart


Infinispan ships with pre-configured JGroups stacks that make it easy for you to jump-start a clustered
configuration.
Using an external JGroups file
Use one of the pre-configured JGroups files
Fine-tuning JGroups settings
jgroups-udp.xml
jgroups-tcp.xml
jgroups-ec2.xml
Further reading

3.16.1 Using an external JGroups file


If you are configuring your cache programmatically, all you need to do is:

// ...
GlobalConfiguration gc = new
GlobalConfigurationBuilder().transport().addProperty("configurationFile",
"jgroups.xml").build();
// ...

and if you happen to use an XML file to configure Infinispan, just use:

<infinispan>
<global>
<transport>
<properties>
<property name="configurationFile" value="jgroups.xml" />
</properties>
</transport>
</global>
...
</infinispan>

In both cases above, Infinispan looks for jgroups.xml first in your classpath, and then for an absolute path
name if not found in the classpath.

JBoss Community Documentation

Page 118 of 617

Infinispan 6.0

3.16.2 Use one of the pre-configured JGroups files


Infinispan ships with a few different JGroups files (packaged in infinispan-core.jar) which means they will
already be on your classpath by default. All you need to do is specify the file name, e.g., instead of
jgroups.xml above, specify jgroups-tcp.xml.
The configurations available are:
jgroups-udp.xml - Uses UDP as a transport, and UDP multicast for discovery. Usually suitable for
larger (over 100 nodes) clusters or if you are using replication or invalidation. Minimises opening too
many sockets.
jgroups-tcp.xml - Uses TCP as a transport and UDP multicast for discovery. Better for smaller
clusters (under 100 nodes) only if you are using distribution, as TCP is more efficient as a
point-to-point protocol
jgroups-ec2.xml - Uses TCP as a transport and S3_PING for discovery. Suitable on Amazon EC2
nodes where UDP multicast isn't available.

Fine-tuning JGroups settings


The settings above can be further tuned without editing the XML files themselves. Passing in certain system
properties to your JVM at startup can affect the behaviour of some of these settings. The table below shows
you which settings can be configured in this way. E.g.,

$ java -cp ... -Djgroups.tcp.port=1234 -Djgroups.tcp.address=10.11.12.13

jgroups-udp.xml
System Property

Description

Default

Required?

jgroups.udp.mcast_addr IP address to use for multicast (both for communications 228.6.7.8 No


and discovery). Must be a valid Class D IP address,
suitable for IP multicast.
jgroups.udp.mcast_port

Port to use for multicast socket

46655

No

jgroups.udp.ip_ttl

Specifies the time-to-live (TTL) for IP multicast packets.

No

The value here refers to the number of network hops a


packet is allowed to make before it is dropped

JBoss Community Documentation

Page 119 of 617

Infinispan 6.0

jgroups-tcp.xml
System Property

Description

Default

jgroups.tcp.address

IP address to use for the TCP transport.

127.0.0.1 No

jgroups.tcp.port

Port to use for TCP socket

7800

jgroups.udp.mcast_addr IP address to use for multicast (for discovery). Must be

Required?

No

228.6.7.8 No

a valid Class D IP address, suitable for IP multicast.


jgroups.udp.mcast_port

Port to use for multicast socket

46655

No

jgroups.udp.ip_ttl

Specifies the time-to-live (TTL) for IP multicast packets.

No

Required?

The value here refers to the number of network hops a


packet is allowed to make before it is dropped

jgroups-ec2.xml
System Property

Description

Default

jgroups.tcp.address

IP address to use for the TCP transport.

127.0.0.1 No

jgroups.tcp.port

Port to use for TCP socket

7800

jgroups.s3.access_key

The Amazon S3 access key used to access an S3

No
No

bucket
jgroups.s3.secret_access_key The Amazon S3 secret key used to access an S3

No

bucket
jgroups.s3.bucket

Name of the Amazon S3 bucket to use. Must be

No

unique and must already exist

3.16.3 Further reading


JGroups also supports more system property overrides, details of which can be found on this page:
SystemProps
In addition, the JGroups configuration files shipped with Infinispan are intended as a jumping off point to
getting something up and running, and working. More often than not though, you will want to fine-tune your
JGroups stack further to extract every ounce of performance from your network equipment. For this, your
next stop should be the JGroups manual which has a detailed section on configuring each of the protocols
you see in a JGroups configuration file.

JBoss Community Documentation

Page 120 of 617

Infinispan 6.0

3.17 Locking and Concurrency


Infinispan makes use of multi-versioned concurrency control (MVCC) - a concurrency scheme popular with
relational databases and other data stores. MVCC offers many advantages over coarse-grained Java
synchronization and even JDK Locks for access to shared data, including:
allowing concurrent readers and writers
readers and writers do not block one another
write skews can be detected and handled
internal locks can be striped
The rest of this wiki page is broken down into the following sections:
MVCC implementation details
Isolation levels
The LockManager
Lock striping
Concurrency levels
Explicit and implicit distributed eager locking
Locking a single remote node
Consistency
Non-transactional caches and concurrent updates

3.17.1 MVCC implementation details


Infinispan's MVCC implementation makes use of minimal locks and synchronizations, leaning heavily
towards lock-free techniques such as compare-and-swap and lock-free data structures wherever possible,
which helps optimize for multi-CPU and multi-core environments.
In particular, Infinispan's MVCC implementation is heavily optimized for readers. Reader threads do not
acquire explicit locks for entries, and instead directly read the entry in question.
Writers, on the other hand, need to acquire a write lock. This ensures only one concurrent writer per entry,
causing concurrent writers to queue up to change an entry. To allow concurrent reads, writers make a copy
of the entry they intend to modify, by wrapping the entry in a MVCCEntry. This copy isolates concurrent
readers from seeing partially modified state. Once a write has completed, MVCCEntry.commit() will flush
changes to the data container and subsequent readers will see the changes written.

JBoss Community Documentation

Page 121 of 617

Infinispan 6.0

3.17.2 Isolation levels


Infinispan offers two isolation levels - READ_COMMITTED (the default) and REPEATABLE_READ,
configurable via the <locking /> configuration element. These isolation levels determine when readers see a
concurrent write, and are implemented using different subclasses of MVCCEntry, which have different
behaviour in how state is committed back to the data container.
Here's a more detailed example that should help understand the difference between READ_COMMITTED
and REPEATABLE_READ in the context of Infinispan. With read committed, if between two consecutive
read calls on the same key, the key has been updated by another transaction, the second read will return the
new updated value:
1. Thread1: tx.begin()
2. Thread1: cache.get(k) returns v
3. Thread2: tx.begin()
4. Thread2: cache.get(k) returns v
5. Thread2: cache.put(k, v2)
6. Thread2: tx.commit()
7. Thread1: cache.get(k) returns v2!
With REPEATABLE_READ, step 7 will still return v. So, if you're gonna retrieve the same key multiple times
within a transaction, you should use REPEATABLE_READ.

3.17.3 The LockManager


The LockManager is a component that is responsible for locking an entry for writing. The LockManager
makes use of a LockContainer to locate/hold/create locks. LockContainers come in two broad flavours, with
support for lock striping and with support for one lock per entry.

JBoss Community Documentation

Page 122 of 617

Infinispan 6.0

3.17.4 Lock striping


Lock striping entails the use of a fixed-size, shared collection of locks for the entire cache, with locks being
allocated to entries based on the entry's key's hash code. Similar to the way the JDK's ConcurrentHashMap
allocates locks, this allows for a highly scalable, fixed-overhead locking mechanism in exchange for
potentially unrelated entries being blocked by the same lock.
The alternative is to disable lock striping - which would mean a new lock is created per entry. This approach
may give you greater concurrent throughput, but it will be at the cost of additional memory usage, garbage
collection churn, etc.

Default lock stripping settings


Since Infinispan 5.0, lock striping is disabled by default, due to potential deadlocks that can happen
if locks for different keys end up in the same lock stripe. Previously, in Infinispan 4.x lock striping
used to be enabled by default.

The size of the shared lock collection used by lock striping can be tuned using the concurrencyLevel
attribute of the <locking /> configuration element.

3.17.5 Concurrency levels


In addition to determining the size of the striped lock container, this concurreny level is also used to tune any
JDK ConcurrentHashMap based collections where related, such as internal to DataContainers. Please refer
to the JDK ConcurrentHashMap Javadocs for a detailed discussion of concurrency levels, as this parameter
is used in exactly the same way in Infinispan.

JBoss Community Documentation

Page 123 of 617

Infinispan 6.0

3.17.6 Explicit and implicit distributed eager locking


Infinispan, by default, acquires remote locks lazily. Locks are acquired locally on a node that runs a
transaction while other cluster nodes attempt to lock cache keys involved in a transaction during two-phase
prepare/commit phase. However, if desired, Infinispan can eagerly lock cache keys either explicitly or
implicitly.
Infinispan cache interface exposes lock API that allows cache users to explicitly lock set of cache keys
eagerly during a transaction. Lock call attempts to lock specified cache keys across all cluster nodes and it
either succeeds or fails. All locks are released during commit or rollback phase.
Consider a transaction running on one of the cache nodes:

tx.begin()
cache.lock(K)
cache.put(K,V5)
tx.commit()

// acquire cluster wide lock on K


// guaranteed to succeed
// releases locks

Implicit locking goes one step ahead and locks cache keys behind the scene as keys are accessed for
modification operations.
Consider a transaction running on one of the cache nodes:

tx.begin()
cache.put(K,V)
cache.put(K2,V2)
cache.put(K,V5)
tx.commit()

//
//
//
//

acquire cluster wide lock on K


acquire cluster wide lock on K2
no-op, we already own cluster wide lock for K
releases locks

Implicit eager locking locks cache keys across cluster nodes only if it is necessary to do so. In a nutshell, if
implicit eager locking is turned on then for each modification Infinispan checks if cache key is locked locally.
If it is then a global cluster wide lock has already been obtained, otherwise a cluster wide lock request is sent
and lock is acquired.
Implicit eager locking is enabled as follows:

<transaction useEagerLocking="true" />

3.17.7 Locking a single remote node


Starting with 4.2, Infinispan allows eagerLockSingleNode configuration option. This only applies for DIST
modes. Having this enabled would make the number of remote locks acquired to be always 1, disregarding
the configured numOwners. Following diagrams are intended to explain better this option. All diagrams
represent an cluster having 5 nodes, with numOwners=2.

JBoss Community Documentation

Page 124 of 617

Infinispan 6.0

Above diagram shows the situation where eagerLockSingleNode=false (default configuration). On each lock
request, numOwners remote calls are performed (in our example 2).

Above diagram shows how lock on the same key are acquired when eagerLockSingleNode=true. The
number of remote calls being performed is always 1, disregarding numOwners values (it can actually be 0,
as we'll see later on).
In this scenario, if the lock owner fails (Node_C) then the transaction that holds the lock, which originated on
Node_A is marked for rollback.
Combining eagerLockSingleNode with the KeyAffinityService can bring some interesting advantages. The
next diagram shows this:

By using KeyAffinityService one can generate keys that would always map to the local node. If
eagerLockSingleNode=true, then the remote lock acquisition happens locally: this way one can benefit from
eager locking semantics and having the same performance as non eager locking. The optimisation is
affected by cluster topology changes, so keys might get relocated. But for clusters where topology changes
are rather rare this can bring a lot of value.
The following xml snippet shows how can be configured:

<transaction
transactionManagerLookupClass="org.infinispan.transaction.lookup.GenericTransactionManagerLookup"
syncRollbackPhase="false"
syncCommitPhase="false"
useEagerLocking="true" eagerLockSingleNode="true"/>

<transaction
transactionManagerLookupClass="org.infinispan.transaction.lookup.GenericTransactionManagerLookup"
syncRollbackPhase="false"
syncCommitPhase="false"
useEagerLocking="true" eagerLockSingleNode="true"/>

Note that the configuration is ignored if eager locking is disabled or cache mode is not DIST.

JBoss Community Documentation

Page 125 of 617

Infinispan 6.0

Consistency
The fact that a single owner is locked (as opposed to all owners being locked) does not break the following
consistency guarantee: if key K is hashed to nodes {A, B} and transaction TX1 acquires a lock for K, let's say
on A. If another transaction, TX2, is started on B (or any other node) and TX2 tries to lock K then it will fail
with a timeout as the lock is already held by TX1. The reason for this is the that the lock for a key K is
always, deterministically, acquired on the same node of the cluster, regardless of where the transaction
originates.

3.17.8 transactional caches and concurrent updates


This configuration refers to non-transactional distributed and local caches only (doesn't apply to replicated
caches) and was added in Infinispan 5.2. Depending on whether one needs to support concurrent updates
(e.g. two threads concurrently writing the same key), the following configuration option can be used:

<locking supportsConcurrentUpdates="true"/>

When enabled (default == true), the supportConcurrentUpdates adds internal support for concurrent writes:
a locking interceptor that would serialize writes to the same key and a delegation layer, that designates a
lock owner and uses it in order to coordinate the writes to a key.
More specific, when a thread running on node A writes on key k that mapps according to the consistent hash
to nodes {B, C}
(given numOwners==2):
A forwards (RPC) the write to the primary owner. The primary owner is the first node in the list of
owners, in our example B
B acquires a lock on k. Once the lock successfully acquired,_ _it forwards (RPC) the request to the
rest of owners (in this example C) that apply it locally
B applies the result locally, releases the lock and then it returns to A
Reasoning about the performance: in order to assure consistency under concurrent update, we do 2 RPCs:
from operation originator to main owner and from main owner to the rest of the owners. That's one more
than when supportConcurrentUpdates == false: in this case the operation originator does a single (multicast)
RPC to all the owners. This induces a performance cost and whenever one uses the cache in
non-concurrent manner, it is recommended that this configuration to be set to false in order to increase the
performance. When using Infinispan in client/server mode with a Hot Rod client, this would use the main
data owner in order to write data, so in this scenario there should not be any performance cost when
supporting concurrent updates.

JBoss Community Documentation

Page 126 of 617

Infinispan 6.0

3.18 Configuring Cache declaratively


One of the major goals of Infinispan is to aim for zero configuration. A simple XML configuration file
containing nothing more than a single infinispan element is enough to get you started. The configuration file
listed below provides sensible defaults and is perfectly valid.

<infinispan />

However, that would only give you the most basic, local mode, non-clustered cache. Non basic
configurations are very likely to use customized global and default cache elements.
Declarative configuration is the most common approach to configuring Infinispan cache instances. In order to
read XML configuration files one would typically construct an instance of CacheManager by pointing to an
XML file containing Infinispan configuration. Once configuration file is read you can obtain reference to the
default cache instance.

CacheManager manager = new DefaultCacheManager("my-config-file.xml");


Cache defaultCache = manager.getCache();

or any other named instance specified in "my-config-file.xml".

Cache someNamedCache = manager.getCache("someNamedCache");

Every time you define <namedCache> element in XML configuration file, in addition to <default> cache
element, you are effectively configuring additional caches whose settings are inheriting and/or overriding the
default cache.
Refer to Infinispan configuration reference for more details. If you are using XML editing tools for
configuration writing you can use provided Infinispan schema to assist you.

3.19 Configuration Migration Tools


Infinispan has a number of scripts for importing configurations from other cache products. Currently we have
scripts to import configurations from:
JBoss Cache 3.x
EHCache 1.x
Coherence 3.x
JBoss Cache 3.x itself supports configuration migration from previous (2.x) versions, so JBoss Cache 2.x
configurations can be migrated indirectly.

If you wish to help write conversion tools for other caching systems, please contact <a
href="https://lists.jboss.org/mailman/listinfo/infinispan-dev">infinispan-dev</a>.

JBoss Community Documentation

Page 127 of 617

Infinispan 6.0
There is a single scripts for importing configurations: ${INFINISPAN_HOME}/bin/importConfig.sh and an
equivalent .BAT script for Windows. Just run it and you should get a help message to assist you with the
import:

C:\infinispan\bin> importConfig.bat
Missing 'source', cannot proceed
Usage:
importConfig [-source <the file to be transformed>]
[-destination <where to store resulting XML>]
[-type <the type of the source, possible values being: [JBossCache3x, Ehcache1x, Coherence35x]
>]
C:\infinispan\bin>

Here is how a JBoss Cache 3.x configuration file is imported:

C:\infinispan\bin>importConfig.bat -source in\jbosscache_all.xml -destination out.xml -type


JBossCache3x
WARNING! Preload elements cannot be automatically transformed, please do it manually!
WARNING! Please configure cache loader props manually!
WARNING! Singleton store was changed and needs to be configured manually!
IMPORTANT: Please take a look at the generated file
for (possible) TODOs about the elements that couldn't be converted automatically!
--New configuration file [out.xml] successfully created.
--C:\infinispan\bin>

Please read all warning messages carefully and inspect the generated XML for potential TODO statements
that indicate the need for manual intervention. In the case of JBoss Cache 3.x this would usually have to do
with custom extensions, such as custom CacheLoaders that cannot be automatically migrated.
For EHCache and Coherence these may also contain suggestions and warnings for configuration options
that may not have direct equivalents in Infinispan.

JBoss Community Documentation

Page 128 of 617

Infinispan 6.0

3.20 Consistent Concurrent Updates With Hot Rod


Versioned Operations
Introduction
Data Consistency Problem
Peer-to-Peer Solution
Client-Server Solution

3.20.1 Introduction
Data structures, such as Infinispan Cache, that are accessed and modified concurrently can suffer from data
consistency issues unless there're mechanisms to guarantee data correctness. Infinispan Cache, since it
implements ConcurrentMap, provides operations such as conditional replace, putIfAbsent, and conditional
remove to its clients in order to guarantee data correctness. It even allows clients to operate against cache
instances within JTA transactions, hence providing the necessary data consistency guarantees.
However, when it comes to Hot Rod protocol backed servers, clients do not yet have the ability to start
remote transactions but they can call instead versioned operations to mimic the conditional methods
provided by the embedded Infinispan cache instance API. Let's look at a real example to understand how it
works.

3.20.2 Data Consistency Problem


Imagine you have two ATMs that connect using Hot Rod to a bank where an account's balance is stored.
Two closely followed operations to retrieve the latest balance could return 500 CHF (swiss francs) as shown
below:

Next a customer connects to the first ATM and requests 400 CHF to be retrieved. Based on the last value
read, the ATM could calculate what the new balance is, which is 100 CHF, and request a put with this new
value. Let's imagine now that around the same time another customer connects to the ATM and requests
200 CHF to be retrieved. Let's assume that the ATM thinks it has the latest balance and based on its
calculations it sets the new balance to 300 CHF:

JBoss Community Documentation

Page 129 of 617

Infinispan 6.0

Obviously, this would be wrong. Two concurrent updates have resulted in an incorrect account balance. The
second update should not have been allowed since the balance the second ATM had was incorrect. Even if
the ATM would have retrieved the balance before calculating the new balance, someone could have updated
between the new balance being retrieved and the update. Before finding out how to solve this issue in a
client-server scenario with Hot Rod, let's look at how this is solved when Infinispan clients run in peer-to-peer
mode where clients and Infinispan live within the same JVM.

Peer-to-Peer Solution
If the ATM and the Infinispan instance storing the bank account lived in the same JVM, the ATM could use
the conditional replace API referred at the beginning of this article. So, it could send the previous known
value to verify whether it has changed since it was last read. By doing so, the first operation could double
check that the balance is still 500 CHF when it was to update to 100 CHF. Now, when the second operation
comes, the current balance would not be 500 CHF any more and hence the conditional replace call would
fail, hence avoiding data consistency issues:

JBoss Community Documentation

Page 130 of 617

Infinispan 6.0

Client-Server Solution
In theory, Hot Rod could use the same p2p solution but sending the previous value would be not practical. In
this example, the previous value is just an integer but the value could be a lot bigger and hence forcing
clients to send it to the server would be rather wasteful. Instead, Hot Rod offers versioned operations to deal
with this situation.
Basically, together with each key/value pair, Hot Rod stores a version number which uniquely identifies each
modification. So, using an operation called getVersioned or getWithVersion, clients can retrieve not only the
value associated with a key, but also the current version. So, if we look at the previous example once again,
the ATMs could call getVersioned and get the balance's version:

When the ATMs wanted to modify the balance, instead of just calling put, they could call replaceIfUnmodified
operation passing the latest version number of which the clients are aware of. The operation will only
succeed if the version passed matches the version in the server. So, the first modification by the ATM would
be allowed since the client passes 1 as version and the server side version for the balance is also 1. On the
other hand, the second ATM would not be able to make the modification because after the first ATMs
modification the version would have been incremented to 2, and now the passed version (1) and the server
side version (2) would not match:

Finally, to find out how to call these operations from a Java environment, checkout the Java Hot Rod Client
article.

JBoss Community Documentation

Page 131 of 617

Infinispan 6.0

3.21 Cache Loaders and Stores


Introduction
Configuration
Cache Passivation
Cache Loader Behavior with Passivation Disabled vs Enabled
File system based cache loaders
JDBC based cache loaders
Which JDBC cache loader should I use?
Connection management (pooling)
Sample configurations
Cloud cache loader
Remote cache loader
Cassandra cache loader
Cluster cache loader
JPA cache store
Sample Usage
Configuration
Sample Programatic Configuration
Sample XML Configuration
Additional References
LevelDB cache store
Sample Usage
Configuration
Sample Programatic Configuration
Sample XML Configuration
Additional References
Cache Loaders and transactional caches
MongoDB cache loader

3.21.1 Introduction
Cache loader is Infinispan's connection to a (persistent) data store. Cache loader fetches data from a store
when that data is not in the cache, and when modifications are made to data in the cache the CacheLoader
is called to store those modifications back to the store. Cache loaders are associated with individual caches,
i.e. different caches from the same cache manager might have different cache store configurations.

3.21.2 Configuration
Cache loaders can be configured in a chain. Cache read operations will look at all of the cache loaders in the
order they've been configured until it finds a valid, non-null element of data. When performing writes all
cache loaders are written to except if the ignoreModifications element has been set to true for a specific
cache loader. See the configuration section below for details.

JBoss Community Documentation

Page 132 of 617

Infinispan 6.0

<loaders passivation="false" shared="false" preload="true">


<!-- We can have multiple cache loaders, which get chained -->
<fileStore
fetchPersistentState="true"
purgerThreads="3"
purgeSynchronously="true"
ignoreModifications="false"
purgeOnStartup="false"
location="${java.io.tmpdir}">
<async
enabled="true"
flushLockTimeout="15000"
threadPoolSize="5" />
<singletonStore
enabled="true"
pushStateWhenCoordinator="true"
pushStateTimeout="20000" />
</fileStore>
</loaders>

ConfigurationBuilder builder = new ConfigurationBuilder();


builder.loaders()
.passivation(false)
.shared(false)
.preload(true)
.addFileCacheStore()
.fetchPersistentState(true)
.purgerThreads(3)
.purgeSynchronously(true)
.ignoreModifications(false)
.purgeOnStartup(false)
.location(System.getProperty("java.io.tmpdir"))
.async()
.enabled(true)
.flushLockTimeout(15000)
.threadPoolSize(5)
.singletonStore()
.enabled(true)
.pushStateWhenCoordinator(true)
.pushStateTimeout(20000);

passivation (false by default) has a significant impact on how Infinispan interacts with the loaders, and
is discussed in the next paragraph.
shared (false by default) indicates that the cache loader is shared among different cache instances,
for example where all instances in a cluster use the same JDBC settings to talk to the same remote,
shared database. Setting this to true prevents repeated and unnecessary writes of the same data to
the cache loader by different cache instances.

JBoss Community Documentation

Page 133 of 617

Infinispan 6.0
preload (false by default) if true, when the cache starts, data stored in the cache loader will be
pre-loaded into memory. This is particularly useful when data in the cache loader is needed
immediately after startup and you want to avoid cache operations being delayed as a result of loading
this data lazily. Can be used to provide a 'warm-cache' on startup, however there is a performance
penalty as startup time is affected by this process. Note that preloading is done in a local fashion, so
any data loaded is only stored locally in the node. No replication or distribution of the preloaded data
happens. Also, Infinispan only preloads up to the maximum configured number of entries in eviction.
class attribute (mandatory) defines the class of the cache loader implementation.
fetchPersistentState (false by default) determines whether or not to fetch the persistent state of a
cache when joining a cluster. The aim here is to take the persistent state of a cache and apply it to the
local cache store of the joining node. Hence, if cache store is configured to be shared, since caches
access the same cache store, fetch persistent state is ignored. Only one configured cache loader may
set this property to true; if more than one cache loader does so, a configuration exception will be
thrown when starting your cache service.
purgeSynchronously will control whether the expiration takes place in the eviction thread, i.e. if
purgeSynchronously (false by default) is set to true, the eviction thread will block until the purging is
finished, otherwise would return immediately. If the cache loader supports multi-threaded purge then
purgeThreads (1 by default) are used for purging expired entries. There are cache loaders that
support multi-threaded purge (e.g. FileCacheStore) and caches that don't (e.g. JDBCCacheStore);
check the actual cache loader configuration in order to see that.
ignoreModifications(false by default) determines whether write methods are pushed down to the
specific cache loader. Situations may arise where transient application data should only reside in a file
based cache loader on the same server as the in-memory cache, for example, with a further JDBC
based cache loader used by all servers in the network. This feature allows you to write to the 'local'
file cache loader but not the shared JDBCCacheLoader.
purgeOnStatup empties the specified cache loader (if ignoreModifications is false) when the cache
loader starts up.
additional attributes configure aspects specific to each cache loader, e.g. the location attribute in the
previous example refers to where the FileCacheStore will keep the files that contain data. Other
loaders, with more complex configuration, also introduce additional sub-elements to the basic
configuration. See for example the JDBC cache store configuration examples below
singletonStore (default for enabled is false) element enables modifications to be stored by only one
node in the cluster, the coordinator. Essentially, whenever any data comes in to some node it is
always replicated(or distributed) so as to keep the caches in-memory states in sync; the coordinator,
though, has the sole responsibility of pushing that state to disk. This functionality can be activated
setting the enabled attribute to true in all nodes, but again only the coordinator of the cluster will the
modifications in the underlying cache loader as defined in loader element. You cannot define a shared
and with singletonStore enabled at the same time.
pushStateWhenCoordinator (true by default) If true, when a node becomes the coordinator, it will
transfer in-memory state to the underlying cache loader. This can be very useful in situations where
the coordinator crashes and the new coordinator is elected.
async element has to do with cache store persisting data (a)synchronously to the actual store. It is
discussed in detail here.

JBoss Community Documentation

Page 134 of 617

Infinispan 6.0

3.21.3 Cache Passivation


A cache loader can be used to enforce entry passivation and activation on eviction in a cache. Cache
passivation is the process of removing an object from in-memory cache and writing it to a secondary data
store (e.g., file system, database) on eviction. Cache Activation is the process of restoring an object from the
data store into the in-memory cache when it's needed to be used. In both cases, the configured cache loader
will be used to read from the data store and write to the data store.
When an eviction policy in effect evicts an entry from the cache, if passivation is enabled, a notification that
the entry is being passivated will be emitted to the cache listeners and the entry will be stored. When a user
attempts to retrieve a entry that was evicted earlier, the entry is (lazily) loaded from the cache loader into
memory. When the entry and its children have been loaded, they're removed from the cache loader and a
notification is emitted to the cache listeners that the entry has been activated. In order to enable passivation
just set passivation to true (false by default). When passivation is used, only the first cache loader configured
is used and all others are ignored.

JBoss Community Documentation

Page 135 of 617

Infinispan 6.0

Cache Loader Behavior with Passivation Disabled vs Enabled


When passivation is disabled, whenever an element is modified, added or removed, then that modification is
persisted in the backend store via the cache loader. There is no direct relationship between eviction and
cache loading. If you don't use eviction, what's in the persistent store is basically a copy of what's in memory.
If you do use eviction, what's in the persistent store is basically a superset of what's in memory (i.e. it
includes entries that have been evicted from memory). When passivation is enabled, there is a direct
relationship between eviction and the cache loader. Writes to the persistent store via the cache loader only
occur as part of the eviction process. Data is deleted from the persistent store when the application reads it
back into memory. In this case, what's in memory and what's in the persistent store are two subsets of the
total information set, with no intersection between the subsets. Following is a simple example, showing what
state is in RAM and in the persistent store after each step of a 6 step process:
1. Insert keyOne
2. Insert keyTwo
3. Eviction thread runs, evicts keyOne
4. Read keyOne
5. Eviction thread runs, evicts keyTwo
6. Remove keyTwo
When passivation is disabled :
1. Memory: keyOne Disk: keyOne
2. Memory: keyOne, keyTwo Disk: keyOne, keyTwo
3. Memory: keyTwo Disk: keyOne, keyTwo
4. Memory: keyOne, keyTwo Disk: keyOne, keyTwo
5. Memory: keyOne Disk: keyOne, keyTwo
6. Memory: keyOne Disk: keyOne
When passivation is enabled :
1. Memory: keyOne Disk:
2. Memory: keyOne, keyTwo Disk:
3. Memory: keyTwo Disk: keyOne
4. Memory: keyOne, keyTwo Disk:
5. Memory: keyOne Disk: keyTwo
6. Memory: keyOne Disk:

JBoss Community Documentation

Page 136 of 617

Infinispan 6.0

3.21.4 File system based cache loaders


Infinispan ships with several cache loaders that utilize the file system as a data store. They all require a
location attribute, which maps to a directory to be used as a persistent store. (e.g.,
location="/tmp/myDataStore" ).
FileCacheStore: a simple filesystem-based implementation. Usage on shared filesystems like NFS,
Windows shares, etc. should be avoided as these do not implement proper file locking and can cause
data corruption. File systems are inherently not transactional, so when attempting to use your cache
in a transactional context, failures when writing to the file (which happens during the commit phase)
cannot be recovered. Please visit the file cache store configuration documentation for more
information on the configurable parameters of this store.
BdbjeCacheStore: a cache loader implementation based on the Oracle/Sleepycat's BerkeleyDB Java
Edition.
JdbmCacheStore: a cache loader implementation based on the JDBM engine, a fast and free
alternative to BerkeleyDB.
LevelDBCacheStore: a cache store implementation based on Google's LevelDB, a fast key-value
store.
SingleFileCacheStore: starting with Infinispan 6.0, a brand new filesystem-based cache store
implementation has been created that requires no extra dependencies. The reason this brand new file
based cache store has been created is because FileCacheStore didn't perform as expected, and it
also caused issues due to the number of files created. This brand new single-file based cache store
vastly outperforms the existing FileCacheStore and in some cases, particularly when reading from the
store, it even outperforms the LevelDB based cache store. One key aspect of this cache store is that
it keeps keys in-memory along with the information where the value is located in the file. This offers
great speed improvements but results in extra memory consumption. To limit this, the cache store's
maximum size can be set, but this will only work as expected in a very limited set of use cases. For
more detailed information, check the single-file cache store configuration javadoc.
Note that the BerkeleyDB implementation requires a commercial license if distributed with an application
(see http://www.oracle.com/database/berkeley-db/index.html for details).
For detailed description of all the parameters supported by the stores, please consult the javadoc.

3.21.5 JDBC based cache loaders


Based on the type of keys to be persisted, there are three JDBC cache loaders:

JBoss Community Documentation

Page 137 of 617

Infinispan 6.0

JdbcBinaryCacheStore - can store any type of keys. It stores all the keys that have the same hash
value (hashCode method on key) in the same table row/blob, having as primary key the hash value.
While this offers great flexibility (can store any key type), it impacts concurrency/throughput. E.g. If
storing k1,k2 and k3 keys, and keys had same hash code, then they'd persisted in the same table
row. Now, if 3 threads try to concurrently update k1, k2 and k3 respectively, they would need to do it
sequentially since these threads would be updating the same row.
JdbcStringBasedCacheStore - stores each key in its own row, increasing throughput under concurrent
load. In order to store each key in its own column, it relies on a (pluggable) bijection that maps the
each key to a String object. The bijection is defined by the Key2StringMapper interface. Infinispans
ships a default implementation (smartly named DefaultKey2StringMapper) that knows how to handle
primitive types.
JdbcMixedCacheStore - it is a hybrid implementation that, based on the key type, delegates to either
JdbcBinaryCacheStore or JdbcStringBasedCacheStore.

Which JDBC cache loader should I use?


It is generally preferable to use JdbcStringBasedCacheStore when you are in control of the key types, as it
offers better throughput under heavy load. One scenario in which it is not possible to use it though, is when
you can't write an Key2StringMapper to map the keys to to string objects (e.g. when you don't have control
over the types of the keys, for whatever reason). Then you should use either JdbcBinaryCacheStore or
JdbcMixedCacheStore. The later is preferred to the former when the majority of the keys are handled by
JdbcStringBasedCacheStore, but you still have some keys you cannot convert through Key2StringMapper.

Connection management (pooling)


In order to obtain a connection to the database all the JDBC cache loaders rely on an ConnectionFactory
implementation. The connection factory is specified programmatically using one of the connectionPool(),
dataSource() or simpleConnection() methods on the JdbcBinaryCacheStoreConfigurationBuilder class or
declaratively using one of the <connectionPool />, <dataSource /> or <simpleConnection /> elements.
Infinispan ships with three ConnectionFactory implementations:
PooledConnectionFactory is a factory based on C3P0. Refer to javadoc for details on configuring it.
ManagedConnectionFactory is a connection factory that can be used within managed environments,
such as application servers. It knows how to look into the JNDI tree at a certain location (configurable)
and delegate connection management to the DataSource. Refer to javadoc javadoc for details on how
this can be configured.
SimpleConnectionFactory is a factory implementation that will create database connection on a per
invocation basis. Not recommended in production.
The PooledConnectionFactory is generally recommended for stand-alone deployments (i.e. not running
within AS or servlet container). ManagedConnectionFactory can be used when running in a managed
environment where a DataSource is present, so that connection pooling is performed within the DataSource.

JBoss Community Documentation

Page 138 of 617

Infinispan 6.0

Sample configurations
Bellow is an sample configuration for the JdbcBinaryCacheStore. For detailed description of all the
parameters used refer to the javadoc. Please note the use of multiple XML schemas, since each cachestore
has its own schema.

<?xml version="1.0" encoding="UTF-8"?>


<infinispan
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="urn:infinispan:config:5.2
http://www.infinispan.org/schemas/infinispan-config-5.2.xsd
urn:infinispan:config:jdbc:5.2
http://www.infinispan.org/schemas/infinispan-cachestore-jdbc-config-5.2.xsd"
xmlns="urn:infinispan:config:5.2"
xmlns:jdbc="urn:infinispan:config:jdbc:5.2" >
<loaders>
<binaryKeyedJdbcStore xmlns="urn:infinispan:config:jdbc:5.2"
fetchPersistentState="false"ignoreModifications="false" purgeOnStartup="false">
<connectionPool connectionUrl="jdbc:h2:mem:infinispan_binary_based;DB_CLOSE_DELAY=-1"
username="sa" driverClass="org.h2.Driver"/>
<binaryKeyedTable dropOnExit="true" createOnStart="true" prefix="ISPN_BUCKET_TABLE">
<idColumn name="ID_COLUMN" type="VARCHAR(255)" />
<dataColumn name="DATA_COLUMN" type="BINARY" />
<timestampColumn name="TIMESTAMP_COLUMN" type="BIGINT" />
</binaryKeyedTable>
</binaryKeyedJdbcStore>
</loaders>
:
</infinispan>

ConfigurationBuilder builder = new ConfigurationBuilder();


builder.loaders()
.addLoader(JdbcBinaryCacheStoreConfigurationBuilder.class)
.fetchPersistentState(false)
.ignoreModifications(false)
.purgeOnStartup(false)
.table()
.dropOnExit(true)
.createOnStart(true)
.tableNamePrefix("ISPN_BUCKET_TABLE")
.idColumnName("ID_COLUMN").idColumnType("VARCHAR(255)")
.dataColumnName("DATA_COLUMN").dataColumnType("BINARY")
.timestampColumnName("TIMESTAMP_COLUMN").timestampColumnType("BIGINT")
.connectionPool()
.connectionUrl("jdbc:h2:mem:infinispan_binary_based;DB_CLOSE_DELAY=-1")
.username("sa")
.driverClass("org.h2.Driver");

JBoss Community Documentation

Page 139 of 617

Infinispan 6.0
Bellow is an sample configuration for the JdbcStringBasedCacheStore. For detailed description of all the
parameters used refer to the javadoc.

<loaders>
<stringKeyedJdbcStore xmlns="urn:infinispan:config:jdbc:5.2" fetchPersistentState="false"
ignoreModifications="false" purgeOnStartup="false">
<connectionPool connectionUrl="jdbc:h2:mem:infinispan_binary_based;DB_CLOSE_DELAY=-1"
username="sa" driverClass="org.h2.Driver"/>
<stringKeyedTable dropOnExit="true" createOnStart="true" prefix="ISPN_STRING_TABLE">
<idColumn name="ID_COLUMN" type="VARCHAR(255)" />
<dataColumn name="DATA_COLUMN" type="BINARY" />
<timestampColumn name="TIMESTAMP_COLUMN" type="BIGINT" />
</stringKeyedTable>
</stringKeyedJdbcStore>
</loaders>

ConfigurationBuilder builder = new ConfigurationBuilder();


builder.loaders().addLoader(JdbcStringBasedCacheStoreConfigurationBuilder.class)
.fetchPersistentState(false)
.ignoreModifications(false)
.purgeOnStartup(false)
.table()
.dropOnExit(true)
.createOnStart(true)
.tableNamePrefix("ISPN_STRING_TABLE")
.idColumnName("ID_COLUMN").idColumnType("VARCHAR(255)")
.dataColumnName("DATA_COLUMN").dataColumnType("BINARY")
.timestampColumnName("TIMESTAMP_COLUMN").timestampColumnType("BIGINT")
.connectionPool()
.connectionUrl("jdbc:h2:mem:infinispan_binary_based;DB_CLOSE_DELAY=-1")
.username("sa")
.driverClass("org.h2.Driver");

Bellow is an sample configuration for the JdbcMixedCacheStore. For detailed description of all the
parameters used refer to the javadoc.

JBoss Community Documentation

Page 140 of 617

Infinispan 6.0

<loaders>
<mixedKeyedJdbcStore xmlns="urn:infinispan:config:jdbc:5.2" fetchPersistentState="false"
ignoreModifications="false" purgeOnStartup="false">
<connectionPool connectionUrl="jdbc:h2:mem:infinispan_binary_based;DB_CLOSE_DELAY=-1"
username="sa" driverClass="org.h2.Driver" />
<stringKeyedTable dropOnExit="true" createOnStart="true" prefix="ISPN_MIXED_STR_TABLE">
<idColumn name="ID_COLUMN" type="VARCHAR(255)" />
<dataColumn name="DATA_COLUMN" type="BINARY" />
<timestampColumn name="TIMESTAMP_COLUMN" type="BIGINT" />
</stringKeyedTable>
<binaryKeyedTable dropOnExit="true" createOnStart="true" prefix="ISPN_MIXED_BINARY_TABLE">
<idColumn name="ID_COLUMN" type="VARCHAR(255)" />
<dataColumn name="DATA_COLUMN" type="BINARY" />
<timestampColumn name="TIMESTAMP_COLUMN" type="BIGINT" />
</binaryKeyedTable>
</loader>
</loaders>

ConfigurationBuilder builder = new ConfigurationBuilder();


builder.loaders().addLoader(JdbcMixedCacheStoreConfigurationBuilder.class)
.fetchPersistentState(false).ignoreModifications(false).purgeOnStartup(false)
.stringTable()
.dropOnExit(true)
.createOnStart(true)
.tableNamePrefix("ISPN_MIXED_STR_TABLE")
.idColumnName("ID_COLUMN").idColumnType("VARCHAR(255)")
.dataColumnName("DATA_COLUMN").dataColumnType("BINARY")
.timestampColumnName("TIMESTAMP_COLUMN").timestampColumnType("BIGINT")
.binaryTable()
.dropOnExit(true)
.createOnStart(true)
.tableNamePrefix("ISPN_MIXED_BINARY_TABLE")
.idColumnName("ID_COLUMN").idColumnType("VARCHAR(255)")
.dataColumnName("DATA_COLUMN").dataColumnType("BINARY")
.timestampColumnName("TIMESTAMP_COLUMN").timestampColumnType("BIGINT")
.connectionPool()
.connectionUrl("jdbc:h2:mem:infinispan_binary_based;DB_CLOSE_DELAY=-1")
.username("sa")
.driverClass("org.h2.Driver");

Finally, below is an example of a JDBC cache store with a managed connection factory, which is chosen
implicitly by specifying a datasource JNDI location:

<stringKeyedJdbcStore xmlns="urn:infinispan:config:jdbc:5.2" fetchPersistentState="false"


ignoreModifications="false" purgeOnStartup="false">
<dataSource jndiUrl="java:/StringStoreWithManagedConnectionTest/DS" />
<stringKeyedTable dropOnExit="true" createOnStart="true" prefix="ISPN_STRING_TABLE">
<idColumn name="ID_COLUMN" type="VARCHAR(255)" />
<dataColumn name="DATA_COLUMN" type="BINARY" />
<timestampColumn name="TIMESTAMP_COLUMN" type="BIGINT" />
</stringKeyedTable>
</stringKeyedJdbcStore>

JBoss Community Documentation

Page 141 of 617

Infinispan 6.0

ConfigurationBuilder builder = new ConfigurationBuilder();


builder.loaders().addLoader(JdbcStringBasedCacheStoreConfigurationBuilder.class)
.fetchPersistentState(false).ignoreModifications(false).purgeOnStartup(false)
.table()
.dropOnExit(true)
.createOnStart(true)
.tableNamePrefix("ISPN_STRING_TABLE")
.idColumnName("ID_COLUMN").idColumnType("VARCHAR(255)")
.dataColumnName("DATA_COLUMN").dataColumnType("BINARY")
.timestampColumnName("TIMESTAMP_COLUMN").timestampColumnType("BIGINT")
.dataSource()
.jndiUrl("java:/StringStoreWithManagedConnectionTest/DS");

Apache Derby users


If you're connecting to an Apache Derby database, make sure you set dataColumnType to BLOB:

<dataColumn name="DATA_COLUMN" type="BLOB"/>

3.21.6 Cloud cache loader


The CloudCacheStore implementation utilizes JClouds to communicate with cloud storage providers such as
Amazon's S3, Rackspace's Cloudfiles or any other such provider supported by JClouds. If you're planning to
use Amazon S3 for storage, consider using it with Infinispan. Infinispan itself provides in-memory caching for
your data to minimize the amount of remote access calls, thus reducing the latency and cost of fetching your
Amazon S3 data. With cache replication, you are also able to load data from your local cluster without
having to remotely access it every time. Note that Amazon S3 does not support transactions. If transactions
are used in your application then there is some possibility of state inconsistency when using this cache
loader. However, writes are atomic, in that if a write fails nothing is considered written and data is never
corrupted. For a list of configuration refer to the javadoc.

3.21.7 Remote cache loader


The RemoteCacheStore is a cache loader implementation that stores data in a remote infinispan cluster. In
order to communicate with the remote cluster, the RemoteCacheStore uses the HotRod client/server
architecture. HotRod bering the load balancing and fault tolerance of calls and the possibility to fine-tune the
connection between the RemoteCacheStore and the actual cluster. Please refer to HotRod for more
information on the protocol, client and server configuration. For a list of RemoteCacheStore configuration
refer to the javadoc. Example:

JBoss Community Documentation

Page 142 of 617

Infinispan 6.0

<?xml version="1.0" encoding="UTF-8"?>


<infinispan
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="urn:infinispan:config:5.2
http://www.infinispan.org/schemas/infinispan-config-5.2.xsd
urn:infinispan:config:remote:5.2
http://www.infinispan.org/schemas/infinispan-cachestore-remote-config-5.2.xsd"
xmlns="urn:infinispan:config:5.2"
xmlns:remote="urn:infinispan:config:remote:5.2" >
:
<loaders>
<remoteStore xmlns="urn:infinispan:config:remote:5.2" fetchPersistentState="false"
ignoreModifications="false" purgeOnStartup="false" remoteCache="mycache"
rawValues="true">
<servers>
<server host="one" port="12111"/>
<server host="two" />
</servers>
<connectionPool maxActive="10" exhaustedAction="CREATE_NEW" />
<async enabled="true" />
</remoteStore>
</loaders>
:
</infinispan>

ConfigurationBuilder b = new ConfigurationBuilder();


b.loaders().addStore(RemoteCacheStoreConfigurationBuilder.class)
.fetchPersistentState(false)
.ignoreModifications(false)
.purgeOnStartup(false)
.remoteCacheName("mycache")
.rawValues(true)
.addServer()
.host("one").port(12111)
.addServer()
.host("two")
.connectionPool()
.maxActive(10)
.exhaustedAction(ExhaustedAction.CREATE_NEW)
.async().enable();

In this sample configuration, the remote cache store is configured to use the remote cache named
"mycache" on servers "one" and "two". It also configures connection pooling and provides a custom transport
executor. Additionally the cache store is asynchronous.

JBoss Community Documentation

Page 143 of 617

Infinispan 6.0

3.21.8 Cassandra cache loader


The CassandraCacheStore was introduced in Infinispan 4.2. Read the specific page for details on
implementation and configuration.

3.21.9 Cluster cache loader


The ClusterCacheLoader is a cache loader implementation that retrieves data from other cluster members.
It is a cache loader only as it doesn't persist anything (it is not a Store), therefore features like
fetchPersistentState (and like) are not applicable.
A cluster cache loader can be used as a non-blocking (partial) alternative to stateTransfer : keys not already
available in the local node are fetched on-demand from other nodes in the cluster. This is a kind of
lazy-loading of the cache content.

<loaders>
<clusterLoader remoteCallTimeout="500" />
</loaders>

ConfigurationBuilder b = new ConfigurationBuilder();


b.loaders()
.addClusterCacheLoader()
.remoteCallTimeout(500);

For a list of ClusterCacheLoader configuration refer to the javadoc.


Note: The ClusterCacheLoader does not support preloading(preload=true). It also won't provide state if
fetchPersistentSate=true.

3.21.10 JPA cache store


The implementation depends on JPA 2.0 specification to access entity meta model.
In normal use cases, it's recommended to leverage Infinispan for JPA second level cache and/or query
cache. However, if you'd like to use only Infinispan API and you want Infinispan to persist into a cache store
using a common format (e.g., a database with well defined schema), then JPA Cache Store could be right
for you.
When using JPA Cache Store, the key should be the ID of the entity, while the value should be the entity
object. Only a single @Id or @EmbeddedId annotated property is allowed. Auto-generated ID is not
supported. Lastly, all entries will be stored as immortal entries.

JBoss Community Documentation

Page 144 of 617

Infinispan 6.0

Sample Usage
For example, given a persistence unit "myPersistenceUnit", and a JPA entity User:
persistence.xml

<persistence-unit name="myPersistenceUnit">
...
</persistence-unit>

User entity class (see test for full example)

@Entity
public class User implements Serializable {
@Id
private String username;
private String firstName;
private String lastName;
...
}

Then you can configure a cache "usersCache" to use JPA Cache Store, so that when you put data into the
cache, the data would be persisted into the database based on JPA configuration.

EmbeddedCacheManager cacheManager = ...;

Configuration cacheConfig = new ConfigurationBuilder().loaders()


.addLoader(JpaCacheStoreConfigurationBuilder.class)
.persistenceUnitName("myPersistenceUnit")
.entityClass(User.class)
.build();
cacheManager.defineCache("usersCache", cacheConfig);
Cache<String, User> usersCache = cacheManager.getCache("usersCache");
usersCache.put("raytsang", new User(...));

Normally a single Infinispan cache can store multiple types of key/value pairs, for example:

Cache<String, User> usersCache = cacheManager.getCache("myCache");


usersCache.put("raytsang", new User());
Cache<Integer, Teacher> teachersCache = cacheManager.getCache("myCache");
teachersCache.put(1, new Teacher());

It's important to note that, when a cache is configured to use a JPA Cache Store, that cache would only be
able to store ONE type of data.

JBoss Community Documentation

Page 145 of 617

Infinispan 6.0

Cache<String, User> usersCache = cacheManager.getCache("myJPACache"); // configured for User


entity class
usersCache.put("raytsang", new User());
Cache<Integer, Teacher> teachersCache = cacheManager.getCache("myJPACache"); // cannot do this
when this cache is configured to use a JPA cache store
teachersCache.put(1, new Teacher());

Use of @EmbeddedId is supported so that you can also use composite keys (see the test code for full
example).

@Entity
public class Vehicle implements Serializable {
@EmbeddedId
private VehicleId id;
private String color; ...
}
@Embeddable
public class VehicleId implements Serializable
{
private String state;
private String licensePlate;
...
}

Lastly, auto-generated IDs (e.g., @GeneratedValue) is not supported. When putting things into the cache
with a JPA cache store, the key should be the ID value!

JBoss Community Documentation

Page 146 of 617

Infinispan 6.0

Configuration
Sample Programatic Configuration
Configuration cacheConfig = new ConfigurationBuilder().loaders()
.addLoader(JpaCacheStoreConfigurationBuilder.class)
.persistenceUnitName("org.infinispan.loaders.jpa.configurationTest")
.entityClass(User.class)
.build();

Parameter

Description

persistenceUnitName JPA persistence unit name in JPA configuration (persistence.xml) that contains the
JPA entity class
entityClass

JPA entity class that is expected to be stored in this cache. Only one class is
allowed.

Sample XML Configuration


<namedCache name="vehicleCache">
<loaders passivation="false" shared="true" preload="true">
<jpaStore
persistenceUnitName="org.infinispan.loaders.jpa.configurationTest"
entityClassName="org.infinispan.loaders.jpa.entity.User"
/>
</loaders>
</namedCache>

Parameter

Description

persistenceUnitName JPA persistence unit name in JPA configuration (persistence.xml) that contains the
JPA entity class
entityClassName

Fully qualified JPA entity class name that is expected to be stored in this cache.
Only one class is allowed.

Additional References
Refer to the test case for code samples in action.
Refer to test configurations for configuration samples.

JBoss Community Documentation

Page 147 of 617

Infinispan 6.0

3.21.11 LevelDB cache store


LevelDB is a fast key-value filesystem-based storage written at Google. LevelDB cache store currently uses
a Java implementation. It may be possible to use a JNI implementation in the future.

Sample Usage
LevelDB cache store requires 2 filesystem directories to be configured - each directory for a LevelDB
database. One location is used to store non-expired data, while the second location is used to store expired
keys pending purge.
EmbeddedCacheManager cacheManager = ...;

Configuration cacheConfig = new ConfigurationBuilder().loaders()


.addLoader(LevelDBCacheStoreConfigurationBuilder.class)
.build();
cacheManager.defineCache("usersCache", cacheConfig);
Cache<String, User> usersCache = cacheManager.getCache("usersCache");
usersCache.put("raytsang", new User(...));

JBoss Community Documentation

Page 148 of 617

Infinispan 6.0

Configuration
Sample Programatic Configuration
Configuration cacheConfig = new ConfigurationBuilder().loaders()
.addLoader(LevelDBCacheStoreConfigurationBuilder.class)
.location("/tmp/leveldb/data")
.expiredLocation("/tmp/leveldb/expired")
.entityClass(User.class)
.build();

Parameter

Description

location

Directory to use for LevelDB to store primary cache store data. Directory will be
auto-created if it does not exit.

expiredLocation

Directory to use for LevelDB to store expiring data pending to be purged permanently.
Directory will be auto-created if it does not exit.

expiryQueueSize

Size of the in-memory queue to hold expiring entries before it gets flushed into expired
LevelDB store

clearThreshold

There are two methods to clear all entries in LevelDB. One method is to iterate through
all entries and remove each entry individually. The other method is to delete the
database and re-init. For smaller databases, deleting individual entries is faster than
the latter method. This configuration sets the max number of entries allowed before
using the latter method

compressionType Configuration for LevelDB for data compression, see CompressionType enum for
options
blockSize

Configuration for LevelDB - see documentation for performance tuning

cacheSize

Configuration for LevelDB - see documentation for performance tuning

Sample XML Configuration


<namedCache name="vehicleCache">
<loaders passivation="false" shared="true" preload="true">
<leveldbStore
location="/tmp/leveldb/data"
expiredLocation="/tmp/leveldb/expired"
/>
</loaders>
</namedCache>

JBoss Community Documentation

Page 149 of 617

Infinispan 6.0

Additional References
Refer to the test case for code samples in action.
Refer to test configurations for configuration samples.

3.21.12 Cache Loaders and transactional caches


When a cache is transactional and a cache loader is present, the cache loader won't be enlisted in the
transaction in which the cache is part. That means that it is possible to have inconsistencies at cache loader
level: the transaction to succeed applying the in-memory state but (partially) fail applying the changes to the
store. Manual recovery would not work with caches stores.

3.21.13 MongoDB cache loader


The MongoDB cachestore is released within the 5.3 version of Infinispan aka "Tactical Nuclear Penguin".
To communicate with the MongoDB server instance, we are using the official Java driver version 2.10.1
To configure the cachestore, you just need to add a new entry into the loaders section.
Here is an example for your xml configuration file:

<loaders>
<mongodbStore xmlns="urn:infinispan:config:mongodb:5.3" >
<connection host="localhost" port="27017" timeout="2000" acknowledgment="0"/>
<authentication username="mongoUser" password="mongoPass" />
<storage database="infinispan_test_database" collection="infispan_cachestore" />
</mongodbStore>
</loaders>

If you prefer the programmatic API here is a snippet:

ConfigurationBuilder b = new ConfigurationBuilder();


b.loaders().addStore(MongoDBCacheStoreConfigurationBuilder.class)
.host( "localhost" )
.port( 27017 )
.timeout( 1500 )
.acknowledgment( 0 )
.username( "mongoDBUSer" )
.password( "mongoBDPassword" )
.database( "infinispan_cachestore" )
.collection( "indexes" );
final Configuration config = b.build();
MongoDBCacheStoreConfiguration store = (MongoDBCacheStoreConfiguration)
config.loaders().cacheLoaders().get(0);

JBoss Community Documentation

Page 150 of 617

Infinispan 6.0
The connection section contains the connection information to connect to the MongoDB server instance.
The authentication section is optional, it allows you to specificy username and password if you are using
some.
The storage section explicits where you will store the data.
Section

property

usage

default
value

connection
host

The hostname of the server on which the MongoDB is

localhost

running
port

The port used by the MongoDB server instance.

27017

timeout

The timeout used by the MongoDB driver at the connection. 2000


(in ms)

acknoledgement The value used to configure the acknowledgment for write

operation (-1 / 0 / 1 / 2+)


authentication
username

The username used for the authentication with the


MongoDB server.

password

The password used for the authentication with the


MongoDB server.

storage
database

The database used to store elements.

collection

The collection which will contain the elements.

For more information about the configuration property usage, you can refer to the official MongoDB java
driver documentation

3.22 Portable Serialization For Hot Rod With Apache


Avro
Introduction
Languages Supported
Object Types Supported
Java Configuration

JBoss Community Documentation

Page 151 of 617

Infinispan 6.0

3.22.1 Introduction
Starting with Infinispan 5.0, Hot Rod clients can be configured with a marshaller that produces plattform
independent payloads using Apache Avro. This means that payloads generated by a Java, Avro-based,
marshaller could be read by a Python, Avro-based, marshaller. When Hot Rod clients in other languages
such as Python or Ruby become available, this will mean that for example, data stored via Java Hot Rod
client will be readable by a Python Hot Rod client.

3.22.2 Languages Supported


Avro currently supports providing portable serialization payloads for the following languages:
C
C++
Java
Python
Ruby
So interoperability of payloads is limited to these languages. The choice of Avro over other existing portable
serialization libraries (i.e. Google Protocol Buffers, Apache Thrift, MessagePack...etc) was done based
languages supported, ease of use, and payload size.

JBoss Community Documentation

Page 152 of 617

Infinispan 6.0

3.22.3 Object Types Supported


Avro based marshaller currently supports basic type and collection marshalling:
Basic types include:
UTF-8 string
Integer
Long
Float
Double
Boolean
Byte Array
Collections composed of the basic types :
Arrays
Lists
Maps
Sets
Marshalling of complex objects is not supported because it's not fully solvable as some language don't
support some concepts other languages offer. Instead, it is recommended that for any complex object
marshalling requirements, users serialize these complex objects into byte arrays using portable serialization
libraries such as Google Protocol Buffers, Apache Thrift, MessagePack, or Apache Avro. Once the byte
array has been created, simply pass it to the Hot Rod client API which will handle it accordingly.
Therefore, it's clear that users are free to use any portable serialization library to transform their complex
objects into byte arrays, regardless of the fact that Infinispan uses Apache Avro for basic type and collection
marshalling. The only limitation here is that the target language used to serialize complex objects needs to
be amongst the languages that Apache Avro supports.
Short and Byte Java primitive types are not supported per se. Instead, clients should pass integers which will
be encoded efficiently using variable-length zig zag coding. Primitive arrays not supported except byte
arrays. Instead, use their object counter partners, i.e. Integer...etc.

JBoss Community Documentation

Page 153 of 617

Infinispan 6.0

3.22.4 Java Configuration


To configure a Java Hot Rod client with Avro marshaller, simply pass a
infinispan.client.hotrod.marshaller property to the RemoteCacheManager constructor
containing the value of org.infinispan.client.hotrod.marshall.ApacheAvroMarshaller. For
example:

Properties props = new Properties();


props.put("infinispan.client.hotrod.marshaller",
"org.infinispan.client.hotrod.marshall.ApacheAvroMarshaller");
RemoteCacheManager remoteCacheManager = new RemoteCacheManager(props);

Note however that if all you're gonna be using are Java Hot Rod clients, there's no need to configure Avro
based marshaller. The default marshaller is capable of transforming any Serializable or Externalizable java
object into a byte array in a quick and efficient manner.
Please remember as well that when remote java clients are configured with the apache avro marshaller, the
server's marshaller does not need changing. This is because the server does not make any attempt at
unmarshalling the data that's been passed to it. Internally, it keeps the data as byte arrays.

3.23 The Grouping API


In some cases you may wish to co-locate a group of entries onto a particular node. In this, the group API will
be useful for you.

3.23.1 How does it work?


Infinispan allocates each node a portion of the total hash space. Normally, when you store an entry,
Infinispan will take a hash of the key, and store the entry on the node which owns that portion of the hash
space. Infinispan always uses an algorithm to locate a key in the hash space, never allowing the node on
which the entry is stored to be specified manually. This scheme allows any node to know which nodes owns
a key, without having to distribute such ownership information. This reduces the overhead of Infinispan, but
more importantly improves redundancy as there is no need to replicate the ownership information in case of
node failure.
If you use the grouping API , then Infinispan will ignore the hash of the key when deciding which node to
store the entry on, and instead use a hash of the group. Infinispan still uses the hash of the key to store the
entry on a node. When the group API is in use, it is important that every node can still compute, using an
algorithm, the owner of every key. For this reason, the group cannot be specified manually. The group can
either be intrinsic to the entry (generated by the key class) or extrinsic (generated by an external function).

JBoss Community Documentation

Page 154 of 617

Infinispan 6.0

3.23.2 How do I use the grouping API?


First, you must enable groups. If you are configuring Infinispan programmatically, then call:

Configuration c = new ConfigurationBuilder().clustering().hash().groups().enabled().build();

Or, if you are using XML:

<clustering>
<hash>
<groups enabled="true" />
</hash>
</clustering>

If you have control of the key class (you can alter the class definition, it's not part of an unmodifiable library),
and the determination of the group is not an orthogonal concern to the key class, then we recommend you
use an intrinsic group. The intrinsic group can be specified using the @Group annotation placed on the
method. Let's take a look at an example:

class User {
...
String office;
...
int hashCode() {
// Defines the hash for the key, normally used to determine location
...
}
// Override the location by specifying a group, all keys in the same
// group end up with the same owner
@Group
String getOffice() {
return office;
}
}

The group must be a String.

JBoss Community Documentation

Page 155 of 617

Infinispan 6.0
If you don't have control over the key class, or the determination of the group is an orthogonal concern to the
key class, we recommend you use an extrinsic group. In extrinsic group is specified by implementing the
Grouper interface, which has a single method computeGroup, which should return the group. Grouper acts
as an interceptor, passing the previously computed value in. The group passed to the first Grouper will be
that determined by @Group (if @Groupis defined). This allows you even greater control over the group
when using an intrinsic group. For a grouper to be used when determining the group for a key, it's keyType
must be assignable from the key being grouped.
Let's take a look at an example of a Grouper:

public class KXGrouper implements Grouper<String> {


// A pattern that can extract from a "kX" (e.g. k1, k2) style key
// The pattern requires a String key, of length 2, where the first character is
// "k" and the second character is a digit. We take that digit, and perform
// modular arithmetic on it to assign it to group "1" or group "2".
private static Pattern kPattern = Pattern.compile("(^k)(<a>\\d</a>)$");
public String computeGroup(String key, String group) {
Matcher matcher = kPattern.matcher(key);
if (matcher.matches()) {
String g = Integer.parseInt(matcher.group(2)) % 2 + "";
return g;
} else
return null;
}
public Class<String> getKeyType() {
return String.class;
}
}

Here we determine a simple grouper that can take the key class and extract from the group from the key
using a pattern. We ignore any group information specified on the key class.
You must register every grouper you wish to have used. If you are configuring Infinispan programmatically:

Configuration c = new ConfigurationBuilder().clustering().hash().groups().addGrouper(new


KXGrouper()).build();

Or, if you are using XML:

<clustering>
<hash>
<groups enabled="true">
<grouper class="com.acme.KXGrouper" />
</groups>
</hash>
</clustering>

JBoss Community Documentation

Page 156 of 617

Infinispan 6.0

3.24 Infinispan transactions


JTA Support
Configuring transactions
Transactional modes
Optimistic Transactions
Pessimistic Transactions
Backward compatibility
What do I need - pessimistic or optimistic transactions?
Deadlock detection
Transaction and exceptions
Transaction recovery on node failures
Enlisting Synchronization

JBoss Community Documentation

Page 157 of 617

Infinispan 6.0

3.24.1 JTA Support


Infinispan can be configured to use and to participate in JTA compliant transactions. Alternatively, if
transaction support is disabled, it is equivalent to using autocommit in JDBC calls, where modifications are
potentially replicated after every change (if replication is enabled).
On every cache operation Infinispan does the following:
1. Retrieves the current Transaction associated with the thread
2. If not already done, registers XAResource with the transaction manager to be notified when a transaction
commits or is rolled back.
In order to do this, the cache has to be provided with a reference to the environment's TransactionManager.
This is usually done by configuring the cache with the class name of an implementation of the
TransactionManagerLookup interface. When the cache starts, it will create an instance of this class and
invoke its getTransactionManager() method, which returns a reference to the TransactionManager.
Infinispan ships with several transaction manager lookup classes:
DummyTransactionManagerLookup : This provides with a dummy transaction manager which should
only be used for testing. Being a dummy, this is not recommended for production use a it has some
severe limitations to do with concurrent transactions and recovery.
JBossStandaloneJTAManagerLookup : If you're running Infinispan in a standalone environment, this
should be your default choice for transaction manager. It's a fully fledged transaction manager based
on JBoss Transactions which overcomes all the deficiencies of the dummy transaction manager.
GenericTransactionManagerLookup : This is a lookup class that locate transaction managers in the
most popular Java EE application servers. If no transaction manager can be found, it defaults on the
dummy transaction manager.
JBossTransactionManagerLookup : This lookup class locates the transaction manager running within
a JBoss Application Server instance.
Once initialized, the TransactionManager can also be obtained from the Cache itself:

//the cache must have a transactionManagerLookupClass defined


Cache cache = cacheManager.getCache();
//equivalent with calling TransactionManagerLookup.getTransactionManager();
TransactionManager tm = cache.getAdvancedCache().getTransactionManager();

JBoss Community Documentation

Page 158 of 617

Infinispan 6.0

3.24.2 Configuring transactions


Transactions are being configured at cache level; bellow is a sample configuration:

<transaction
transactionManagerLookupClass="org.infinispan.transaction.lookup.GenericTransactionManagerLookup"
transactionMode="TRANSACTIONAL"
lockingMode="OPTIMISTIC"/>

transactionManagerLookupClass fully qualified class name of a class that looks up a reference to a


javax.transaction.TransactionManager
transactionMode - configures whether the cache is transactional or not
lockingMode - configures whether the cache uses optimistic or pessimistic locking.
For more details on how two phase commit (2PC) is implemented in Infinispan and how locks are being
acquired see the section below. All possible transactional settings are available in Configuration reference

3.24.3 Transactional modes


Starting with Infinispan 5.1 release a cache can accessed either transactionally or non-transactionally. The
mixed access mode is no longer supported. There are several reasons for going this path, but one of them
most important is a cleaner semantic on how concurrency is managed between multiple requestors for the
same cache entry.
By default, all Infinispan caches are non-transactional. A cache can be made transactional by changing the
transactionMode attribute:

<namedCache name="transactional">
<transaction transactionMode="TRANSACTIONAL"/>
</namedCache>

transactionMode can only take two values: TRANSACTIONAL and NON_TRANSACTIONAL; one can
configure a transactional cache programatically as well:

Configuration c = new
ConfigurationBuilder().transaction().transactionMode(TransactionMode.TRANSACTIONAL).build();
assert c.transaction().transactionalCache();

Do not forget to configure a TransactionManagerLookup for transactional caches.

JBoss Community Documentation

Page 159 of 617

Infinispan 6.0
Supported transaction models are optimistic and pessimistic. Optimistic model is an improvement over the
old transaction model as it completely defers lock acquisition to transaction prepare time. New approach
reduces lock acquisition duration and increases throughput which in turn avoids deadlocks significantly. In
pessimistic model, cluster wide-locks are acquired on each write operation only being released after the
transaction completed.

Optimistic Transactions
With optimistic transactions locks are being acquired at transaction prepare time and are only being held up
to the point the transaction commits (or rollbacks). This is different from the 5.0 default locking model where
local locks are being acquire on writes and cluster locks are being acquired during prepare time.
Optimistic transactions can be enabled in the configuration file:

<namedCache name="transactional">
<transaction transactionMode="TRANSACTIONAL" lockingMode="OPTIMISTIC"/>
</namedCache>

or programatically:

Configuration c = new
ConfigurationBuilder().transaction().lockingMode(LockingMode.OPTIMISTIC).build();
assert c.transaction().lockingMode() == LockingMode.OPTIMISTIC;

By default, a transactional cache is optimistic.

JBoss Community Documentation

Page 160 of 617

Infinispan 6.0

Pessimistic Transactions
From a lock acquisition perspective, pessimistic transactions obtain locks on keys at the time the key is
written. E.g.

transactionManager.begin();
cache.put(k1,v1); //k1 is locked
cache.remove(k2); //k2 is locked when this returns
transactionManager.commit();

When cache.put(k1,v1) returns k1 is locked and no other transaction running anywhere in the cluster can
write to it. Reading k1 is still possible. The lock on k1 is released when the transaction completes (commits
or rollbacks).
Pessimistic transactions can be enabled in the configuration file:

<namedCache name="transactional"/>
<transaction transactionMode="TRANSACTIONAL" lockingMode="PESSIMISTIC"/>
</namedCache>

or programatically:

Configuration c = new
ConfigurationBuilder().transaction().lockingMode(LockingMode.PESSIMISTIC).build();
assert c.transaction().lockingMode() == LockingMode.PESSIMISTIC;

Backward compatibility
The autoCommit attribute was added in order to assure backward compatibility. If a cache is transactional
and autoCommit is enabled (defaults to true) then any call that is performed outside of a transaction's scope
is transparently wrapped within a transaction. In other words Infinispan adds the logic for starting a
transaction before the call and committing it after the call.
Therefore if your code accesses a cache both transactionally and non-transactionally all you have to do
when migrating to Infinispan 5.1 is mark the cache as transactional and enable autoCommit (that's actually
enabled by default)
The autoCommit feature can be managed through configuration:

<namedCache name="transactional">;
<transaction transactionMode="TRANSACTIONAL" autoCommit="true"/>
</namedCache>

JBoss Community Documentation

Page 161 of 617

Infinispan 6.0

What do I need - pessimistic or optimistic transactions?


From a use case perspective, optimistic transactions should be used when there is not a lot of contention
between multiple transactions running at the same time. That is because the optimistic transactions rollback
if data has changed between the time it was read and the time it was committed (writeSkewCheck).
On the other hand, pessimistic transactions might be a better fit when there is high contention on the keys
and transaction rollbacks are less desirable. Pessimistic transactions are more costly by their nature: each
write operation potentially involves a RPC for lock acquisition.

3.24.4 Deadlock detection


Deadlocks can significantly (up to one order of magnitude, see benchmarks) reduce the throughput of a
system, especially when multiple transactions are operating agains the same key set. Deadlock detection is
disabled by default, but can be enabled/configured per cache (i.e. under namedCache config element) by
adding the following:

<deadlockDetection enabled="true" spinDuration="1000"/>

Some clues on when to enable deadlock detection. A high number of transaction rolling back due to
TimeoutException is an indicator that this functionality might help. TimeoutException might be caused by
other causes as well, but deadlocks will always result in this exception being thrown. Generally, when you
have a high contention on a set of keys, deadlock detection may help. But the best way is not to guess the
performance improvement but to benchmark and monitor it: you can have access to statistics (e.g. number
of deadlocks detected) through JMX, as it is exposed via the DeadlockDetectingLockManager MBean. For
more details on how deadlock detection works, benchmarks and design details refer to this article.
Note: deadlock detection only runs on an a per cache basis: deadlocks that spread over two or more caches
won't be detected.

3.24.5 Transaction and exceptions


If a CacheException (or a subclass of it) is thrown by a cache method within the scope of a JTA transaction,
then the transaction is automatically marked for rollback.

3.24.6 Transaction recovery on node failures


Transaction recovery is discussed in this document.

JBoss Community Documentation

Page 162 of 617

Infinispan 6.0

3.24.7 Enlisting Synchronization


By default Infinispan registers itself as a first class participant in distributed transactions through
XAResource. There are situations where Infinispan is not required to be a participant in the transaction, but
only to be notified by its lifecycle (prepare, complete): e.g. in the case Infinispan is used as a 2nd level cache
in Hiberenate.
Starting with 5.0 release, Infinispan allows transaction enlistment through Synchronisation. This can be
enabled through the useSynchronization attribute on the transaction element:

<transaction useSynchronization="true"/>

Synchronisations have the advantage that they allow TransactionManager to optimize 2PC with a 1PC
where only one other resource is enlisted with that transaction (last resource commit optimization). E.g.
Hibernate second level cache: if Infinispan registers itself with the TransactionManager as a XAResource
than at commit time, the TransactionManager sees two XAResource (cache and database) and does not
make this optimization. Having to coordinate between two resources it needs to write the tx log to disk. On
the other hand, registering Infinispan as a Synchronisation makes the TransactionManager skip wrtting the
log to the disk (performance improvement).

3.25 Load Testing Infinispan Server Modules


Infinispan comes with different server implementations that allow Infinispan to be accessed remotely. You
can find an overview about these servers here.
This wiki explains how to load test and benchmark these server implementations using Grinder, which is a
Java load testing framework that makes it easy to run a distributed test using many load injector machines.
1. First of all, download Grinder version 3.4 or higher and unzip it somewhere locally.
2. Next, download and unzip the Infinispan version that you want to be testing. Make sure you download
the -all.zip distribution to run these tests. Note that although Infinispan REST server was included
in 4.0, Memcached and Hot Rod servers are only included from 4.1 onwards.
3. Download Infinispan Grinder scripts and other material from this source repository.
4. Next up, modify bin/setGrinderEnv.sh file to set correct environment paths. Primarily, you
should be looking at setting the following properties correctly (The rest of properties not mentioned
below can be left as they are) :
1. INFINISPAN_HOME: It should point to the location where Infinispan was unzipped.
2. GRINDER_HOME: It should point to where Grinder was unzipped.
3. GRINDER_PROPERTIES: It should point to the grinder.properties provided with the Infinispan
Grinder scripts
4. SPYMEMCACHED_HOME: It should only be modified to point to Spymemcached Memcached
client library if you're planning to load test Infinispan Memcached server.

JBoss Community Documentation

Page 163 of 617

Infinispan 6.0
5. It is time now to start the Infinispan server that you want to be testing. For detailed information on
starting up a Hot Rod server, check this wiki. If you want to start the Hot Rod server quickly, the
following command should do the job:
1. $INFINISPAN_HOME/bin/startServer.sh -r hotrod -l 0.0.0.0
6. Finally, let's start the load test. Currently, a single load test exists which after a warmup phase, it does
a certain amount of put/get calls on a pool of keys with a configurable distribution. By default, it
executes 20% put operations and 80% get operations. So, if you're going to start the Hot Rod test,
you'd simply do:
1. cd infinispan-server-grinder/
2. ./bin/startHotRodAgent.sh
7. Once the test has finished, the output can be located in
infinispan-server-grinder/log/out-<host>-0.log and will show something like this at the
bottom:

Tests

Errors

Mean Test
Time (ms)

Test Time
Standard
Deviation
(ms)

TPS

Test 1
Test 2
Test 3

25
400136
99864

0
0
0

13742.56
1.92
2.41

457.22
2.55
4.97

0.29
4687.08
1169.78

Totals

500025

2.70

97.26

1952.38

"Warmup (1000 ops)"


"Read (20000 ops per thread)"
"Put (20000 ops per thread)"

The output is saying that it first run 25 threads, each sending 1000 operations in order to warm up the
cache. Afterwards, each of these 25 threads send 20.000 operations making a total of 500.000
operations, out of which 400136 were get calls and 99864 were put calls, and the test here indicates
what was the mean test time for each of these operations, including standard deviation and how many
operations per second (TPS) were executed. In this case, 4686 get operations per second and 1169
put operations per second.

JBoss Community Documentation

Page 164 of 617

Infinispan 6.0

3.26 Using Infinispan as JPA-Hibernate Second Level


Cache Provider
Overview
Configuration
Default Configuration Explained
Defaults for Entity/Collection Caching
Defaults for Query Caching
Defaults for Timestamps Cache
JTA Transactions Configuration
Standalone JTA for JPA/Hibernate using Infinispan as 2LC
Advanced Configuration
Integration with JBoss Application Server
Using Infinispan as remote Second Level Cache?
Frequently Asked Questions

3.26.1 Overview
Following some of the principles set out by Brian Stansberry in Using JBoss Cache 3 as a Hibernate 3.5
Second Level Cache and taking in account improvements introduced by Infinispan, an Infinispan
JPA/Hibernate second level cache provider has been developed. This wiki explains how to configure
JPA/Hibernate to use the Infinispan and for those keen on lower level details, the key design decisions made
and differences with previous JBoss Cache based cache providers.
If you're unfamiliar with JPA/Hibernate Second Level Caching, I'd suggest you to read Chapter 2.1 in this
guide which explains the different types of data that can be cached.

On Caching
Query result caching, or entity caching, may or may not improve application performance. Be
sure to benchmark your application with and without caching.

3.26.2 Configuration
1. First of all, to enable JPA/Hibernate second level cache with query result caching enabled, add either of
the following:

<!-- If using JPA, add to your persistence.xml -->


<property name="hibernate.cache.use_second_level_cache" value="true" />
<property name="hibernate.cache.use_query_cache" value="true" />

JBoss Community Documentation

Page 165 of 617

Infinispan 6.0

<!-- If using Hibernate, add to your hibernate.cfg.xml -->


<property name="hibernate.cache.use_second_level_cache">true</property>
<property name="hibernate.cache.use_query_cache">true</property>

2. Now, configure the Infinispan cache region factory using one of the two options below:
If the Infinispan CacheManager instance happens to be bound to JNDI select JndiInfinispanRegionFactory
as the cacheregion factory and add the cache manager's JNDI name:

<!-- If using JPA, add to your persistence.xml -->


<property name="hibernate.cache.region.factory_class"
value="org.hibernate.cache.infinispan.JndiInfinispanRegionFactory" />
<property name="hibernate.cache.infinispan.cachemanager" value="java:CacheManager" />

<!-- If using Hibernate, add to your hibernate.cfg.xml -->


<property
name="hibernate.cache.region.factory_class">org.hibernate.cache.infinispan.JndiInfinispanRegionFactory</proper
name="hibernate.cache.infinispan.cachemanager">java:CacheManager/entity</property>

JBoss Application Server


JBoss Application Server 6 and 7 deploy a shared Infinispan cache manager that can be used by
all services, so when trying to configure applications with Infinispan second level cache, you should
use the JNDI name for the cache manager responsible for the second level cache. By default, this
is "java:CacheManager/entity". In any other application server, you can deploy your own cache
manager and bind the CacheManager to JNDI, but in this cases it's generally preferred that the
following method is used.

If running JPA/Hibernate and Infinispan standalone or within third party Application Server, select the
InfinispanRegionFactory as the cache region factory:

<!-- If using JPA, add to your persistence.xml -->


<property name="hibernate.cache.region.factory_class"
value="org.hibernate.cache.infinispan.InfinispanRegionFactory"/>

<!-- If using Hibernate, add to your hibernate.cfg.xml -->


<property
name="hibernate.cache.region.factory_class">org.hibernate.cache.infinispan.InfinispanRegionFactory</property>

JBoss Community Documentation

Page 166 of 617

Infinispan 6.0
This is all the configuration you need to have JPA/Hibernate use Infinispan as cache provider with the
default settings. You will still need to define which entities and queries need to be cached as defined in the
Hibernate reference documentation, but that configuration aspect is not peculiar to Infinispan.
This default configuration should suit the majority of use cases but sometimes, further configuration is
required and to help with such situations, please check the following section where more advanced settings
are discussed.

3.26.3 Default Configuration Explained


The aim of this section is to explain the default settings for each of the different global data type (entity,
collection, query and timestamps) caches, why these were chosen and what are the available alternatives.

Defaults for Entity/Collection Caching


By default, for all entities and collections, whenever an new entity or collection is read from
database and needs to be cached, it's only cached locally in order to reduce intra-cluster traffic.
This option cannot be changed.
By default, all entities and collections are configured to use a synchronous invalidation as
clustering mode. This means that when an entity is updated, the updated cache will send a message
to the other members of the cluster telling them that the entity has been modified. Upon receipt of this
message, the other nodes will remove this data from their local cache, if it was stored there. This
option can be changed to use replication by configuring entities or collections to use "replicated-entity"
cache but it's generally not a recommended choice.
By default, all entities and collections have initial state transfer disabled since there's no need for
it. It's not recommended that this is enabled.
By default, entities and collections are configured to use READ_COMMITTED as cache isolation
level. It would only make sure to configure REPEATABLE_READ if the application evicts/clears
entities from the Hibernate Session and then expects to repeatably re-read them in the same
transaction. Otherwise, the Session's internal cache provides repeatable-read semantics. If you really
need to use REPEATABLE_READ, you can simply configure entities or collections to use
"entity-repeatable" cache.
By default, entities and collections are configured with the following eviction settings:
Eviction wake up interval is 5 seconds.
Max number of entries are 10.000
Max idle time before expiration is 100 seconds
You can change these settings on a per entity or collection basis or per individual entity or collection
type.
More information in the "Advanced Configuration" section below.
By default entites and collections are configured with lazy deserialization which helps
deserialization when entities or collections are stored in isolated deployments. If you're sure you'll
never deploy your entities or collections in classloader isolated deployment archives, you can disable
this setting.

JBoss Community Documentation

Page 167 of 617

Infinispan 6.0

Defaults for Query Caching


By default, query cache is configured so that queries are only cached locally. Alternatively, you can
configure query caching to use replication by selecting the "replicated-query" as query cache name.
However, replication for query cache only makes sense if, and only if, all of this conditions are true:
Performing the query is quite expensive.
The same query is very likely to be repeatedly executed on different cluster nodes.
The query is unlikely to be invalidated out of the cache (Note: Hibernate must aggressively
invalidate query results from the cache any time any instance of one of the entity types
targeted by the query. All such query results are invalidated, even if the change made to the
specific entity instance would not have affected the query result)
By default, query cache uses the same cache isolation levels and eviction/expiration settings as
for entities/collections.
By default, query cache has initial state transfer disabled. It is not recommended that this is
enabled.

Defaults for Timestamps Cache


By default, the timestamps cache is configured with asynchronous replication as clustering
mode. Local or invalidated cluster modes are not allowed, since all cluster nodes must store all
timestamps. As a result, no eviction/expiration is allowed for timestamp caches either.
By default, the timestamps cache is configured with a cluster cache loader (in Hibernate 3.6.0
or earlier it had state transfer enabled) so that joining nodes can retrieve all timestamps. You
shouldn't attempt to disable the cluster cache loader for the timestamps cache.

3.26.4 JTA Transactions Configuration


It is highly recommended that Hibernate is configured with JTA transactions so that both Hibernate and
Infinispan cooperate within the same transaction and the interaction works as expected.
Otherwise, if Hibernate is configured for example with JDBC transactions, Hibernate will create a
Transaction instance via java.sql.Connection and Infinispan will create a transaction via whatever
TransactionManager returned by hibernate.transaction.manager_lookup_class. If
hibernate.transaction.manager_lookup_class has not been populated, it will default on the dummy
transaction manager. So, any work on the 2nd level cache will be done under a different transaction to the
one used to commit the stuff to the database via Hibernate. In other words, your operations on the database
and the 2LC are not treated as a single unit. Risks here include failures to update the 2LC leaving it with
stale data while the database committed data correctly. It has also been observed that under some
circumstances where JTA was not used, commit/rollbacks are not propagated to Infinispan.
To sum up, if you configure Hibernate with Infinispan, apply the following changes to your configuration file:
1. Unless your application uses JPA, you need to select the correct Hibernate transaction factory via the
property hibernate.transaction.factory_class:

JBoss Community Documentation

Page 168 of 617

Infinispan 6.0

If you're running within an application server, it's recommended that you use:

<!-- If using JPA, add to your persistence.xml -->


<property name="hibernate.transaction.factory_class"
value="org.hibernate.transaction.CMTTransactionFactory"/>

<!-- If using Hibernate, add to your hibernate.cfg.xml -->


<property
name="hibernate.transaction.factory_class">org.hibernate.transaction.CMTTransactionFactory</property>

If you're running in a standalone environment and you wanna enable JTA transaction factory, use:

<!-- If using JPA, add to your persistence.xml -->


<property name="hibernate.transaction.factory_class"
value="org.hibernate.transaction.JTATransactionFactory"/>

<!-- If using Hibernate, add to your hibernate.cfg.xml -->


<property
name="hibernate.transaction.factory_class">org.hibernate.transaction.JTATransactionFactory</property>

The reason why JPA does not require a transaction factory class to be set up is because the entity
manager already sets it to a variant of CMTTransactionFactory.
2. Select the correct Hibernate transaction manager lookup:
If you're running within an application server, select the appropriate lookup class according to "JTA
Transaction Managers" table.
For Example if you were running with the JBoss Application Server you would set:

<!-- If using JPA, add to your persistence.xml -->


<property name="hibernate.transaction.manager_lookup_class"
value="org.hibernate.transaction.JBossTransactionManagerLookup"/>

<!-- If using Hibernate, add to your hibernate.cfg.xml -->


<property name="hibernate.transaction.manager_lookup_class">
org.hibernate.transaction.JBossTransactionManagerLookup
</property>

JBoss Community Documentation

Page 169 of 617

Infinispan 6.0

If you are running standalone and you want to add a JTA transaction manager lookup, things get a bit
more complicated. Due to a current limitation, Hibernate does not support injecting a JTA
TransactionManager or JTA UserTransaction that are not bound to JNDI. In other words, if you want
to use JTA, Hibernate expects your TransactionManager to be bound to JNDI and it also expects that
UserTransaction instances are retrieved from JNDI. This means that in an standalone environment,
you need to add some code that binds your TransactionManager and UserTransaction to JNDI. With
this in mind and with the help of one of our community contributors, we've created an example that
does just that: JBoss Standalone JTA Example. Once you have the code in place, it's just a matter of
selecting the correct Hibernate transaction manager lookup class, based on the JNDI names given. If
you take JBossStandaloneJtaExample as an example, you simply have to add:

<!-- If using JPA, add to your persistence.xml -->


<property name="hibernate.transaction.manager_lookup_class"
value="org.hibernate.transaction.JBossTransactionManagerLookup"/>

<!-- If using Hibernate, add to your hibernate.cfg.xml -->


<property name="hibernate.transaction.manager_lookup_class">
org.hibernate.transaction.JBossTransactionManagerLookup
</property>

As you probably have noted through this section, there wasn't a single mention of the need to
configure Infinispan's transaction manager lookup and there's a good reason for that. Basically, the
code within Infinispan cache provider takes the transaction manager that has been configured at the
Hibernate level and uses that. Otherwise, if no Hibernate transaction manager lookup class has been
defined, Infinispan uses a default dummy transaction manager.
Since Hibernate 4.0, the way Infinispan hooks into the transaction manager can be configured. By default,
since 4.0, Infinispan interacts with the transaction manager as an JTA synchronization, resulting in a faster
interaction with the 2LC thanks to some key optimisations that the transaction manager can apply . However
if desired, users can configure Infinispan to act as an XA resource (just like it did in 3.6 and earlier) by
disabling the use of the synchronization. For example:

<!-- If using JPA, add to your persistence.xml: -->


<property name="hibernate.cache.infinispan.use_synchronization"

value="false"/>

<!-- If using Hibernate, add to your hibernate.cfg.xml: -->


<property name="hibernate.cache.infinispan.use_synchronization">
false
</property>

JBoss Community Documentation

Page 170 of 617

Infinispan 6.0

Standalone JTA for JPA/Hibernate using Infinispan as 2LC


The JBoss standalone JTA example referred to in the previous section is inspired by the great work of
Guenther Demetz, one of the members of the Infinispan community, who wrote an impressive wiki explaining
how to set up standalone JTA with different transaction managers running outside of an EE server, and how
to get this to work with an Infinispan backed JPA/Hibernate application.

3.26.5 Advanced Configuration


Infinispan has the capability of exposing statistics via JMX and since Hibernate 3.5.0.Beta4, you can enable
such statistics from the Hibernate/JPA configuration file. By default, Infinispan statistics are turned off but
when these are disabled via the following method, statistics for the Infinispan Cache Manager and all the
managed caches (entity, collection,...etc) are enabled:

<!-- If using JPA, add to your persistence.xml -->


<property name="hibernate.cache.infinispan.statistics" value="true"/>

<!-- If using Hibernate, add to your hibernate.cfg.xml: -->


<property name="hibernate.cache.infinispan.statistics">true</property>

The Infinispan cache provider jar file contains an Infinispan configuration file, which is the one used by
default when configuring the Infinispan standalone cache region factory. This file contains default cache
configurations for all Hibernate data types that should suit the majority of use cases. However, if you want to
use a different configuration file, you can configure it via the following property:

<!-- If using JPA, add to your persistence.xml -->


<property name="hibernate.cache.infinispan.cfg"
value="/home/infinispan/cacheprovider-configs.xml"/>

<!-- If using Hibernate, add to your hibernate.cfg.xml: -->


<property name="hibernate.cache.infinispan.cfg">
/home/infinispan/cacheprovider-configs.xml
</property>

For each Hibernate cache data types, Infinispan cache region factory has defined a default cache name to
look up in either the default, or the user defined, Infinispan cache configuration file. These default values can
be found in the Infinispan cache provider javadoc. You can change these cache names using the following
properties:

JBoss Community Documentation

Page 171 of 617

Infinispan 6.0

<!-- If using JPA, add to your persistence.xml: -->


<property name="hibernate.cache.infinispan.entity.cfg"
value="custom-entity"/>
<property name="hibernate.cache.infinispan.collection.cfg"
value="custom-collection"/>
<property name="hibernate.cache.infinispan.query.cfg"
value="custom-collection"/>
<property name="hibernate.cache.infinispan.timestamp.cfg"
value="custom-timestamp"/>

<!-- If using Hibernate, add to your hibernate.cfg.xml -->


<property name="hibernate.cache.infinispan.entity.cfg">
custom-entity
</property>
<property name="hibernate.cache.infinispan.collection.cfg">
custom-collection
</property>
<property name="hibernate.cache.infinispan.query.cfg">
custom-collection
</property>
<property name="hibernate.cache.infinispan.timestamp.cfg">
custom-timestamp
</property>

One of the key improvements brought in by Infinispan is the fact that cache instances are more lightweight
than they used to be in JBoss Cache. This has enabled a radical change in the way entity/collection type
cache management works. With the Infinispan cache provider, each entity/collection type gets each own
cache instance, whereas in old JBoss Cache based cache providers, all entity/collection types would be
sharing the same cache instance. As a result of this, locking issues related to updating different
entity/collection types concurrently are avoided completely.
This also has an important bearing on the meaning of hibernate.cache.infinispan.entity.cfg and
hibernate.cache.infinispan.collection.cfg properties. These properties define the template cache name that
should be used for all entity/collection data types. So, with the above hibernate.cache.infinispan.entity.cfg
configuration, when a region needs to be created for entity com.acme.Person, the cache instance to be
assigned to this entity will be based on a "custom-entity" named cache.
On top of that, this finer grained cache definition enables users to define cache settings on a per
entity/collection basis. For example:

<!-- If using JPA, add to your persistence.xml -->


<property name="hibernate.cache.infinispan.com.acme.Person.cfg"
value="person-entity"/>
<property name="hibernate.cache.infinispan.com.acme.Person.addresses.cfg"
value="addresses-collection"/>

JBoss Community Documentation

Page 172 of 617

Infinispan 6.0

<!-- If using Hibernate, add to your hibernate.cfg.xml -->


<property name="hibernate.cache.infinispan.com.acme.Person.cfg">
person-entity
</property>
<property name="hibernate.cache.infinispan.com.acme.Person.addresses.cfg">
addresses-collection
</property>

Here, we're configuring the Infinispan cache provider so that for com.acme.Person entity type, the cache
instance assigned will be based on a "person-entity" named cache, and for com.acme.Person.addresses
collection type, the cache instance assigned will be based on a "addresses-collection" named cache. If either
of these two named caches did not exist in the Infinispan cache configuration file, the cache provider would
create a cache instance for com.acme.Person entity and com.acme.Person.addresses collection based on
the default cache in the configuration file.
Furthermore, thanks to the excellent feedback from the Infinispan community and in particular, Brian
Stansberry, we've decided to allow users to define the most commonly tweaked Infinispan cache parameters
via hibernate.cfg.xml or persistence.xml, for example eviction/expiration settings. So, with the Infinispan
cache provider, you can configure eviction/expiration this way:

<!-- If using JPA, add to your persistence.xml -->


<property name="hibernate.cache.infinispan.entity.eviction.strategy"
value= "LRU"/>
<property name="hibernate.cache.infinispan.entity.eviction.wake_up_interval"
value= "2000"/>
<property name="hibernate.cache.infinispan.entity.eviction.max_entries"
value= "5000"/>
<property name="hibernate.cache.infinispan.entity.expiration.lifespan"
value= "60000"/>
<property name="hibernate.cache.infinispan.entity.expiration.max_idle"
value= "30000"/>

<!-- If using Hibernate, add to your hibernate.cfg.xml -->


<property name="hibernate.cache.infinispan.entity.eviction.strategy">
LRU
</property>
<property name="hibernate.cache.infinispan.entity.eviction.wake_up_interval">
2000
</property>
<property name="hibernate.cache.infinispan.entity.eviction.max_entries">
5000
</property>
<property name="hibernate.cache.infinispan.entity.expiration.lifespan">
60000
</property>
<property name="hibernate.cache.infinispan.entity.expiration.max_idle">
30000
</property>

JBoss Community Documentation

Page 173 of 617

Infinispan 6.0
With the above configuration, you're overriding whatever eviction/expiration settings were defined for the
default entity cache name in the Infinispan cache configuration used, regardless of whether it's the default
one or user defined. More specifically, we're defining the following:
All entities to use LRU eviction strategy
The eviction thread to wake up every 2000 milliseconds
The maximum number of entities for each entity type to be 5000 entries
The lifespan of each entity instance to be 600000 milliseconds
The maximum idle time for each entity instance to be 30000
You can also override eviction/expiration settings on a per entity/collection type basis in such way that the
overriden settings only afftect that particular entity (i.e. com.acme.Person) or collection type (i.e.
com.acme.Person.addresses). For example:

<!-- If using JPA, add to your persistence.xml -->


<property name="hibernate.cache.infinispan.com.acme.Person.eviction.strategy"
value= "FIFO"/>
<property name="hibernate.cache.infinispan.com.acme.Person.eviction.wake_up_interval"
value= "2500"/>
<property name="hibernate.cache.infinispan.com.acme.Person.eviction.max_entries"
value= "5500"/>
<property name="hibernate.cache.infinispan.com.acme.Person.expiration.lifespan"
value= "65000"/>
<property name="hibernate.cache.infinispan.com.acme.Person.expiration.max_idle"
value= "35000"/>

<!-- If using Hibernate, add to your hibernate.cfg.xml -->


<property name="hibernate.cache.infinispan.com.acme.Person.eviction.strategy">
FIFO
</property>
<property name="hibernate.cache.infinispan.com.acme.Person.eviction.wake_up_interval">
2500
</property>
<property name="hibernate.cache.infinispan.com.acme.Person.eviction.max_entries">
5500
</property>
<property name="hibernate.cache.infinispan.com.acme.Person.expiration.lifespan">
65000
</property>
<property name="hibernate.cache.infinispan.com.acme.Person.expiration.max_idle">
35000
</property>

The aim of these configuration capabilities is to reduce the number of files needed to modify in order to
define the most commonly tweaked parameters. So, by enabling eviction/expiration configuration on a per
generic Hibernate data type or particular entity/collection type via hibernate.cfg.xml or persistence.xml, users
don't have to touch to Infinispan's cache configuration file any more. We believe users will like this approach
and so, if you there are any other Infinispan parameters that you often tweak and these cannot be configured
via hibernate.cfg.xml or persistence.xml, please let the Infinispan team know by sending an email to
infinispan-dev@lists.jboss.org.

JBoss Community Documentation

Page 174 of 617

Infinispan 6.0
Please note that query/timestamp caches work the same way they did with JBoss Cache based cache
providers. In other words, there's a query cache instance and timestamp cache instance shared by all. It's
worth noting that eviction/expiration settings are allowed for query cache but not for timestamp cache. So
configuring an eviction strategy other than NONE for timestamp cache would result in a failure to start up.
Finally, from Hibernate 3.5.4 and 3.6 onwards, queries with specific cache region names are stored under
matching cache instances. This means that you can now set query cache region specific settings. For
example, assuming you had a query like this:

Query query = session.createQuery(


"select account.branch from Account as account where account.holder = ?");
query.setCacheable(true);
query.setCacheRegion("AccountRegion");

The query would be stored under "AccountRegion" cache instance and users could control settings in similar
fashion to what was done with entities and collections. So, for example, you could define specific eviction
settings for this particular query region doing something like this:

<!-- If using JPA, add to your persistence.xml -->


<property name="hibernate.cache.infinispan.AccountRegion.eviction.strategy"
value= "FIFO"/>
<property name="hibernate.cache.infinispan.AccountRegion.eviction.wake_up_interval"
value= "10000"/>

<!-- If using Hibernate, add to your hibernate.cfg.xml -->


<property name="hibernate.cache.infinispan.AccountRegion.eviction.strategy">
FIFO
</property>
<property name="hibernate.cache.infinispan.AccountRegion.eviction.wake_up_interval">
10000
</property>

3.26.6 Integration with JBoss Application Server


In JBoss Application Server 7, Infinispan is the default second level cache provider and you can find details
about its configuration the AS7 JPA reference guide.
Infinispan based Hibernate 2LC was developed as part of Hibernate 3.5 release and so it currently only
works within AS 6 or higher. Hibernate 3.5 is not designed to work with AS/EAP 5.x or lower. To be able to
run Infinispan based Hibernate 2LC in a lower AS version such as 5.1, the Infinispan 2LC module would
require porting to Hibernate 3.3.
Recently, William Decoste has helped migrate the Infinispan 2LC module to Hibernate 3.3, and in this wiki,
he explains how to integrate Infinispan Hibernate 2LC with JBoss AS/EAP 5.x.

JBoss Community Documentation

Page 175 of 617

Infinispan 6.0

3.26.7 Using Infinispan as remote Second Level Cache?


Lately, several questions (here & here) have appeared in the Infinispan user forums asking whether it'd be
possible to have an Infinispan second level cache that instead of living in the same JVM as the Hibernate
code, it resides in a remote server, i.e. an Infinispan Hot Rod server. It's important to understand that trying
to set up second level cache in this way is generally not a good idea for the following reasons:
The purpose of a JPA/Hibernate second level cache is to store entities/collections recently retrieved
from database or to maintain results of recent queries. So, part of the aim of the second level cache is
to have data accessible locally rather than having to go to the database to retrieve it everytime this is
needed. Hence, if you decide to set the second level cache to be remote as well, you're losing one of
the key advantages of the second level cache: the fact that the cache is local to the code that requires
it.
Setting a remote second level cache can have a negative impact in the overall performance of your
application because it means that cache misses require accessing a remote location to verify whether
a particular entity/collection/query is cached. With a local second level cache however, these misses
are resolved locally and so they are much faster to execute than with a remote second level cache.
There are however some edge cases where it might make sense to have a remote second level cache, for
example:
You are having memory issues in the JVM where JPA/Hibernate code and the second level cache is
running. Off loading the second level cache to remote Hot Rod servers could be an interesting way to
separate systems and allow you find the culprit of the memory issues more easily.
Your application layer cannot be clustered but you still want to run multiple application layer nodes. In
this case, you can't have multiple local second level cache instances running because they won't be
able to invalidate each other for example when data in the second level cache is updated. In this
case, having a remote second level cache could be a way out to make sure your second level cache
is always in a consistent state, will all nodes in the application layer pointing to it.
Rather than having the second level cache in a remote server, you want to simply keep the cache in a
separate VM still within the same machine. In this case you would still have the additional overhead of
talking across to another JVM, but it wouldn't have the latency of across a network. The benefit of
doing this is that:
Size the cache separate from the application, since the cache and the application server have
very different memory profiles. One has lots of short lived objects, and the other could have
lots of long lived objects.
To pin the cache and the application server onto different CPU cores (using numactl), and
even pin them to different physically memory based on the NUMA nodes.

3.26.8 Frequently Asked Questions


To find out more please go to the Hibernate 2nd level cache section in the Technical FAQ wiki.

JBoss Community Documentation

Page 176 of 617

Infinispan 6.0

3.27 Default Values For Property Based Attributes


The aim of this article is to complement the configuration reference documentation with information on
default values that could not be automatically generated. Please find below the name of the XML elements
and their corresponding property default values:

3.27.1 asyncListenerExecutor
maxThreads = 1
threadNamePrefix = "notification-thread"

3.27.2 asyncTransportExecutor
maxThreads = 25
threadNamePrefix = "transport-thread"

3.27.3 evictionScheduledExecutor
maxThreads = 1 (cannot be changed)
threadNamePrefix = "eviction-thread"

3.27.4 replicationQueueScheduledExecutor
maxThreads = 1 (cannot be changed)
threadNamePrefix = "replicationQueue-thread"

3.28 Running Infinispan on Amazon Web Services


Infinispan can be used on the Amazon Web Service (AWS) platform and similar cloud based environment in
several ways. As Infinispan uses JGroups as the underlying communication technology, the majority of the
configuration work is done JGroups. The default auto discovery won't work on EC2 as multicast is not
allowed, but JGroups provides several other discovery protocols so we only have to choose one.

JBoss Community Documentation

Page 177 of 617

Infinispan 6.0

3.28.1 TCPPing, GossipRouter, S3_PING


The TCPPing approach contains a static list of the IP address of each member of the cluster in the JGroups
configuration file. While this works it doesn't really help when cluster nodes are dynamically added to the
cluster. See http://community.jboss.org/wiki/JGroupsTCPPING for more information about TCPPing.
Sample TCPPing configuration
<config xmlns="urn:org:jgroups" xmlns:xsi="[http://www.w3.org/2001/XMLSchema-instance]"
xsi:schemaLocation="urn:org:jgroups file:schema/JGroups-2.8.xsd">
<TCP bind_port="7800" />
<TCPPING timeout="3000"
initial_hosts="$\{jgroups.tcpping.initial_hosts:localhost\[7800\],localhost\[7801\]\}"
port_range="1"
num_initial_members="3"/>
<MERGE2 max_interval="30000" min_interval="10000"/>
<FD_SOCK/>
<FD timeout="10000" max_tries="5" />
<VERIFY_SUSPECT timeout="1500" />
<pbcast.NAKACK
use_mcast_xmit="false" gc_lag="0"
retransmit_timeout="300,600,1200,2400,4800"
discard_delivered_msgs="true"/>
<UNICAST timeout="300,600,1200" />
<pbcast.STABLE
stability_delay="1000"
desired_avg_gossip="50000"
max_bytes="400000"/>
<pbcast.GMS
print_local_addr="true"
join_timeout="3000"
view_bundling="true"/>
<FC max_credits="2000000" min_threshold="0.10"/>
<FRAG2 frag_size="60000" />
<pbcast.STREAMING_STATE_TRANSFER/>
</config>

JBoss Community Documentation

Page 178 of 617

Infinispan 6.0

3.28.2 GossipRouter
Another approach is to have a central server (Gossip, which each node will be configured to contact. This
central server will tell each node in the cluster about each other node. More on Gossip Router @
http://www.jboss.org/community/wiki/JGroupsGossipRouter
The address (ip:port) that the Gossip router is listening on can be injected into the JGroups configuration
used by Infinispan. To do this pass the gossip routers address as a system property to the JVM e.g.
-DGossipRouterAddress="10.10.2.4[12001]" and reference this property in the JGroups configuration that
Infinispan is using e.g.

<config>
<TCP bind_port="7800" />
<TCPGOSSIP timeout="3000" initial_hosts="$\{GossipRouterAddress\}" num_initial_members="3"
/>
.
.
</config>

JBoss Community Documentation

Page 179 of 617

Infinispan 6.0

3.28.3 S3_PING
Finally you can configure your JGroups instances to use a shared storage to exchange the details of the
cluster nodes. S3_PING was added to JGroups in 2.6.12 and 2.8, and allows the Amazon S3 to be used as
the shared storage. It is experimental at the moment but offers another method of clustering without a central
server. Be sure that you have signed up for Amazon S3 as well as EC2 to use this method.

<?xml version="1.0" encoding="UTF-8"?>


<config>
<TCP bind_port="7800" />
<S3_PING
secret_access_key="replace this with you secret access key"
access_key="replace this with your access key"
location="replace this with your S3 bucket location" />
<MERGE2
max_interval="30000"
min_interval="10000" />
<FD_SOCK />
<FD timeout="10000"
max_tries="5" />
<VERIFY_SUSPECT timeout="1500" />
<pbcast.NAKACK
use_mcast_xmit="false"
gc_lag="0" retransmit_timeout="300,600,1200,2400,4800"
discard_delivered_msgs="true" />
<UNICAST timeout="300,600,1200,2400,3600" />
<pbcast.STABLE
stability_delay="1000"
desired_avg_gossip="50000"
max_bytes="400000" />
<VIEW_SYNC
avg_send_interval="60000" />
<pbcast.GMS
print_local_addr="true"
join_timeout="60000"
view_bundling="true" />
<FC max_credits="20000000"
min_threshold="0.10" />
<FRAG2 frag_size="60000" />
<pbcast.STATE_TRANSFER />
<pbcast.FLUSH timeout="0" />
</config>

3.28.4 JDBC_PING
A similar approach to S3_PING, but using a JDBC connection to a shared database. On EC2 that is quite
easy using Amazon RDS. See the JDBC_PING Wiki page for details.

JBoss Community Documentation

Page 180 of 617

Infinispan 6.0

3.28.5 Creating a cluster node with distributed cache


Creating a cluster
GlobalConfiguration gc = GlobalConfiguration.getClusteredDefault();
gc.setClusterName("infinispan-test-cluster");
gc.setTransportClass(JGroupsTransport.class.getName());
//Load the jgroups properties
Properties p = newProperties();
p.setProperty("configurationFile","jgroups-config.xml");
gc.setTransportProperties(p);
Configuration c = new Configuration();
//Distributed cache mode
c.setCacheMode(Configuration.CacheMode.DIST_SYNC);
c.setExposeJmxStatistics(true);
// turn functionality which returns the previous value when setting
c.setUnsafeUnreliableReturnValues(true);
//data will be distributed over 3 nodes
c.setNumOwners(3);
c.setL1CacheEnabled(true);
//Allow batching
c.setInvocationBatchingEnabled(true);
c.setL1Lifespan(6000000);
cache_manager = new DefaultCacheManager(gc, c, false);

3.29 Eviction Examples


3.29.1 Introduction
1. Expiration is a top-level construct, represented in the configuration as well as in the cache API. More
on this later.
2. While eviction is local to each cache instance , expiration is cluster-wide . Expiration lifespans and
maxIdle values are replicated along with the cache entry.
3. Expiration lifespan and maxIdle are also persisted in CacheStores, so this information survives
eviction/passivation.
4. Four eviction strategies are shipped, EvictionStrategy.NONE, EvictionStrategy.LRU,
EvictionStrategy.UNORDERED, and EvictionStrategy.LIRS.

3.29.2 Configuration
Eviction may be configured using the Configuration bean or the XML file. Eviction configuration is on a
per-cache basis. Valid eviction-related configuration elements are:

JBoss Community Documentation

Page 181 of 617

Infinispan 6.0

<eviction strategy="FIFO" wakeupInterval="1000" maxEntries="2000"/>


<expiration lifespan="1000" maxIdle="500" />

XML changes in Infinispan 5.0


From Infinispan 5.0 onwards, wakeupInterval attribute has been moved to expiration XML
element. This is because since 4.1, eviction happens in the user thread, and so the old eviction
thread now simply purges expired entries from memory and any attached cache store. So,
effectively, wakeUpInterval controls how often this purging occurs:

<eviction strategy="FIFO" maxEntries="2000"/>


<expiration lifespan="1000" maxIdle="500" wakeupInterval="1000"/>

Programmatically, the same would be defined using:

Configuration c = new ConfigurationBuilder().eviction().strategy(EvictionStrategy.LRU)


.maxEntries(2000).expiration().wakeUpInterval(5000l).lifespan(1000l).maxIdle(1000l)
.build();

Default values
Eviction is disabled by default. If enabled (using an empty <eviction /> element), certain default values are
used:
strategy: EvictionStrategy.NONE is assumed, if a strategy is not specified..
wakeupInterval: 5000 is used if not specified.
If you wish to disable the eviction thread, set wakeupInterval to -1.
maxEntries: -1 is used if not specified, which means unlimited entries.
0 means no entries, and the eviction thread will strive to keep the cache empty.
Expiration lifespan and maxIdle both default to -1.

JBoss Community Documentation

Page 182 of 617

Infinispan 6.0

Using expiration
Expiration allows you to set either a lifespan or a maximum idle time on each key/value pair stored in the
cache. This can either be set cache-wide using the configuration, as described above, or it can be defined
per-key/value pair using the Cache interface. Any values defined per key/value pair overrides the
cache-wide default for the specific entry in question.
For example, assume the following configuration:

<expiration lifespan="1000" />

// this entry will expire in 1000 millis


cache.put("pinot noir", pinotNoirPrice);
// this entry will expire in 2000 millis
cache.put("chardonnay", chardonnayPrice, 2, TimeUnit.SECONDS);
// this entry will expire 1000 millis after it is last accessed
cache.put("pinot grigio", pinotGrigioPrice, -1,
TimeUnit.SECONDS, 1, TimeUnit.SECONDS);
// this entry will expire 1000 millis after it is last accessed, or
// in 5000 millis, which ever triggers first
cache.put("riesling", rieslingPrice, 5,
TimeUnit.SECONDS, 1, TimeUnit.SECONDS);

3.29.3 Eviction designs


Central to eviction is an EvictionManager - which is only available if eviction or expiration is configured.
The purpose of the EvictionManager is to drive the eviction/expiration thread which periodically purges items
from the DataContainer. If the eviction thread is disabled (wakeupInterval set to -1) eviction can be kicked
off manually using EvictionManager.processEviction(), for example from another maintenance thread that
may run periodically in your application.
The eviction manager processes evictions in the following manner:
1. Causes the data container to purge expired entries
2. Causes cache stores (if any) to purge expired entries
3. Prunes the data container to a specific size, determined by maxElements

JBoss Community Documentation

Page 183 of 617

Infinispan 6.0

3.30 Clustering modes


Introduction
Local Mode
Replicated Mode
Invalidation Mode
Distribution Mode
Read consistency
Virtual Nodes - Improving the distribution of data
L1 Caching

3.30.1 Introduction
Infinispan can be configured to be either local (standalone) or clustered. If in a cluster, the cache can be
configured to replicate changes to all nodes, to invalidate changes across nodes and finally to be used in
distributed mode - state changes are replicated to a small subset of nodes enough to be fault tolerant but not
to many nodes to prevent scalability.

3.30.2 Local Mode


While Infinispan is particularly interesting in clustered mode, it also offers a very capable local mode, where
it acts as a simple, in-memory data cache similar to JBoss Cache and EHCache. But why would one use a
local cache rather than a map? Caches offer a lot of features over and above a simple map, including
write-through and write-behind caching to persist data, eviction of entries to prevent running out of memory,
and support for expirable entries. Infinispan, specifically, is built around a high-performance, read-biased
data container which uses modern techniques like MVCC locking - which buys you non-blocking, thread-safe
reads even when concurrent writes are taking place. Infinispan also makes heavy use of compare-and-swap
and other lock-free algorithms, making it ideal for high-throughput, multi-CPU/multi-core environments.
Further, Infinispan's Cache API extends the JDK's ConcurrentMap - making migration from a map to
Infinispan trivial. For more details refer to Non-clustered, LOCAL mode section.

3.30.3 Replicated Mode


Replication is a simple clustered mode where cache instances automatically discover neighboring instances
on other JVMs on the same local network, and form a cluster. Entries added to any of these cache instances
will be replicated to all other cache instances in the cluster, and can be retrieved locally from any instance.
This clustered mode provides a quick and easy way to share state across a cluster, however replication
practically only performs well in small clusters (under 10 servers), due to the number of replication messages
that need to happen - as the cluster size increases. Infinispan can be configured to use UDP multicast which
mitigates this problem to some degree.

JBoss Community Documentation

Page 184 of 617

Infinispan 6.0

Figure 1. Replication mode


Replication can be synchronous or asynchronous. Use of either one of the options is application dependent.
Synchronous replication blocks the caller (e.g. on a put() ) until the modifications have been replicated
successfully to all nodes in a cluster. Asynchronous replication performs replication in the background (the
put() returns immediately). Infinispan offers a replication queue, where modifications are replicated
periodically (i.e. interval-based), or when the queue size exceeds a number of elements, or a combination
thereof. A replication queue can therefore offer much higher performance as the actual replication is
performed by a background thread.
Asynchronous replication is faster (no caller blocking), because synchronous replication requires
acknowledgments from all nodes in a cluster that they received and applied the modification successfully
(round-trip time). However, when a synchronous replication returns successfully, the caller knows for sure
that all modifications have been applied to all cache instances, whereas this is not be the case with
asynchronous replication. With asynchronous replication, errors are simply written to a log. Even when using
transactions, a transaction may succeed but replication may not succeed on all cache instances.

JBoss Community Documentation

Page 185 of 617

Infinispan 6.0

3.30.4 Invalidation Mode


Invalidation is a clustered mode that does not actually share any data at all, but simply aims to remove data
that may be stale from remote caches. This cache mode only makes sense if you have another, permanent
store for your data such as a database and are only using Infinispan as an optimization in a read-heavy
system, to prevent hitting the database every time you need some state. If a cache is configured for
invalidation rather than replication, every time data is changed in a cache other caches in the cluster receive
a message informing them that their data is now stale and should be evicted from memory.

Figure 2. Invalidation mode


Invalidation, when used with a shared cache loader would cause remote caches to refer to the shared cache
loader to retrieve modified data. The benefit of this is twofold: network traffic is minimized as invalidation
messages are very small compared to replicating updated data, and also that other caches in the cluster
look up modified data in a lazy manner, only when needed.
Invalidation messages are sent after each modification (no transactions or batches), or at the end of a
transaction or batch, upon successful commit. This is usually more efficient as invalidation messages can be
optimized for the transaction as a whole rather than on a per-modification basis.
Invalidation too can be synchronous or asynchronous, and just as in the case of replication, synchronous
invalidation blocks until all caches in the cluster receive invalidation messages and have evicted stale data
while asynchronous invalidation works in a 'fire-and-forget' mode, where invalidation messages are
broadcast but doesn't block and wait for responses.

JBoss Community Documentation

Page 186 of 617

Infinispan 6.0

3.30.5 Distribution Mode


Distribution is a powerful clustering mode which allows Infinispan to scale linearly as more servers are added
to the cluster. Distribution makes use of a consistent hash algorithm to determine where in a cluster entries
should be stored. Hashing algorithm is configured with the number of copies each cache entry should be
maintained cluster-wide. Number of copies represents the tradeoff between performance and durability of
data. The more copies you maintain, the lower performance will be, but also the lower the risk of losing data
due to server outages. Regardless of how many copies are maintained, distribution still scales linearly and
this is key to Infinispan scalability. Another feature of the consistent hash algorithm is that it is deterministic
in locating entries without resorting to multicasting requests or maintaining expensive metadata. Doing a
PUT would result in at most num_copies remote calls, and doing a GET anywhere in the cluster would result
in at most 1 remote call. In reality, num_copies remote calls are made even for a GET, but these are done in
parallel and as soon as any one of these returns, the entry is passed back to the caller.
NOTE: This behavior is due to change in Infinispan 5.3, where just a single GET call is made. See ISPN-825
.

JBoss Community Documentation

Page 187 of 617

Infinispan 6.0

Read consistency
Since GETs are sent to all data owners in parallel and the first returning result is used, this can lead to data
inconsistency when using an asynchronous transport. If an updating thread modifies the primary data owner,
but updates are only sent to backup nodes asynchronously, a concurrent read may read a stale value for a
short period of time until the asynchronous replication completes.
Note that this is only if the transport is asynchronous. If using a synchronous transport this behavior is not
exhibited.

Figure 3. Distribution mode

Virtual Nodes - Improving the distribution of data


Infinispan does not attempt to evenly split the hash space between nodes by not trying to split it evenly, it
means that if a node joins or leaves the grid, there is no need to adjust the ownership of every node, just the
neighbours of the joiner/leaver. This has a positive impact on network traffic. However this can mean that
some nodes take on substantially larger portions of the hash space than others. This, combined with
potential irregularities in the hash functions of keys, can mean the distribution of entries across the grid
becomes poor. In order to address the irregularities in the hash of keys, Infinispan uses an advanced
hashing function (Murmur Hash 3) by default, as well as using a bit spreader. In order to address the
irregularities in the node distribution, Infinispan uses virtual nodes.

JBoss Community Documentation

Page 188 of 617

Infinispan 6.0
First, let's consider how virtual nodes help conceptually by taking a couple of distribution examples, and
armed with that knowledge, look at how Infinispan uses them.
Consider a hash space of 1000 (there are 1000 buckets into which data can be placed). If there were two
nodes, it is possible you can have 1 node being used for 1 bucket, and 1 node for 999 buckets (this is the
most pessimistic distribution!). If there were 200 nodes, the worst distribution of node would end up being
199 nodes responsible for one bucket each (199 buckets in total), and 1 node being responsible for 801
buckets. If there were 1000 nodes, then each node must be responsible for 1 bucket each. From this we can
deduce that as the number of nodes tends to the size of the hash space, that the distribution of buckets to
nodes improves.
A guiding principle of Infinispan is that it always uses an algorithm to locate a key in the hash space, never
allowing the node on which the entry is stored to be specified manually. This scheme allows any node to
know which nodes owns a key, without having to distribute such ownership information. This reduces the
overhead of Infinispan, but more importantly improves redundancy as there is no need to replicate the
ownership information in case of node failure.
With this in mind, we can see that virtual nodes are an ideal solution to the distribution of nodes problem, as
it allows the location of an entry to be determined algorithmically.
Infinispan implements virtual nodes by altering the algorithm for splitting the hash space whenever a node
joins or leaves the grid. Rather than allocating a block of the hashspace to the node, it allocates a number of
blocks from throughout the hash space.
Often it's easier to understand the topology changes that virtual nodes introduce through diagrams.

JBoss Community Documentation

Page 189 of 617

Infinispan 6.0

Figure: Topology Without Virtual Nodes

JBoss Community Documentation

Page 190 of 617

Infinispan 6.0

Figure: Topology With Virtual Nodes


To use virtual nodes, simply set the number of virtual nodes higher than one. For example

<namedCache name="cacheWithVirtualNodes">
<clustering>
<hash numVirtualNodes="10" />
</clustering>
</namedCache>

Alternatively, you can enable virtual nodes programmatically

new ConfigurationBuilder()
.clustering()
.hash()
.numVirtualNodes(10)
.build();

JBoss Community Documentation

Page 191 of 617

Infinispan 6.0
TODO Add notes on how to select number of virtual nodes.

3.30.6 L1 Caching
To prevent repeated remote calls when doing multiple GETs, L1 caching can be enabled. L1 caching places
remotely received values in a near cache for a short period of time (configurable) so repeated lookups would
not result in remote calls. In the above diagram, if L1 was enabled, a subsequent GET for the same key on
Server3 would not result in any remote calls.

Figure 4. L1 caching
L1 caching is not free though. Enabling it comes at a cost, and this cost is that every time a key is updated,
an invalidation message needs to be multicast to ensure nodes with the entry in L1 invalidates the entry. L1
caching causes the requesting node to cache the retrieved entry locally and listen for changes to the key on
the wire. L1-cached entries are given an internal expiry to control memory usage. Enabling L1 will improve
performance for repeated reads of non-local keys, but will increase memory consumption to some degree. It
offers a nice tradeoff between the "read-mostly" performance of an invalidated data grid with the scalability
of a distributed one. Is L1 caching right for you? The correct approach is to benchmark your application with
and without L1 enabled and see what works best for your access pattern.

JBoss Community Documentation

Page 192 of 617

Infinispan 6.0

Looking for Buddy Replication? Buddy Replication - from JBoss Cache - does not exist in
Infinispan. See this blog article which discusses the reasons why Buddy Replication was not
implemented in Infinispan, and how the same effects can be achieved using Infinispan <a
href="http://infinispan.blogspot.com/2009/08/distribution-instead-of-buddy.html">http://infinispan.blogspot.co

3.31 Using Infinispan as a Spring Cache provider


h1. Introduction

Starting with 3.1 Spring offers a [cache abstraction|<a


href="http://blog.springsource.com/2011/02/23/spring-3-1-m1-caching/">http://blog.springsource.com/2011/02/23/
enabling users to declaratively add caching support to applications via two simple annotations,
{font:monospace}@Cacheable{font} and {font:monospace}@CacheEvict{font}. While out of the box
Spring 3.1's caching support is backed by [Ehcache|<a
href="http://ehcache.org/">http://ehcache.org/</a>] it has been designed to easily support
different cache providers. To that end Spring 3.1 defines a simple and straightforward SPI other
caching solutions may implement. Infinispan's very own spring module does - amongst other things
- exactly this and therefore users invested in Spring's programming model may easily have all
their caching needs fulfilled through Infinispan. Here's how.
(Note that the following is based on a small but fully functional example that is part of Spring
Infinispan's test suite. For further details you are encouraged to look at
{font:monospace}org.infinispan.spring.provider.sample.CachingBookDaoContextTest{font} and its
ilk.)
h1. Activating Spring Cache support
You activate Spring's cache support via putting
{code:xml}
<beans xmlns="<a
href="http://www.springframework.org/schema/beans">http://www.springframework.org/schema/beans</a>"
xmlns:xsi="<a
href="http://www.w3.org/2001/XMLSchema-instance">http://www.w3.org/2001/XMLSchema-instance</a>"
xmlns:cache="<a
href="http://www.springframework.org/schema/cache">http://www.springframework.org/schema/cache</a>"
xsi:schemaLocation="
<a
href="http://www.springframework.org/schema/beans">http://www.springframework.org/schema/beans</a>

<a
href="http://www.springframework.org/schema/beans/spring-beans.xsd">http://www.springframework.org/schema/bean
<a
href="http://www.springframework.org/schema/cache">http://www.springframework.org/schema/cache</a>

<a
href="http://www.springframework.org/schema/cache/spring-cache.xsd">http://www.springframework.org/schema/cach
<cache:annotation-driven />
</beans>

JBoss Community Documentation

Page 193 of 617

Infinispan 6.0
somewhere in your application context. This will tell Spring to be on the lookout for
{font:monospace}@Cacheable{font} and {font:monospace}@CacheEvict{font} within your application
code.Now, assuming you've already {font:monospace}infinispan.jar{font} and its dependencies on your
classpath, all that's left to do is installing {font:monospace}infinispan-spring{font} and
{font:monospace}spring{font}. For maven users this translates into

<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>3.1.0.M1</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.infinispan</groupId>
<artifactId>infinispan-spring</artifactId>
<version>5.0.0</version>
<scope>compile</scope>
</dependency>

{font:monospace}Gradle{font} users will most likely know how to adapt this to their needs. Those leaning
towards a more ... pedestrian way of managing their dependencies will need to download
{font:monospace}Spring 3.1.0 M1{font} and install it manually alongside
{font:monospace}infinispan-spring.jar{font} from the Infinispan distribution.h1. Telling Spring to use Infinispan
as its caching providerSpring 3.1's cache provider SPI comprises two interfaces,
{font:monospace}org.springframework.cache.CacheManager{font} and
{font:monospace}org.springframework.cache.Cache{font} where a {font:monospace}CacheManager{font}
serves as a factory for named {font:monospace}Cache{font} instances. By default Spring will look at runtime
for a {font:monospace}CacheManager{font} implementation having the bean name "cacheManager" in an
application's application context. So by putting

<!-- Infinispan cache manager -->


<bean id="cacheManager"
class="org.infinispan.spring.provider.SpringEmbeddedCacheManagerFactoryBean"
p:configurationFileLocation="classpath:/org/infinispan/spring/provider/sample/books-infinispan-config.xml"
/>

somewhere in your application context you tell Spring to henceforth use Infinispan as its caching provider.h1.
Adding caching to your application codeAs outlined above enabling caching in your application code is as
simple as adding {font:monospace}@Cacheable{font} and {font:monospace}@CacheEvict{font} to select
methods. Suppose you've got a DAO for, say, books and you want book instances to be cached once
they've been loaded from the underlying database using {font:monospace}BookDao#findBook(Integer
bookId){font}. To that end you annotate {font:monospace}findBook(Integer bookId){font} with
{font:monospace}@Cacheable{font}, as in

@Transactional
@Cacheable(value = "books", key = "#bookId")
Book findBook(Integer bookId) {...}

JBoss Community Documentation

Page 194 of 617

Infinispan 6.0
This will tell Spring to cache Book instances returned from calls to {font:monospace}findBook(Integer
bookId){font} in a named cache "books", using the parameter's "bookId" value as a cache key. Here,
"#bookId" is an expression in the [Spring Expression Language|
http://static.springsource.org/spring/docs/current/spring-framework-reference/html/expressions.html] that
evaluates to the {font:monospace}bookId{font} argument. If you don't specify the {font:monospace}key{font}
attribute Spring will generate a hash from the supplied method arguments - in this case only
{font:monospace}bookId{font} - and use that as a cache key. Essentially, you relinquish control over what
cache key to use to Spring. Which may or may not be fine depending on your application's needs.Though
the notion of actually deleting a book will undoubtedly seem alien and outright abhorrent to any sane reader
there might come the time when your application needs to do just that. For whatever reason. In this case you
will want for such a book to be removed not only from the underlying database but from the cache, too. So
you annotate {font:monospace}deleteBook(Integer bookId){font} with {font:monospace}@CacheEvict{font} as
in

@Transactional
@CacheEvict(value = "books", key = "#bookId")
void deleteBook(Integer bookId) {...}

and you may rest assured that no stray books be left in your application once you decide to remove them.h1.
OutroHopefully you enjoyed our quick tour of Infinispan's support for Spring's cache abstraction and saw
how easy it is for all your caching woes to be taken care of by Infinispan. More information may be found in
Spring's as usual rather excellent [reference documentation|
http://static.springsource.org/spring/docs/3.1.0.M1/spring-framework-reference/html/cache.html] and
[javadocs|

http://static.springsource.org/spring/docs/3.1.0.M1/javadoc-api/index.html?org/springframework/cache/package-summary.h
]. Also see [this|http://blog.springsource.com/2011/02/23/spring-3-1-m1-caching/] very nice posting on the
official Spring blog for a somewhat more comprehensive introduction to Spring's cache abstraction.{code}

3.32 Note: This page is obsolete. Please refer to


Infinispan Distributed Execution Framework .
3.33 Invocation Flags
An important aspect of getting the most of Infinispan is the use of per-invocation flags in order to provide
specific behaviour to each particular cache call. By doing this, some important optimizations can be
implemented potentially saving precious time and network resources. One of the most popular usages of
flags can be found right in Cache API, underneath the putForExternalRead() method which is used to load
an Infinispan cache with data read from an external resource. In order to make this call efficient, Infinispan
basically calls a normal put operation passing the following flags: FAIL_SILENTLY,
FORCE_ASYNCHRONOUS, ZERO_LOCK_ACQUISITION_TIMEOUT

JBoss Community Documentation

Page 195 of 617

Infinispan 6.0
What Infinispan is doing here is effectively saying that when putting data read from external read, it will use
an almost-zero lock acquisition time and that if the locks cannot be acquired, it will fail silently without
throwing any exception related to lock acquisition. It also specifies that regardless of the cache mode, if the
cache is clustered, it will replicate asynchronously and so won't wait for responses from other nodes. The
combination of all these flags make this kind of operation very efficient, and the efficiency comes from the
fact this type of putForExternalRead calls are used with the knowledge that client can always head back to a
persistent store of some sorts to retrieve the data that should be stored in memory. So, any attempt to store
the data is just a best effort and if not possible, the client should try again if there's a cache miss.

3.33.1 Examples
If you want to use these or any other flags available, which by the way are described in detail the Flag
enumeration, you simply need to get hold of the advanced cache and add the flags you need via the
withFlags() method call. For example:

Cache cache = ...


cache.getAdvancedCache()
.withFlags(Flag.SKIP_CACHE_STORE, Flag.CACHE_MODE_LOCAL)
.put("local", "only");

It's worth noting that these flags are only active for the duration of the cache operation. If the same flags
need to be used in several invocations, even if they're in the same transaction, withFlags() needs to be
called repeatedly. Clearly, if the cache operation is to be replicated in another node, the flags are carried
over to the remote nodes as well.

3.33.2 DecoratedCache
Another approach would be to use the DecoratedCache wrapper. This allows you to reuse flags. For
example:

AdvancedCache cache = ...


DecoratedCache strictlyLocal
Flag.SKIP_CACHE_STORE);
strictlyLocal.put("local_1",
strictlyLocal.put("local_2",
strictlyLocal.put("local_3",

= new DecoratedCache(cache, Flag.CACHE_MODE_LOCAL,


"only");
"only");
"only");

This approach makes your code more readable.

JBoss Community Documentation

Page 196 of 617

Infinispan 6.0

3.33.3 Suppressing return values from a put() or remove()


Another very important use case is when you want a write operation such as put() to not return the previous
value. To do that, you need to use two flags to make sure that in a distributed environment, no remote
lookup is done to potentially get previous value, and if the cache is configured with a cache loader, to avoid
loading the previous value from the cache store. You can see these two flags in action in the following
example:

Cache cache = ...


cache.getAdvancedCache()
.withFlags(Flag.SKIP_REMOTE_LOOKUP, Flag.SKIP_CACHE_LOAD)
.put("local", "only")

For more information, please check the Flag enumeration javadoc.

3.34 Key affinity service


3.34.1 Introduction
The key affinity service solves the following problem: for a distributed Infinispan cluster one wants to make
sure that a value is placed in a certain node. Based on a supplied cluster address identifying the node, the
service returns a key that will be hashed to that particular node.

JBoss Community Documentation

Page 197 of 617

Infinispan 6.0

3.34.2 API
Following code snippet depicts how a reference to this service can be obtained and used.

//1. obtain a reference to a cache manager


EmbeddedCacheManager cacheManager = getCacheManager();//obtain a reference to a cache manager
Cache cache = cacheManager.getCache();
//2. create the affinity service
KeyAffinityService keyAffinityService =
KeyAffinityServiceFactory.newLocalKeyAffinityService(cache, new RndKeyGenerator(),
Executors.newSingleThreadExecutor(), 100);
//3. obtain a key to be mapped to a certain address
Object localKey = keyAffinityService.getKeyForAddress(cacheManager.getAddress());
//4. this put makes sure that the key resigns on the local node (as obtained
cacheManager.getAddress())
cache.put(localKey, "yourValue");

The service is started at step 2: after this point it uses the supplied Excutor to generate and queue keys. At
step 3, we obtain a key for this service, and use it at step 4, with that guarantee that it is distributed in node
identified by cacheManager.getAddress().

3.34.3 Lifecycle
KeyAffinityService extends Lifecycle, which allows stopping and (re)starting it:

public interface Lifecycle {


void start();
void stop();
}

The service is instantiated through KeyAffinityServiceFactory. All the factory method have an Executors
parameter, that is used for asynchronous key generation (so that it won't happen in the caller's thread). It is
user's responsibility to handle the shutdown of this Executor.
The KeyAffinityService, once started, needs to be explicitly stopped. This stops the async key generation
and releases other held resources.
The only situation in which KeyAffinityService stops by itself is when the cache manager with wich it was
registered is shutdown.

JBoss Community Documentation

Page 198 of 617

Infinispan 6.0

3.34.4 Topology changes


When a topology change takes place the key ownership from the KeyAffinityService might change. The key
affinity service keep tracks of these topology changes and updates and doesn't return stale keys, i.e. keys
that would currently map to a different node than the one specified. However, this does not guarantee that at
the time the key is used its node affinity hasn't changed, e.g.:
- thread T1 reads a key k1 that maps to node A
- a topology change happens which makes k1 map to node B
- T1 uses k1 to add something to the cache. At this point k1 maps to B, different node than the one
requested at the time of read.
Whilst this is not ideal, it should be a supported behaviour for the application as all the already in-use keys
might me moved over during cluster change. The KeyAffinityService provides an access proximity
optimisation for stable clusters which doesn't apply during topology changes.

3.35 Transaction recovery


3.35.1
When to use recovery
How does it work
Configuring recovery
Enable JMX support
Recovery cache
Integration with the TM
Re-conciliate state
Force commit/rollback based on XID
Want to know more?

3.35.2 When to use recovery


Consider a distributed transaction in which money are transfered from an account stored in the database to
an account stored in Infinispan. When TransactionManager.commit() is invoked, both resources prepare
successfully(1st phase). During commit (2nd phase), the database successfully applies the changes whilst
Infinispan fails before receiving the commit request from the TransactionManager. At this point the system is
in an inconsistent state: money are taken from the datbase account but not visible yet in Infinispan(locks are
only released during 2nd phase of 2PC). Recovery deals with this situation to make sure data in both the
database and Infinispan ends up in a consistent state.

JBoss Community Documentation

Page 199 of 617

Infinispan 6.0

3.35.3 How does it work


Recovery is coordinated by the TransactionManager (TM). The TM works with Infinispan to determine the list
of in-doubt transactions that require manual intervention and informs the system administrator (SA) (email,
logs). This process is TM specific, but generally requires some configuration on TM's side.
Knowing the in-doubt transaction ids, the SA can now connect to the Infinispan cluster and replay the
commit of transactions or force the rollback. Infinispan provides JMX tooling for this - this is explained
extensively in the Reconciliate state section.

JBoss Community Documentation

Page 200 of 617

Infinispan 6.0

3.35.4 Configuring recovery


Recovery is not enabled by default in Infinispan. If disabled the TransactionManager won't be able to work
with Infinispan to determine the in-doubt transactions. In order to enable recovery through xml configuration:

<transaction useEagerLocking="true" eagerLockSingleNode="true">


<recovery enabled="true" recoveryInfoCacheName="noRecovery"/>
</transaction>

Note: the recoveryInfoCacheName attribute is not mandatory. More information about it can be found in the
Recovery Cache section below.
Alternatively you can enable it through the fluent configuration API as follows:

//simply calling .recovery() enables it


configuration.fluent().transaction().recovery();
//then you can disable it
configuration.fluent().transaction().recovery().disable();
//or just check its status
boolean isRecoveryEnabled = configuration.isTransactionRecoveryEnabled();

Recovery can be enabled/disabled o a per cache level: e..g it is possible to have a transaction spanning a
cache that is has it enabled and another one that doesn't.

Enable JMX support


Important: In order to be able to use JMX for managing recovery JMX support must be explicitly enabled.
More about enabling JMX here.

Recovery cache
In order to track in-doubt transactions and be able to reply them Infinispan caches all transaction state for
future use. This state is held only for in-doubt transaction, being removed for successfully completed
transactions after the commit/rollback phase completed.
This in-doubt transaction data is held within a local cache: this allows one to configure swapping this info to
disk through cache loader in the case it gets too big. This cache can be specified through the
"recoveryInfoCacheName" configuration attribute. If not specified infinispan will configure a local cache for
you.
It is possible (though not mandated) to share same recovery cache between all the Infinispan caches that
have recovery enabled. If default recovery cache is overridden then the specified recovery cache must use
a TransactionManagerLookup that returns a different TM than the one used by the cache itself.

JBoss Community Documentation

Page 201 of 617

Infinispan 6.0

3.35.5 Integration with the TM


Even though this is TM specific, generally the TM would need a reference to a XAResource imlementation in
order to run XAResource.recover on it. In order to obtain a reference to a Infinispan XAResource following
API can be used:

XAResource xar = cache.getAdvancedCache().getXAResource();

Note: It is a common practice to run the recovery in a different process than the one running the transaction.
At the moment it is not possible to do this with infinispan: the recovery must be run from the same process
where the infinispan instance exists. This limitation will be dropped once ransactions over HotRod are
available.

3.35.6 conciliate state


The TM informs the SA on in-doubt transaction in a proprietary way. At this stage it is assumed that the SA
knows transaction's XID (byte array).
A normal recovery flow is:
1. SA connects to an Infinispan server through JMX, and lists the in doubt transactions
The image below is taken with JCosole connecting to an Infinispan node that has an in doubt transaction.

The status of each in-doubt transaction is displayed(in this example "PREPARED"). There might be multiple
elements in the status field, e.g. "PREPARED" and "COMMITTED" in the case the transaction committed on
certain nodes but not on all of them.
2. SA visually maps the XID received from the TM to an Infinispna internal id, represented as a number. This
step is needed because the XID, a byte array, cannot conveniently be passed to the JMX tool (e.g.
JConsole) and then re-assembled on infinispan's side.
3. SA forces the transaction's commit/rollback through the corresponding jmx operation, based on the
internal id.
The image below is obtained by forcing the commit of the transaction based on its internal id.

JBoss Community Documentation

Page 202 of 617

Infinispan 6.0

Note: All JMX operations described above can be executed on any node, disregarding where the transaction
originated.

Force commit/rollback based on XID


XID-based JMX operations for forcing in-doubt transactions' commit/rollback are available as well: these
methods receive byte[] arrays describing the XID instead of the number associated with the transactions (as
previously described at step 2). These can be useful e.g. if one wants to set up an automatic completion job
for certain in-doubt transactions. This process is plugged into TM's recovery and has access to the TM's XID
objects.

3.35.7 Want to know more?


The [recovery design document] describes in more detail the insides of transaction recovery implementation.

3.36 Implementing standalone JPA JTA Hibernate


application outside J2EE server using Infinispan 2nd
level cache
Introduction
JBoss Transactions
JOTM
Bitronix
Atominkos

JBoss Community Documentation

Page 203 of 617

Infinispan 6.0

3.36.1 Introduction
IMPORTANT NOTE: From Hibernate 4.0.1 onwards, Infinispan now interacts as a synchronization
rather than as an XA resource with the transaction manager when used as second-level cache, so
there's no longer need to apply any of the changes suggested below!
Infinispans predecessor JBossCache requires integration with JTA when used as 2L-cache for a Hibernate
application. At the moment of writing this article (Hibernate 3.5.0.Beta3) also Infinspan requires integration
with JTA. Hibernate integrated with JTA is already largely used in EJB applications servers, but most users
using Hibernate with Java SE outside any EJB container, still use the plain JDBC approach instead to use
JTA.
According Hiberante documentation it should also possible to integrate JTA in a standalone application
outside any EJB container, but I did hardly find any documentation how to do that in detail. (probably the
reason is, that probably 95% of people is using hibernate within a EJB app. server or using SPRING). This
article should give you some example how to realize a standalone Hibernate app. outside of a EJB container
with JTA integration (and using Infinispan 2nd level cache).
As first thing you have to choose which implementation of TransactionManager to take. This article comes
with examples for following OpenSource TransactionManagers:
1. JBoss
2. JOTM
3. Bitronix
4. Atomikos

Datasource/Transaction interaction
A very important aspect is not forgetting to couple the datasource with your transaction manager. In
other words, the corresponding XAResource must be onto the transaction manager, otherwise only
DML-statements but no commits/rollbacks are propagated to your database.

3.36.2 JBoss Transactions


The example with JBoss Transactions Transaction Manager was the most complex to implement, as JBoss's
TransactionManager and UserTransaction objects are not declared serializable whilst it's JNDI-server isn't
able to bind non serializable objects out of the box. Special use of NonSerializableFactory is needed,
requiring some additional custom code:

import
import
import
import
import

hello.A; // a persistent class


java.io.Serializable;
java.sql.Connection;
java.sql.SQLException;
java.util.Properties;

JBoss Community Documentation

Page 204 of 617

Infinispan 6.0

import
import
import
import
import
import
import
import
import
import

javax.naming.Context;
javax.naming.InitialContext;
javax.naming.Name;
javax.naming.NameNotFoundException;
javax.naming.Reference;
javax.naming.StringRefAddr;
javax.persistence.EntityManager;
javax.persistence.Persistence;
javax.transaction.TransactionManager;
javax.transaction.UserTransaction;

import
import
import
import
import
import
import
import
import
import

org.enhydra.jdbc.standard.StandardXADataSource;
org.hibernate.Session;
org.hibernate.SessionFactory;
org.hibernate.ejb.HibernateEntityManagerFactory;
org.hibernate.transaction.JBossTransactionManagerLookup;
org.infinispan.transaction.lookup.JBossStandaloneJTAManagerLookup;
org.jboss.util.naming.NonSerializableFactory;
org.jnp.interfaces.NamingContext;
org.jnp.server.Main;
org.jnp.server.NamingServer;

public class JTAStandaloneExampleJBossTM

static JBossStandaloneJTAManagerLookup _ml =

new JBossStandaloneJTAManagerLookup();

public static void main(String[] args) {


try {
// Create an in-memory jndi
NamingServer namingServer = new NamingServer();
NamingContext.setLocal(namingServer);
Main namingMain = new Main();
namingMain.setInstallGlobalService(true);
namingMain.setPort(-1);
namingMain.start();
Properties props = new Properties();
props.put(Context.INITIAL_CONTEXT_FACTORY,
"org.jnp.interfaces.NamingContextFactory");
props.put("java.naming.factory.url.pkgs", "org.jboss.naming:org.jnp.interfaces");
InitialContext ictx = new InitialContext( props );

// as JBossTransactionManagerLookup extends JNDITransactionManagerLookup we must


also register the TransactionManager
bind("java:/TransactionManager", _ml.getTransactionManager(),
_ml.getTransactionManager().getClass(), ictx);

// also the UserTransaction must be registered on jndi:


org.hibernate.transaction.JTATransactionFactory#getUserTransaction() requires this
bind(new
JBossTransactionManagerLookup().getUserTransactionName(),_ml.getUserTransaction(),_ml.getUserTransaction().get
ictx);
ExtendedXADataSource xads = new ExtendedXADataSource();

JBoss Community Documentation

Page 205 of 617

Infinispan 6.0
xads.setDriverName("org.hsqldb.jdbcDriver");
xads.setDriverName("com.p6spy.engine.spy.P6SpyDriver"); // comment this line if you
don't want p6spy-logging
xads.setUrl("jdbc:hsqldb:hsql://localhost");
//xads.setTransactionManager(_ml.getTransactionManager()); useless here as this
information is not serialized
ictx.bind("java:/MyDatasource", xads);
final HibernateEntityManagerFactory emf =
Persistence.createEntityManagerFactory("helloworld");

(HibernateEntityManagerFactory)

UserTransaction userTransaction = _ml.getUserTransaction();


userTransaction.setTransactionTimeout(300000);
//SessionFactory sf = (SessionFactory)
ictx.lookup("java:/hibernate/MySessionFactory"); // if hibernate.session_factory_name set
final SessionFactory sf = emf.getSessionFactory();
userTransaction.begin();
EntityManager em = emf.createEntityManager();
// do here your persistent work
A a = new A();
a.name= "firstvalue";
em.persist(a);
em.flush();
// do manually flush here as apparently FLUSH_BEFORE_COMPLETION
seems not work, bug ?
System.out.println("\nCreated and flushed instance a with id : " + a.oid + "
set to:" + a.name);

a.name

System.out.println("Calling userTransaction.commit() (Please check if the commit is


effectively executed!)");
userTransaction.commit();

ictx.close();
namingMain.stop();
emf.close();
} catch (Exception e) {
e.printStackTrace();
}
System.exit(0);
}
public static class ExtendedXADataSource extends StandardXADataSource { // XAPOOL
@Override
public Connection getConnection() throws SQLException {
if (getTransactionManager() == null) { // although already set before, it results
null again after retrieving the datasource by jndi
TransactionManager tm; // this is because the TransactionManager information is
not serialized.
try {
tm = _ml.getTransactionManager();
} catch (Exception e) {

JBoss Community Documentation

Page 206 of 617

Infinispan 6.0
throw new SQLException(e);
}
setTransactionManager(tm); //
retrieved by jndi,
//
}

resets the TransactionManager on the datasource


this makes the datasource JTA-aware

// According to Enhydra documentation, here we must return the connection of our


XAConnection

// see
http://cvs.forge.objectweb.org/cgi-bin/viewcvs.cgi/xapool/xapool/examples/xapooldatasource/DatabaseHelper.java
return super.getXAConnection().getConnection();
}
}
/**
* Helper method that binds the a non serializable object to the JNDI tree.
*
* @param jndiName Name under which the object must be bound
* @param who Object to bind in JNDI
* @param classType Class type under which should appear the bound object
* @param ctx Naming context under which we bind the object
* @throws Exception Thrown if a naming exception occurs during binding
*/
private static void bind(String jndiName, Object who, Class classType, Context ctx) throws
Exception {
// Ah ! This service isn't serializable, so we use a helper class
NonSerializableFactory.bind(jndiName, who);
Name n = ctx.getNameParser("").parse(jndiName);
while (n.size() > 1) {
String ctxName = n.get(0);
try {
ctx = (Context) ctx.lookup(ctxName);
} catch (NameNotFoundException e) {
System.out.println("Creating subcontext:" + ctxName);
ctx = ctx.createSubcontext(ctxName);
}
n = n.getSuffix(1);
}
// The helper class NonSerializableFactory uses address type nns, we go on to
// use the helper class to bind the service object in JNDI
StringRefAddr addr = new StringRefAddr("nns", jndiName);
Reference ref = new Reference(classType.getName(), addr,
NonSerializableFactory.class.getName(), null);
ctx.rebind(n.get(0), ref);
}
private static void unbind(String jndiName, Context ctx) throws Exception {
NonSerializableFactory.unbind(jndiName);
ctx.unbind(jndiName);
}
}

The content of the corresponding complete persistence.xml:

JBoss Community Documentation

Page 207 of 617

Infinispan 6.0

<persistence xmlns="http://java.sun.com/xml/ns/persistence"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/persistence
http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd" version="1.0">
<persistence-unit name="helloworld" transaction-type="JTA">
<jta-data-source>java:/MyDatasource</jta-data-source>
<properties>
<property name="hibernate.hbm2ddl.auto" value = "create"/>
<property name="hibernate.archive.autodetection" value="class, hbm"/>
<property name="hibernate.dialect" value="org.hibernate.dialect.HSQLDialect"/>
<property name="hibernate.jndi.class"
value="org.jnp.interfaces.NamingContextFactory"/>
<property name="hibernate.transaction.manager_lookup_class"
value="org.hibernate.transaction.JBossTransactionManagerLookup"/>
<property name="current_session_context_class" value="jta"/>
<!-- <property name="hibernate.session_factory_name"
value="java:/hibernate/MySessionFactory"/> optional -->
<property name="hibernate.transaction.factory_class"
value="org.hibernate.transaction.JTATransactionFactory"/>
<property name="hibernate.connection.release_mode" value="auto"/>
<!-- setting above is important using XA-DataSource on SQLServer,
otherwise SQLServerException: The function START: has failed. No transaction
cookie was returned.-->
<property name="hibernate.cache.use_second_level_cache" value="true"/>
<property name="hibernate.cache.use_query_cache" value="true"/>
<property name="hibernate.cache.region.factory_class"
value="org.hibernate.cache.infinispan.InfinispanRegionFactory"/>
</properties>
</persistence-unit>
</persistence>

3.36.3 JOTM
The example with JOTM is more simple, but apparently it's JNDI implementation is not useable without
wasting any rmi port. So it is not completely 'standalone' as the JNDI service is exposed outside your virtual
machine.

import hello.A; // a persistent class


import java.sql.Connection;
import java.sql.SQLException;
import java.util.Properties;
import javax.naming.Context;
import javax.naming.InitialContext;

JBoss Community Documentation

Page 208 of 617

Infinispan 6.0
import
import
import
import
import

javax.persistence.EntityManager;
javax.persistence.EntityManagerFactory;
javax.persistence.Persistence;
javax.transaction.TransactionManager;
javax.transaction.UserTransaction;

import
import
import
import

org.enhydra.jdbc.standard.StandardXADataSource;
org.hibernate.transaction.JOTMTransactionManagerLookup;
org.objectweb.jotm.Jotm;
org.objectweb.transaction.jta.TMService;

public class JTAExampleJOTM {


static JOTMTransactionManagerLookup _ml =

new JOTMTransactionManagerLookup();

public static class ExtendedXADataSource extends StandardXADataSource { // XAPOOL


@Override
public Connection getConnection() throws SQLException {
if (getTransactionManager() == null) { // although already set before, it results
null again after retrieving the datasource by jndi
TransactionManager tm; // this is because the TransactionManager information is
not serialized.
try {
tm = _ml.getTransactionManager(null);
} catch (Exception e) {
throw new SQLException(e);
}
setTransactionManager(tm); // resets the TransactionManager on the datasource
retrieved by jndi,
// this makes the datasource JTA-aware
}
// According to Enhydra documantation, here we must return the connection of our
XAConnection

// see
http://cvs.forge.objectweb.org/cgi-bin/viewcvs.cgi/xapool/xapool/examples/xapooldatasource/DatabaseHelper.java
return super.getXAConnection().getConnection();
}
}

public static void main( String[] args )


{
try
{
java.rmi.registry.LocateRegistry.createRegistry(1099); // also possible to lauch by
command line rmiregistry
System.out.println("RMI registry ready.");

// following properties can be left out if specifying thes values in a file


jndi.properties located into classpath
Properties props = new Properties();
props.put(Context.INITIAL_CONTEXT_FACTORY,
"org.ow2.carol.jndi.spi.MultiOrbInitialContextFactory");
InitialContext jndiCtx = new InitialContext(props);

JBoss Community Documentation

Page 209 of 617

Infinispan 6.0

// XAPOOL
ExtendedXADataSource xads = new ExtendedXADataSource();
xads.setDriverName("org.hsqldb.jdbcDriver");
xads.setDriverName("com.p6spy.engine.spy.P6SpyDriver");
xads.setUrl("jdbc:hsqldb:hsql://localhost");
jndiCtx.bind("java:/MyDatasource", xads);

/* startup JOTM */
TMService jotm = new Jotm(true, false);
jotm.getUserTransaction().setTransactionTimeout(36000); // secs, important JOTM
default is only 60 secs !

/* and get a UserTransaction */


UserTransaction userTransaction = jotm.getUserTransaction();

jndiCtx.bind("java:comp/UserTransaction", jotm.getUserTransaction()); // this is


needed by hibernates JTATransactionFactory
/* get the Hibernate SessionFactory */
EntityManagerFactory emf =
Persistence.createEntityManagerFactory("helloworld");
//SessionFactory sf = (SessionFactory)
jndiCtx.lookup("java:/hibernate/MySessionFactory");
// begin a new Transaction
userTransaction.begin();
EntityManager em = emf.createEntityManager();
A a = new A();
a.name= "firstvalue";
em.persist(a);
em.flush();
// do manually flush here as apparently FLUSH_BEFORE_COMPLETION seems
not work, bug ?
System.out.println("Calling userTransaction.commit() (Please check if the commit is
effectively executed!)");
userTransaction.commit();

// stop the transaction manager


jotm.stop();
jndiCtx.close();
emf.close();

}
catch( Exception e )
{
e.printStackTrace();
}
System.exit(0);
}

JBoss Community Documentation

Page 210 of 617

Infinispan 6.0
}

Adjust following 2 properties in your persistence.xml:

<property name="hibernate.jndi.class"
value="org.ow2.carol.jndi.spi.MultiOrbInitialContextFactory"/>
<property name="hibernate.transaction.manager_lookup_class"
value="org.hibernate.transaction.JOTMTransactionManagerLookup"/>

For using the JTA Hibernate application as servlet in tomcat please read
http://jotm.objectweb.org/current/jotm/doc/howto-tomcat-jotm.html and also
https://forum.hibernate.org/viewtopic.php?f=1&t=1003866

3.36.4 Bitronix
The Transaction Manager comes bundled with a fake in memory jndi-implementation which is ideal for
standalone purpose. To integrate with Infinispan I did need a ad-hoc pre-alpha improvement (see attached
btm-ispn.jar by courtesy of Mr. Ludivic Orban). BitronixTM offers the so-called Last Resource Commit
optimization (aka Last Resource Gambit or Last Agent optimization) and it allows a single non-XA database
to participate in a XA transaction by cleverly ordering the resources. "Last Resource Commit" is not part of
the XA spec as it doesn't cover the transaction-recovery aspect, so if your database does not support XA (or
if you don't wish to have the Xa-driver performance overhead against the plain jdbc) then the "Last Resource
Commit" feature should be ideal for the combination 1 single database plus infinispan.

import hello.A; // a persistent class


import java.util.Properties;
import
import
import
import
import

javax.naming.Context;
javax.naming.InitialContext;
javax.persistence.EntityManager;
javax.persistence.Persistence;
javax.transaction.UserTransaction;

import
import
import
import

org.hibernate.cache.infinispan.InfinispanRegionFactory;
org.hibernate.ejb.HibernateEntityManagerFactory;
org.hibernate.impl.SessionFactoryImpl;
org.infinispan.manager.CacheManager;

import bitronix.tm.resource.ResourceRegistrar;
import bitronix.tm.resource.infinispan.InfinispanCacheManager;
import bitronix.tm.resource.jdbc.PoolingDataSource;

public class JTAExampleBTM {


public static void main(String[] args) {
try {
Properties props = new Properties();
props.put(Context.INITIAL_CONTEXT_FACTORY,

JBoss Community Documentation

Page 211 of 617

Infinispan 6.0
"bitronix.tm.jndi.BitronixInitialContextFactory");
// Attention: BitronixInitialContextFactory is'nt a real jndi implementation: you
can't do explicit bindings
// It is ideal for hiberante standalone usage, as it automatically 'binds' the
needed things: datasource + usertransaction
System.out.println("create initial context");
InitialContext ictx = new InitialContext(props);
PoolingDataSource myDataSource = new PoolingDataSource();
myDataSource.setClassName("bitronix.tm.resource.jdbc.lrc.LrcXADataSource");
myDataSource.setMaxPoolSize(5);
myDataSource.setAllowLocalTransactions(true);
myDataSource.getDriverProperties().setProperty("driverClassName",
"com.p6spy.engine.spy.P6SpyDriver");
myDataSource.getDriverProperties().setProperty("url",
"jdbc:hsqldb:hsql://localhost");
myDataSource.getDriverProperties().setProperty("user", "sa");
myDataSource.getDriverProperties().setProperty("password", "");
myDataSource.setUniqueName("java:/MyDatasource");
myDataSource.setAutomaticEnlistingEnabled(true); // important to keep it to true
(default), otherwise commits/rollbacks are not propagated
myDataSource.init(); // does also register the datasource on the Fake-JNDI with
Unique Name
org.hibernate.transaction.BTMTransactionManagerLookup lokhiberante = new
org.hibernate.transaction.BTMTransactionManagerLookup();
HibernateEntityManagerFactory emf = (HibernateEntityManagerFactory)
Persistence.createEntityManagerFactory("helloworld");
SessionFactoryImpl sfi = (SessionFactoryImpl) emf.getSessionFactory();
InfinispanRegionFactory infinispanregionfactory = (InfinispanRegionFactory)
sfi.getSettings().getRegionFactory();
CacheManager manager = infinispanregionfactory.getCacheManager();
// register Inifinispan as a BTM resource
InfinispanCacheManager icm = new InfinispanCacheManager();
icm.setUniqueName("infinispan");
ResourceRegistrar.register(icm);
icm.setManager(manager);
final UserTransaction userTransaction = (UserTransaction)
ictx.lookup(lokhiberante.getUserTransactionName());
// begin a new Transaction
userTransaction.begin();
EntityManager em = emf.createEntityManager();
A a = new A();
a.name= "firstvalue";
em.persist(a);
em.flush();
// do manually flush here as apparently FLUSH_BEFORE_COMPLETION
seems not work, bug ?
System.out.println("Calling userTransaction.commit() (Please check if the commit is
effectively executed!)");

JBoss Community Documentation

Page 212 of 617

Infinispan 6.0
userTransaction.commit();
emf.close();
} catch (Exception e) {
e.printStackTrace();
System.exit(1);
}
System.exit(0);
}
}

Adjust following 2 properties in your corresponding persistence.xml:

<property name="hibernate.jndi.class" value="bitronix.tm.jndi.BitronixInitialContextFactory"/>


<property name="hibernate.transaction.manager_lookup_class"
value="org.hibernate.transaction.BTMTransactionManagerLookup"/>

3.36.5 Atominkos
Last but not least, the Atomikos Transaction manager. It is currently the unique Transaction manager I've
found with a online-documentation on how to integrate with Hiberantewithout Spring, outside any J2EE
container.. It seems to be the unique supporting XaDataSource together with Pooling, so it doesn't matter
that It does not come with it's own JNDI implementation (we will use the one of JBoss in following example).

import hello.A; // a persistent class


import
import
import
import

java.io.Serializable;
java.sql.Connection;
java.sql.SQLException;
java.util.Properties;

import
import
import
import
import
import
import
import
import
import

javax.naming.Context;
javax.naming.InitialContext;
javax.naming.Name;
javax.naming.NameNotFoundException;
javax.naming.Reference;
javax.naming.StringRefAddr;
javax.persistence.EntityManager;
javax.persistence.Persistence;
javax.transaction.TransactionManager;
javax.transaction.UserTransaction;

import
import
import
import

org.hibernate.Session;
org.hibernate.SessionFactory;
org.hibernate.ejb.HibernateEntityManagerFactory;
org.hibernate.impl.SessionFactoryImpl;

import org.jboss.util.naming.NonSerializableFactory;

JBoss Community Documentation

Page 213 of 617

Infinispan 6.0
import org.jnp.interfaces.NamingContext;
import org.jnp.server.Main;
import org.jnp.server.NamingServer;
import com.atomikos.icatch.jta.hibernate3.TransactionManagerLookup;
import com.atomikos.jdbc.AtomikosDataSourceBean;
import com.atomikos.jdbc.SimpleDataSourceBean;
public class JTAStandaloneExampleAtomikos

public static void main(String[] args) {


try {
// Create an in-memory jndi
NamingServer namingServer = new NamingServer();
NamingContext.setLocal(namingServer);
Main namingMain = new Main();
namingMain.setInstallGlobalService(true);
namingMain.setPort(-1);
namingMain.start();
Properties props = new Properties();
props.put(Context.INITIAL_CONTEXT_FACTORY,
"org.jnp.interfaces.NamingContextFactory");
props.put("java.naming.factory.url.pkgs", "org.jboss.naming:org.jnp.interfaces");
InitialContext ictx = new InitialContext( props );
AtomikosDataSourceBean ds = new AtomikosDataSourceBean();
ds.setUniqueResourceName("sqlserver_ds");
ds.setXaDataSourceClassName("com.microsoft.sqlserver.jdbc.SQLServerXADataSource");
Properties p = new Properties();
p.setProperty ( "user" , "sa" );
p.setProperty ( "password" , "" );
p.setProperty ( "serverName" , "myserver" );
ds.setXaProperties ( p );
ds.setPoolSize(5);
bind("java:/MyDatasource", ds, ds.getClass(), ictx);
TransactionManagerLookup _ml = new TransactionManagerLookup();
UserTransaction userTransaction = new com.atomikos.icatch.jta.UserTransactionImp();
bind("java:/TransactionManager", _ml.getTransactionManager(null),
_ml.getTransactionManager(null).getClass(), ictx);
bind("java:comp/UserTransaction", userTransaction, userTransaction.getClass(),
ictx);
HibernateEntityManagerFactory emf = (HibernateEntityManagerFactory)
Persistence.createEntityManagerFactory("helloworld");
// begin a new Transaction
userTransaction.begin();
EntityManager em = emf.createEntityManager();
A a = new A();
a.name= "firstvalue";
em.persist(a);
em.flush();
// do manually flush here as apparently FLUSH_BEFORE_COMPLETION
seems not work, bug ?

JBoss Community Documentation

Page 214 of 617

Infinispan 6.0

System.out.println("Calling userTransaction.commit() (Please check if the commit is


effectively executed!)");
userTransaction.commit();
emf.close();
} catch (Exception e) {
e.printStackTrace();
System.exit(1);
}
System.exit(0);
}
/**
* Helper method that binds the a non serializable object to the JNDI tree.
*
* @param jndiName Name under which the object must be bound
* @param who Object to bind in JNDI
* @param classType Class type under which should appear the bound object
* @param ctx Naming context under which we bind the object
* @throws Exception Thrown if a naming exception occurs during binding
*/
private static void bind(String jndiName, Object who, Class<?> classType, Context ctx)
throws Exception {
// Ah ! This service isn't serializable, so we use a helper class
NonSerializableFactory.bind(jndiName, who);
Name n = ctx.getNameParser("").parse(jndiName);
while (n.size() > 1) {
String ctxName = n.get(0);
try {
ctx = (Context) ctx.lookup(ctxName);
} catch (NameNotFoundException e) {
System.out.println("Creating subcontext:" + ctxName);
ctx = ctx.createSubcontext(ctxName);
}
n = n.getSuffix(1);
}
// The helper class NonSerializableFactory uses address type nns, we go on to
// use the helper class to bind the service object in JNDI
StringRefAddr addr = new StringRefAddr("nns", jndiName);
Reference ref = new Reference(classType.getName(), addr,
NonSerializableFactory.class.getName(), null);
ctx.rebind(n.get(0), ref);
}
private static void unbind(String jndiName, Context ctx) throws Exception {
NonSerializableFactory.unbind(jndiName);
ctx.unbind(jndiName);
}
}

Adjust follwing 2 properties in your corresponding persistence.xml:

JBoss Community Documentation

Page 215 of 617

Infinispan 6.0

<property name="hibernate.jndi.class" value="org.jnp.interfaces.NamingContextFactory"/>


<property name="hibernate.transaction.manager_lookup_class"
value="com.atomikos.icatch.jta.hibernate3.TransactionManagerLookup"/>

And create a file named jta.properties in your classpath with following content:

com.atomikos.icatch.service=com.atomikos.icatch.standalone.UserTransactionServiceFactory
com.atomikos.icatch.automatic_resource_registration=false
com.atomikos.icatch.console_log_level=WARN
com.atomikos.icatch.force_shutdown_on_vm_exit=true
com.atomikos.icatch.enable_logging=false

3.37 Infinispan Maven Archetypes


Infinispan currently has 2 separate Maven archetypes you can use to create a skeleton project and get
started using Infinispan. This is an easy way to get started using Infinispan as the archetype generates
sample code, a sample Maven pom.xml with necessary depedencies, etc.

NOTE: You don't need to have any experience with or knowledge of Maven's Archetypes to use this!
Just follow the simple steps below.

Starting a new project


Playing with your new project
On the command line...
Writing a test case for Infinispan
On the command line...
Available profiles
Contributing tests back to Infinispan
Versions
Source Code

WARNING: These archetypes have only been tested with Maven 3. Please report back if you have any
success with using Maven 2.

JBoss Community Documentation

Page 216 of 617

Infinispan 6.0

3.37.1 Starting a new project


Use the newproject-archetype project. The simple command below will get you started, and

$ mvn archetype:generate \
-DarchetypeGroupId=org.infinispan.archetypes \
-DarchetypeArtifactId=newproject-archetype \
-DarchetypeVersion=1.0.13 \
-DarchetypeRepository=http://repository.jboss.org/nexus/content/groups/public

You will be prompted for a few things, including the artifactId , groupId and version of your new project. And
that's it - you're ready to go!

Playing with your new project


The skeleton project ships with a sample application class, interacting with Infinispan. You should open this
new project in your IDE - most good IDEs such as IntelliJ and Eclipse allow you to import Maven projects,
see this guide and this guide. Once you open your project in your IDE, you should examine the generated
classes and read through the comments.

On the command line...


Try running

$ mvn install -Prun

in your newly generated project! This runs the main() method in the generated application class.

3.37.2 Writing a test case for Infinispan


This archetype is useful if you wish to contribute a test to the Infinispan project and helps you get set up to
use Infinispan's testing harness and related tools.
Use

$ mvn archetype:generate \
-DarchetypeGroupId=org.infinispan.archetypes \
-DarchetypeArtifactId=testcase-archetype \
-DarchetypeVersion=1.0.13 \
-DarchetypeRepository=http://repository.jboss.org/nexus/content/groups/public

As above, this will prompt you for project details and again as above, you should open this project in your
IDE. Once you have done so, you will see some sample tests written for Infinispan making use of
Infinispan's test harness and testing tools along with extensive comments and links for further reading.

JBoss Community Documentation

Page 217 of 617

Infinispan 6.0

On the command line...


Try running

$ mvn test

in your newly generated project to run your tests.


The generated project has a few different profiles you can use as well, using Maven's -P flag. E.g.,

$ mvn test -Pudp

Available profiles
The profiles available in the generated sample project are:
udp: use UDP for network communications rather than TCP
tcp: use TCP for network communications rather than UDP
jbosstm: Use the embedded JBoss Transaction Manager rather than Infinispan's dummy test
transaction manager

Contributing tests back to Infinispan


If you have written a functional, unit or stress test for Infinispan and want to contribute this back to Infinispan,
your best bet is to fork the Infinispan sources on GitHub. The test you would have prototyped and tested in
an isolated project created using this archetype can be simply dropped in to Infinispan's test suite. Make
your changes, add your test, prove that it fails even on Infinispan's upstream source tree and issue a pull
request.

TIP: New to working with Infinispan and GitHub? Want to know how best to work with the repositories
and contribute code? Read Infinispan and GitHub

3.37.3 Versions
The archetypes generate poms with dependencies to specific versions of Infinispan. You should edit these
generated poms by hand to point to other versions of Infinispan that you are interested in.

3.37.4 Source Code


The source code used to generate these archetypes are on GitHub. If you wish to enhance and contribute
back to the project, fork away!

JBoss Community Documentation

Page 218 of 617

Infinispan 6.0

3.38 Accessing data in Infinispan via RESTful interface

Standards Red Hat is working towards standardization of the REST API as a part of the REST-*
effort. To participate in this standard, please visit this Google Group

3.38.1 Putting data in


HTTP PUT and POST methods are used to place data in the cache - the data being the body of the request
(the data can be anything you like). It is important that a Content-Type header is set.

PUT /{cacheName}/{cacheKey}
A PUT request of the above URL form will place the payload (body) in the given cache, with the given key
(the named cache must exist on the server). For example http://someserver/hr/payRoll/3 (in which case "hr"
is the cache name, and "payRoll/3" is the key). Any existing data will be replaced, and Time-To-Live and
Last-Modified values etc will updated (if applicable).

POST /{cacheName}/{cacheKey}
Exactly the same as PUT, only if a value in a cache/key already exists, it will return a Http CONFLICT status
(and the content will not be updated).

JBoss Community Documentation

Page 219 of 617

Infinispan 6.0

Headers:
Content-Type: MANDATORY (use media/mime-types for example: "application/json").

Special case
If you set the Content-Type to application/x-java-serialized-object, then it
will be stored as a Java object

performAsync: OPTIONAL true/false (if true, this will return immediately, and then replicate data to
the cluster on its own. Can help with bulk data inserts/large clusters.)
timeToLiveSeconds: OPTIONAL number (the number of seconds before this entry will
automatically be deleted)
If no parameter is sent, Infinispan assumes -1 as default value, which means that the entry will
not expire as a result of ttl. Passing any negative value will have the same effect.
maxIdleTimeSeconds: OPTIONAL number (the number of seconds after last usage of this entry
when it will automatically be deleted)
If no parameter is sent, Infinispan assumes -1 as default value, which means that the entry will
not expire as a result of idle time. Passing any negative value will have the same effect.

Passing 0 as parameter for timeToLiveSeconds and/or maxIdleTimeSeconds

If both timeToLiveSeconds and maxIdleTimeSeconds are 0, the cache will use the
default lifespan and maxIdle values configured in XML/programmatically
If only maxIdleTimeSeconds is 0, it uses the timeToLiveSeconds value passed as
parameter (or -1 if not present), and default maxIdle configured in XML/programmatically
If only timeToLiveSeconds is 0, it uses 0 as timeToLiveSeconds meaning that it will
expire immediately, and maxIdle is set whatever came as parameter (or -1 if not present)

3.38.2 Getting data back out


HTTP GET and HEAD are used to retrieve data from entries.

JBoss Community Documentation

Page 220 of 617

Infinispan 6.0

GET /{cacheName}/{cacheKey}
This will return the data found in the given cacheName, under the given key - as the body of the response. A
Content-Type header will be supplied which matches what the data was inserted as (other then if it is a Java
object, see below). Browsers can use the cache directly of course (eg as a CDN).
An ETag will be returned unique for each entry, as will the Last-Modified and Expires headers field indicating
the state of the data at the given URL. ETags allow browsers (and other clients) to ask for data only in the
case where it has changed (to save on bandwidth) - this is standard HTTP and is honoured by Infinispan.
Since Infinispan 5.3 it is possible to obtain additional information by appending the "extended" parameter on
the query string, as follows:

GET /cacheName/cacheKey?extended

This will return the following custom headers:


Cluster-Primary-Owner: the node name of the primary owner for this key
Cluster-Node-Name: the JGroups node name of the server that has handled the request
Cluster-Physical-Address: the physical JGroups address of the server that has handled the request.
Since version 6.0, the Cache-Control header is supported. The min-fresh directive of this header can be
supplied with a request. A cache entry will then only be returned if it won't expire in min-fresh seconds since
the response creation. A response might contain Cache-Control header with no-transform and max-age
directives. The max-age directive is similar to Expires in that is signifies entry's lifespan. The only difference
is that max-age returns number of seconds relative to the response creation time.

JBoss Community Documentation

Page 221 of 617

Infinispan 6.0

HEAD /{cacheName}/{cacheKey}
The same as GET, only no content is returned (only the header fields). You will receive the same content
that you stored. E.g., if you stored a String, this is what you get back. If you stored some XML or JSON, this
is what you will receive. If you stored a binary (base 64 encoded) blob, perhaps a serialized; Java; object you will need to; deserialize this yourself.

Prior to Infinispan 4.2


The behaviour was as follows:
If the data in the grid is a Java object - there are a few options in how it can be returned, which use
the HTTP Accept header:
application/xml - the object will be serialized via XStream to XML representation
application/json - the object will be sent via a JSON format (via Jackson)
application/x-java-serialized-object - if the object is Serializable, you can use
this and get a stream of the Java Serialization form of the object (obviously only makes
sense for java clients with a suitable class loaded). If its not Serializable, you have to use
one of the other options.

Similarly to the GET method, the HEAD method also supports returning extended information via headers.
See above.

GET /{cacheName}
This will return a list of keys present in the given cacheName as the body of the response. The format of the
response can be controlled via the Accept header as follows:
application/xml - the list of keys will be returned in XML format.
application/json - the list of keys will be return in JSON format.
text/html - the list of keys will be returned in HTML format.
text/plain - the list of keys will be returned in plain text format, one key per line
If the cache identified by cacheName is distributed, only the keys owned by the node handling the request
will be returned. To return all keys, append the "global" parameter to the query, as follows:

GET /cacheName?global

JBoss Community Documentation

Page 222 of 617

Infinispan 6.0

3.38.3 Removing data


Data can be removed at the cache key/element level, or via a whole cache name using the HTTP delete
method.

DELETE /{cacheName}/{cacheKey}
Removes the given key name from the cache.

DELETE /{cacheName}
Removes ALL the entries in the given cache name (ie everything from that path down). If the operation is
successful, it returns 200 code.

Make it quicker!
Set the header performAsync to true to return immediately and let the removal happen in the
background.

3.39 Infinispan Distributed Execution Framework


Introduction
DistributedCallable API
Callable and CDI
DistributedExecutorService, DistributedTaskBuilder and DistributedTask API
Distributed task failover
Distributed task execution policy
Examples

JBoss Community Documentation

Page 223 of 617

Infinispan 6.0

3.39.1 Introduction
Infinispan provides distributed execution through a standard JDK ExecutorService interface. Tasks
submitted for execution, instead of being executed in a local JVM, are executed on an entire cluster of
Infinispan nodes. Every DistributedExecutorService is bound to one particular cache. Tasks submitted will
have access to key/value pairs from that particular cache if and only if the task submitted is an instance of
DistributedCallable. Also note that there is nothing preventing users from submitting a familiar Runnable
or Callable just like to any other ExecutorService. However, DistributedExecutorService, as it name implies,
will likely migrate submitted Callable or Runnable to another JVM in Infinispan cluster, execute it and return
a result to task invoker. Due to a potential task migration to other nodes every
Callable, Runnable and/or DistributedCallable submitted must be either Serializable or Externalizable. Also
the value returned from a callable must be Serializable or Externalizable as well. If the value returned is not
serializable a NotSerializableException will be thrown.
Infinispan's distributed task executors use data from Infinispan cache nodes as input for execution tasks.
Most other distributed frameworks do not have that leverage and users have to specify input for distributed
tasks from some well known location. Furthermore, users of Infinispan distributed execution framework do
not have to configure store for intermediate and final results thus removing another layer of complexity and
maintenance.
Our distributed execution framework capitalizes on the fact input data in Infinispan data grid is already load
balanced (in case of DIST mode). Since input data is already balanced execution tasks will be automatically
balanced as well; users do not have to explicitly assign work tasks to specific Infinispan nodes. However, our
framework accommodates users to specify arbitrary subset of cache keys as input for distributed execution
tasks.

JBoss Community Documentation

Page 224 of 617

Infinispan 6.0

3.39.2 DistributedCallable API


In case users needs access to Infinispan cache data for an execution of a task we recommend that you
encapsulate task in DistributedCallable interface. DistributedCallable is a subtype of the existing Callable
from java.util.concurrent package; DistributedCallable can be executed in a remote JVM and receive input
from Infinispan cache. Task's main algorithm could essentially remain unchanged, only the input source is
changed. Exisiting Callable implementations most likely get its input in a form of some Java object/primitive
while DistributedCallable gets its input from Infinispan cache. Therefore, users who have already
implemented Callable interface to describe their task units would simply extend DistributedCallable and use
keys from Infinispan execution environment as input for the task. Implentation of DistributedCallable can in
fact continue to support implementation of an already existing Callable while simultaneously be ready for
distribited execution by extending DistributedCallable.

public interface DistributedCallable<K, V, T> extends Callable<T> {


/**
* Invoked by execution environment after DistributedCallable
* has been migrated for execution to a specific Infinispan node.
*
* @param cache
*
cache whose keys are used as input data for this
*
DistributedCallable task
* @param inputKeys
*
keys used as input for this DistributedCallable task
*/
public void setEnvironment(Cache<K, V> cache, Set<K> inputKeys);
}

JBoss Community Documentation

Page 225 of 617

Infinispan 6.0

3.39.3 Callable and CDI


Users that do not want or can not implement DistributedCallable yet need a reference to input cache used
in DistributedExecutorService have an option of the input cache being injected by CDI mechanism. Upon
arrival of user's Callable to an Infinispan executing node, Infinispan CDI mechanism will provide appropriate
cache reference and inject it to executing Callable. All one has to do is to declare a Cache field in Callable
and annotate it with org.infinispan.cdi.Input annotation along with mandatory @Inject annotation.

public class CallableWithInjectedCache implements Callable<Integer>, Serializable {


@Inject
@Input
private Cache<String, String> cache;

@Override
public Integer call() throws Exception {
//use injected cache reference
return 1;
}
}

JBoss Community Documentation

Page 226 of 617

Infinispan 6.0

3.39.4 DistributedExecutorService, DistributedTaskBuilder and


DistributedTask API
DistributedExecutorService is a simple extension of a familiar ExecutorService from java.util.concurrent
package. However, advantages of DistributedExecutorService are not to be overlooked. Existing Callable
tasks, instead of being executed in JDK's ExecutorService, are also eligible for execution on Infinispan
cluster. Infinispan execution environment would migrate a task to execution node(s), run the task and return
the result(s) to the calling node. Of course, not all Callable tasks would benefit from parallel distributed
execution. Excellent candidates are long running and computationally intensive tasks that can run
concurrently and/or tasks using input data that can be processed concurrently. For more details about good
candidates for parallel execution and parallel algorithms in general refer to Introduction to Parallel
Computing.
The second advantage of the DistributedExecutorService is that it allows a quick and simple implementation
of tasks that take input from Infinispan cache nodes, execute certain computation and return results to the
caller. Users would specify which keys to use as input for specified DistributedCallable and submit that
callable for execution on Infinispan cluster. Infinispan runtime would locate the appriate keys, migrate
DistributedCallable to target execution node(s) and finally return a list of results for each executed Callable.
Of course, users can omit specifying input keys in which case Infinispan would execute DistributedCallable
on all keys for a specified cache.
Lets see how we can use DistributedExecutorService If you already have Callable/Runnable tasks defined!
Well, simply submit them to an instance of DefaultExecutorService for execution!

ExecutorService des = new DefaultExecutorService(cache);


Future<Boolean> future = des.submit(new SomeCallable());
Boolean r = future.get();

In case you need to specify more task parameters like task timeout, custom failover policy or execution
policy use DistributedTaskBuilder and DistributedTask API.

DistributedExecutorService des = new DefaultExecutorService(cache);


DistributedTaskBuilder<Boolean> taskBuilder = des.createDistributedTaskBuilder(new
SomeCallable());
taskBuilder.timeout(10,TimeUnit.SECONDS);
...
...
DistributedTask<Boolean> distributedTask = taskBuilder.build();
Future<Boolean> future = des.submit(distributedTask);
Boolean r = future.get();

JBoss Community Documentation

Page 227 of 617

Infinispan 6.0

3.39.5 Distributed task failover


Distributed execution framework supports task failover. By default no failover policy is installed and task's
Runnable/Callable/DistributedCallable will simply fail. Failover mechanism is invoked in the following cases:
a) Failover due to a node failure where task is executing
b) Failover due to a task failure (e.g. Callable task throws Exception).
Infinispan provides random node failover policy which will attempt execution of a part of distributed task on
another random node, if such node is available. However, users that have a need to implement a more
sophisticated failover policy can implement DistributedTaskFailoverPolicy interface. For example, users
might want to use consistent hashing (CH) mechanism for failover of uncompleted tasks. CH based failover
might for example migrate failed task T to cluster node(s) having a backup of input data that was executed
on a failed node F.

/**
* DistributedTaskFailoverPolicy allows pluggable fail over target selection for a failed
remotely
* executed distributed task.
*
*/
public interface DistributedTaskFailoverPolicy {
/**
* As parts of distributively executed task can fail due to the task itself throwing an
exception
* or it can be an Infinispan system caused failure (e.g node failed or left cluster during
task
* execution etc).
*
* @param failoverContext
*
the FailoverContext of the failed execution
* @return result the Address of the Infinispan node selected for fail over execution
*/
Address failover(FailoverContext context);
/**
* Maximum number of fail over attempts permitted by this DistributedTaskFailoverPolicy
*
* @return max number of fail over attempts
*/
int maxFailoverAttempts();
}

Therefore one could for example specify random failover execution policy simply by:

JBoss Community Documentation

Page 228 of 617

Infinispan 6.0

DistributedExecutorService des = new DefaultExecutorService(cache);


DistributedTaskBuilder<Boolean> taskBuilder = des.createDistributedTaskBuilder(new
SomeCallable());
taskBuilder.failoverPolicy(DefaultExecutorService.RANDOM_NODE_FAILOVER);
DistributedTask<Boolean> distributedTask = taskBuilder.build();
Future<Boolean> future = des.submit(distributedTask);
Boolean r = future.get();

3.39.6 Distributed task execution policy


DistributedTaskExecutionPolicy is an enum that allows tasks to specify its custom task execution policy
across Infinispan cluster. DistributedTaskExecutionPolicy effectively scopes execution of tasks to a subset of
nodes. For example, someone might want to exclusively execute tasks on a local network site instead of
a backup remote network centre as well. Others might, for example, use only a dedicated subset of a certain
Infinispan rack nodes for specific task execution. DistributedTaskExecutionPolicy is set per instance of
DistributedTask.

DistributedExecutorService des = new DefaultExecutorService(cache);


DistributedTaskBuilder<Boolean> taskBuilder = des.createDistributedTaskBuilder(new
SomeCallable());
taskBuilder.executionPolicy(DistributedTaskExecutionPolicy.SAME_RACK);
DistributedTask<Boolean> distributedTask = taskBuilder.build();
Future<Boolean> future = des.submit(distributedTask);
Boolean r = future.get();

3.39.7 Examples
Pi approximation can greatly benefit from parallel distributed execution in DistributedExecutorService. Recall
that area of the square is Sa = 4r2 and area of the circle is Ca=pi*r2. Substituting r2 from the second
equation into the first one it turns out that pi = 4 * Ca/Sa. Now, image that we can shoot very large number of
darts into a square; if we take ratio of darts that land inside a circle over a total number of darts shot we will
approximate Ca/Sa value. Since we know that pi = 4 * Ca/Sa we can easily derive approximate value of pi.
The more darts we shoot the better approximation we get. In the example below we shoot 10 million darts
but instead of "shooting" them serially we parallelize work of dart shooting across entire Infinispan cluster.

JBoss Community Documentation

Page 229 of 617

Infinispan 6.0

public class PiAppx {


public static void main (String [] arg){
List<Cache> caches = ...;
Cache cache = ...;
int numPoints = 10000000;
int numServers = caches.size();
int numberPerWorker = numPoints / numServers;
DistributedExecutorService des = new DefaultExecutorService(cache);
long start = System.currentTimeMillis();
CircleTest ct = new CircleTest(numberPerWorker);
List<Future<Integer>> results = des.submitEverywhere(ct);
int countCircle = 0;
for (Future<Integer> f : results) {
countCircle += f.get();
}
double appxPi = 4.0 * countCircle / numPoints;
System.out.println("Distributed PI appx is " + appxPi +
" completed in " + (System.currentTimeMillis() - start) + " ms");
}
private static class CircleTest implements Callable<Integer>, Serializable {
/** The serialVersionUID */
private static final long serialVersionUID = 3496135215525904755L;
private final int loopCount;
public CircleTest(int loopCount) {
this.loopCount = loopCount;
}
@Override
public Integer call() throws Exception {
int insideCircleCount = 0;
for (int i = 0; i < loopCount; i++) {
double x = Math.random();
double y = Math.random();
if (insideCircle(x, y))
insideCircleCount++;
}
return insideCircleCount;
}
private boolean insideCircle(double x, double y) {
return (Math.pow(x - 0.5, 2) + Math.pow(y - 0.5, 2))
<= Math.pow(0.5, 2);
}
}
}

JBoss Community Documentation

Page 230 of 617

Infinispan 6.0

3.40 Listeners and Notifications


Infinispan offers a listener API, where clients can register for and get notified when events take place. This
annotation-driven API applies to 2 different levels: cache level events and cache manager level events.
Events trigger a notification which are dispatched to listeners. Listeners are simple POJOs annotated with
@Listener and registered using the methods defined in the Listenable interface.

Both Cache and CacheManager implement Listenable, which means you can attach listeners to either
a cache or a cache manager, to receive either cache-level or cache manager-level notifications.

For example, the following class defines a listener to print out some information every time a new entry is
added to the cache:

@Listener
public class PrintWhenAdded {
@CacheEntryCreated
public void print(CacheEntryCreatedEvent event) {
System.out.println("New entry " + event.getKey() + " created in the cache");
}
}

For more comprehensive examples, please see the Javadocs for @Listener.

3.40.1 Cache-level notifications


Cache-level events occur on a per-cache basis, and is global and cluster-wide. Examples of cache-level
events are entries being added, removed, modified, etc. These events trigger notifications to listeners
registered to a specific cache.
Please see the Javadocs on the org.infinispan.notifications.cachelistener.annotation package for a
comprehensive list of all cache-level notifications, and their respective method-level annotations.

NOTE: In Infinispan 5.0, additional events were added. Please refer to the <a
href="http://docs.jboss.org/infinispan/5.0/apidocs/org/infinispan/notifications/cachelistener/annotation/packa
on the org.infinispan.notifications.cachelistener.annotation package</a> for Infinispan 5.0 for
the list of cache-level notifications available in Infinispan 5.0.

JBoss Community Documentation

Page 231 of 617

Infinispan 6.0

3.40.2 Cache manager-level notifications


Cache manager-level events occur on a cache manager. These too are global and cluster-wide, but involve
events that affect all caches created by a single cache manager. Examples of cache manager-level events
are nodes joining or leaving a cluster, or caches starting or stopping.
Please see the Javadocs on the org.infinispan.notifications.cachemanagerlistener.annotation package for a
comprehensive list of all cache manager-level notifications, and their respective method-level annotations.

3.40.3 Synchronicity
By default, all notifications are dispatched in the same thread that generates the event. This means that you
must write your listener such that it does not block or do anything that takes too long, as it would prevent the
thread from progressing. Alternatively, you could annotate your listener as asynchronous , in which case a
separate thread pool will be used to dispatch the notification and prevent blocking the event originating
thread. To do this, simply annotate your listener such:

@Listener (sync = false)


public class MyAsyncListener { .... }

Asynchronous thread pool


To tune the thread pool used to dispatch such asynchronous notifications, use the <asyncListenerExecutor
/> XML element in your configuration file.

3.40.4 Listeners on RemoteCacheManager


At the moment there is no support for registering listeners for the RemoteCacheManager. Whenever calling
one of the add/remove/getListener methods on the RemoteCacheManager
an UnsupportedOperationException will be thrown. There are plans to support remote listeners in future
versions; in order to be notified when this feature will be added you can watch/vote for ISPN-374.

JBoss Community Documentation

Page 232 of 617

Infinispan 6.0

3.41 Eviction
Eviction in 5.2
NONE
UNORDERED
LRU
LIRS
Configuration and defaults in 5.2.x
Advanced Eviction Internals
Expiration
Difference between Eviction and Expiration
Infinispan supports eviction of entries, such that you do not run out of memory. Eviction is typically used in
conjunction with a cache store, so that entries are not permanently lost when evicted, since eviction only
removes entries from memory and not from cache stores or the rest of the cluster.

Passivation is also a popular option when using eviction, so that only a single copy of an entry is
maintained - either in memory or in a cache store, but not both. The main benefit of using
passivation over a regular cache store is that updates to entries which exist in memory are cheaper
since the update doesn't need to be made to the cache store as well.

Note that eviction occurs on a local basis, and is not cluster-wide. Each node runs an eviction thread to
analyse the contents of its in-memory container and decide what to evict. Eviction does not take into account
the amount of free memory in the JVM as threshold to starts evicting entries. You have to set maxEntries
attribute of the eviction element to be greater than zero in order for eviction to be turned on. If maxEntries is
too large you can run out of memory. maxEntries attribute will probably take some tuning in each use case.

JBoss Community Documentation

Page 233 of 617

Infinispan 6.0

3.41.1 Eviction in 5.2


Eviction is configured by adding the <eviction /> element to your <default /> or <namedCache />
configuration sections or using EvictionConfigurationBuilder API programmatic approach. LIRS is default
eviction algorithm in Infinispan 5.2 release.
All cache entry are evicted by piggybacking on user threads that are hitting the cache. Periodic pruning of
expired cache entries from cache is done on a dedicated thread which is turned on by enabling reaper in
expiration configuration element/API.

NONE
This eviction strategy effectively disables the eviction thread.

UNORDERED
UNORDERED eviction strategy is a legacy eviction strategy that has been deprecated. If UNORDERED
strategy is specified LRU eviction algorithm will be used.

LRU
If LRU eviction is used cache entries are selected for eviction using a well known least-recently-used pattern.

LIRS
LRU eviction algorithm, although simple and easy to understand, under performs in cases of weak access
locality (one time access entries are not timely replaced, entries to be accessed soonest are unfortunately
replaced, and so on). Recently, a new eviction algorithm - LIRS has gathered a lot of attention because it
addresses weak access locality shortcomings of LRU yet it retains LRU's simplicity. Eviction in LIRS
algorithm relies on history information of cache entries accesses using so called Inter-Reference Recency
(a.k.a IRR) and the Recency. The IRR of a cache entry A refers to number of other distinct entries accessed
between the last two consecutive accesses to cache entry A, while recency refers to the number of other
entries accessed from last reference to A up to current time point. If we relied only on cache recency we
would essentially have LRU functionality. However, in addition to recency LIRS tracks elements that are in
low IRR and high IRR, aptly named LIR and HIR cache entry blocks respectively. LIRS eviction algorithm
essentially keeps entries with a low IRR in the cache as much as possible while evicting high IRR entries if
eviction is required. If recency of a LIR cache entry increases to a certain point and entry in HIR gets
accessed at a smaller recency than that of the LIR entry, the LIR/HIR statuses of the two blocks are
switched. Entries in HIR may be evicted regardless of its recency, even if element was recently accessed.

JBoss Community Documentation

Page 234 of 617

Infinispan 6.0

3.41.2 Configuration and defaults in 5.2.x


By default when no <eviction> element is specified, no eviction takes place.
In case there is an eviction element, this table describes behaviour of eviction based on information provided
in the xml configuration ("-" in Supplied maxEntries or Supplied strategy column means that the attribute
wasn't supplied)
Supplied

Supplied

Example

Eviction behaviour

maxEntries

strategy

<eviction />

no eviction

>0

<eviction maxEntries="100" />

the strategy defaults to LIRS and


eviction takes place

>0

>0

NONE

!= NONE

<eviction maxEntries="100"

the strategy defaults to LIRS and

strategy="NONE" />

eviction takes place

<eviction maxEntries="100"

eviction takes place with defined

strategy="LRU" />

strategy

<eviction maxEntries="0" />

no eviction

NONE

<eviction maxEntries="0"

no eviction

strategy="NONE" />
0

!= NONE

<eviction maxEntries="0"

ConfigurationException

strategy="LRU" />
<0

<eviction maxEntries="-1" />

no eviction

<0

NONE

<eviction maxEntries="-1"

no eviction

strategy="NONE" />
<0

!= NONE

<eviction maxEntries="-1"

ConfigurationException

strategy="LRU" />

JBoss Community Documentation

Page 235 of 617

Infinispan 6.0

3.41.3 Advanced Eviction Internals


Implementing eviction in a scalable, low lock contention approach while at the same time doing meaningful
selection of entries for eviction is not an easy feat. Data container needs to be locked until appropriate
eviction entries are selected. Having such a lock protected data container in turn causes high lock contention
offsetting any eviction precision gained by sophisticated eviction algorithms. In order to get superior
throughput while retaining high eviction precision both low lock contention data container and high precision
eviction algorithm implementation are needed. Infinispan evicts entries from cache on a segment level
(segments similar to ConcurrentHashMap), once segment is full entries are evicted according to eviction
algorithm. However, there are two drawbacks with this approach. Entries might get evicted from cache even
though maxEntries has not been reached yet and maxEntries is a theoretical limit for cache size but in
practical terms it will be slightly less than maxEntries. For more details refer to Infinispan eviction design.

3.41.4 Expiration
Similar to, but unlike eviction, is expiration. Expiration allows you to attach lifespan and/or maximum idle
times to entries. Entries that exceed these times are treated as invalid and are removed. When removed
expired entries are not passivated like evicted entries (if passivation is turned on).

Unlike eviction, expired entries are removed globally - from memory, cache stores, and
cluster-wide.

By default entries created are immortal and do not have a lifespan or maximum idle time. Using the cache
API, mortal entries can be created with lfiespans and/or maximum idle times. Further, default lifespans
and/or maximum idle times can be configured by adding the <expiration /> element to your <default /> or
<namedCache /> configuration sections.

3.41.5 Difference between Eviction and Expiration


Both Eviction and Expiration are means of cleaning the cache of unused entries and thus guarding the heap
against OutOfMemory exceptions, so now a brief explanation of the difference.
With eviction you set maximal number of entries you want to keep in the cache and if this limit is
exceeded, some candidates are found to be removed according to a choosen eviction strategy (LRU,
LIRS, etc...). Eviction can be setup to work with passivation (evicting to a cache store).
With expiration you set time criteria for entries, how long you want to keep them in cache. Either you set
maximum lifespan of the entry - time it is allowed to stay in the cache or maximum idle time, time it's
allowed to be untouched (no operation performed with given key).

JBoss Community Documentation

Page 236 of 617

Infinispan 6.0

3.42 ServerHinting
3.42.1 What is server hinting?
The motivations behind this feature is to ensure when using distribution, backups are not picked to reside on
the same physical server, rack or data centre. For obvious reasons it doesn't work with total replication.

3.42.2 Version
Server hinting was added in Infinspan 4.2.0 "Ursus". You'll need this release or later in order to use it.

3.42.3 Configuration
The hints are configured at transport level:

<transport
clusterName = "MyCluster"
machineId = "LinuxServer01"
rackId = "Rack01"
siteId = "US-WestCoast" />

Following topology hints can be specified:


machineId - this is probably the most useful, to disambiguate between multiple JVM instances on the
same node, or even multiple virtual hosts on the same physical host.
rackId - in larger clusters with nodes occupying more than a single rack, this setting would help
prevent backups being stored on the same rack.
siteId - to differentiate between nodes in different data centres replicating to each other.

All of the

above are optional, and if not provided, the distribution algorithms provide no guarantees that
backups will not be stored in instances on the same host/rack/site.

JBoss Community Documentation

Page 237 of 617

Infinispan 6.0

3.42.4 Algorithm
This is an advanced topic, useful e.g. if you need to change distribution behaviour.
The consistent hash beyond this implementation is wheel based. Conceptually this works as follows: each
node is placed on a wheel ordered by the hash code of its address. When an entry is added its owners are
chosen using this algorithm:
key's hash code is calculated
the first node on the wheel with a value grater than key's hash code is the first owner
for subsequent nodes, walk clockwise and pick nodes that have a different site id
if not enough nodes found repeat walk again and pick nodes that have different site id and rack id
if not enough nodes found repeat walk again and pick nodes that have different site id, rack id and
machine id
Ultimately cycle back to the first node selected, don't discard any nodes, regardless of machine
id/rack

3.43 Java Hot Rod client


Introduction
Basic API
Versioned API
Async API
Unsupported methods
Return values
Intelligence
Hash-distribution-aware client
Request Balancing
Persistent connections
Marshalling data
Statistics
Configuration
Multi-Get Operations
More info

3.43.1 Introduction
Hot Rod is a binary, language neutral protocol. This article explains how a Java client can interact with a
server via the Hot Rod protocol. A reference implementation of the protocol written in Java can be found in
all Infinispan distributions since 4.1, and this article focuses on the capabilities of this java client.

JBoss Community Documentation

Page 238 of 617

Infinispan 6.0

3.43.2 Basic API


Bellow is a sample code snippet on how the client API can be used to store or retrieve information from a
Hot Rod server using the Java Hot Rod client. It assumes that a Hot Rod server has been started bound to
the default location (localhost:11222)

//API entry point, by default it connects to localhost:11222


CacheContainer cacheContainer = new RemoteCacheManager();
//obtain a handle to the remote default cache
Cache<String, String> cache = cacheContainer.getCache();
//now add something to the cache and make sure it is there
cache.put("car", "ferrari");
assert cache.get("car").equals("ferrari");
//remove the data
cache.remove("car");
assert !cache.containsKey("car") : "Value must have been removed!";

The client API maps the local API: RemoteCacheManager corresponds to DefaultCacheManager (both
implement CacheContainer). This common API facilitates an easy migration from local calls to remote calls
through Hot Rod: all one needs to do is switch between DefaultCacheManager and RemoteCacheManagerwhich is further simplified by the common CacheContainer interface that both inherit.
Starting from Infinispan 5.2, all keys can be retrieved from the remote cache (whether it's local, replicated, or
distributed) by using keySet() method. If the remote cache is a distributed cache, the server will start a
map/reduce job to retrieve all keys from clustered nodes, and return all keys to the client. Please use this
method with care if there are large number of keys.

Set keys = remoteCache.keySet();

JBoss Community Documentation

Page 239 of 617

Infinispan 6.0

3.43.3 Versioned API


A RemoteCacheManager provides instances of RemoteCache interface that represents a handle to the
named or default cache on the remote cluster. API wise, it extends the Cache interface to which it also adds
some new methods, including the so called versioned API. Please find below some examples of this API but
to understand the motivation behind it, make sure you read this article.
The code snippet bellow depicts the usage of these versioned methods:

// To use the versioned API, remote classes are specifically needed


RemoteCacheManager remoteCacheManager = new RemoteCacheManager();
RemoteCache<String, String> cache = remoteCacheManager.getCache();
remoteCache.put("car", "ferrari");
RemoteCache.VersionedValue valueBinary = remoteCache.getVersioned("car");
// removal only takes place only if the version has not been changed
// in between. (a new version is associated with 'car' key on each change)
assert remoteCache.remove("car", valueBinary.getVersion());
assert !cache.containsKey("car");

In a similar way, for replace:

remoteCache.put("car", "ferrari");
RemoteCache.VersionedValue valueBinary = remoteCache.getVersioned("car");
assert remoteCache.replace("car", "lamborghini", valueBinary.getVersion());

For more details on versioned operations refer to RemoteCache's javadoc.

3.43.4 Async API


This cool feature is "borrowed" from the Infinispan core and it is largely discussed here.

JBoss Community Documentation

Page 240 of 617

Infinispan 6.0

3.43.5 Unsupported methods


Some of the Cache methods are not being supported by the RemoteCache. Calling one of these methods
results in an UnsupportedOperationException being thrown. Most of these methods do not make sense on
the remote cache (e.g. listener management operations), or correspond to methods that are not supported
by local cache as well (e.g. containsValue). Another set of unsupported operations are some of the atomic
operations inherited from ConcurrentMap:

boolean remove(Object key, Object value);


boolean replace(Object key, Object value);
boolean replace(Object key, Object oldValue, Object value);

RemoteCache offers alternative versioned methods for these atomic operations, that are also network
friendly, by not sending the whole value object over the network, but a version identifier. See the section on
versioned API.
Each one of these unsupported operation is documented in the RemoteCache javadoc.

3.43.6 Return values


There is a set of methods that alter an cached entry and return the previous existing value, e.g.:

V remove(Object key);
V put(K key, V value);

By default on RemoteCache, these operations return null even if such a previous value exists. This approach
reduces the amount of data sent over the network. However, if these return values are needed they can be
enforced on an per invocation basis using flags:

cache.put("aKey", "initialValue");
assert null == cache.put("aKey", "aValue");
assert "aValue".equals(cache.withFlags(Flag.FORCE_RETURN_VALUE).put("aKey",
"newValue"));

This default behaviour can can be changed through force-return-value=true configuration parameter (see
configuration section bellow).

JBoss Community Documentation

Page 241 of 617

Infinispan 6.0

3.43.7 Intelligence
HotRod defines three level of intelligence for the clients:
basic client, interested in neither cluster nor hash information
topology-aware client, interested in cluster information
hash-distribution-aware client, that is interested in both cluster and hash information
The java client supports all 3 levels of intelligence. It is transparently notified whenever a new server is
added/removed from the HotRod cluster. At startup it only needs to know the address of one HotRod server
(ip:host). On connection to the server the cluster topology is piggybacked to the client, and all further
requests are being dispatched to all available servers. Any further topology change is also piggybacked.
Hash-distribution-aware client is discussed in the next section.

3.43.8 Hash-distribution-aware client


Another aspect of the 3rd level of intelligence is the fact that it is hash-distribution-aware. This means that,
for each operation, the client chooses the most appropriate remote server to go to: the data owner. As an
example, for a put(k,v) operation, the client calculates k's hash value and knows exactly on which server the
data resides on. Then it picks up a tcp connection to that particular server and dispatches the operation to it.
This means less burden on the server side which would otherwise need to lookup the value based on the
key's hash. It also results in a quicker response from the server, as an additional network roundtrip is
skipped. This hash-distribution-aware aspect is only relevant to the distributed HotRod clusters and makes
no difference for replicated server deployments.

JBoss Community Documentation

Page 242 of 617

Infinispan 6.0

3.43.9 Request Balancing


Request balancing is only relevant when the server side is configured with replicated infinispan cluster (on
distributed clusters the hash-distribution-aware client logic is used, as discussed in the previos paragraph).
Because the client is topology-aware, it knows the list of available servers at all the time. Request balancing
has to do with how the client dispatches requests to the available servers.
The default strategy is round-robin: requests are being dispatched to all existing servers in a circular
manner. E.g. given a cluster of servers {s1, s2, s3} here is how request will be dispatched:

CacheContainer cacheContainer = new RemoteCacheManager();


Cache<String, String> cache = cacheContainer.getCache();
cache.put("key1", "aValue"); //this goes to s1
cache.put("key2", "aValue"); //this goes to s2
String value = cache.get("key1"); //this goes to s3
cache.remove("key2"); //this is dispatched to s1 again, and so on...

Custom types of balancing policies can defined by implementing the RequestBalancingStrategy and by
specifying it through the infinispan.client.hotrod.request-balancing-strategy configuration property. Please
refer to configuration section for more details on this.

3.43.10 Persistent connections


In order to avoid creating a TCP connection on each request (which is a costly operation), the client keeps a
pool of persistent connections to all the available servers and it reuses these connections whenever it is
possible. The validity of the connections is checked using an async thread that iterates over the connections
in the pool and sends a HotRod ping command to the server. By using this connection validation process the
client is being proactive: there's a hight chance for broken connections to be found while being idle in the
pool and no on actual request from the application.
The number of connections per server, total number of connections, how long should a connection be kept
idle in the pool before being closed - all these (and more) can be configured. Please refer to the javadoc of
RemoteCacheManager for a list of all possible configuration elements.

JBoss Community Documentation

Page 243 of 617

Infinispan 6.0

3.43.11 Marshalling data


The Hot Rod client allows one to plug in a custom marshaller for transforming user objects into byte arrays
and the other way around. This transformation is needed because of Hot Rod's binary nature - it doesn't
know about objects.
The marshaller can be plugged through the "marshaller" configuration element (see Configuration section):
the value should be the fully qualified name of a class implementing the Marshaller interface. This is a
optional parameter, if not specified it defaults to the GenericJBossMarshaller - a highly optimized
implementation based on the JBoss Marshalling library.
Since version 5.0, there's a new marshaller available to Java Hot Rod clients based on Apache Avro which
generates portable payloads. You can find more information about it here

3.43.12 Statistics
Various server usage statistics can be obtained through the RemoteCache.stats() method. This returns an
ServerStatistics object - please refer to javadoc for details on the available statistics.

3.43.13 Configuration
All the configurations are passed to the RemoteCacheManager's constructor as key-value pairs, through an
instance of java.util.Properties or reference to a .properties file. Please refer to the javadoc of
RemoteCacheManager for a exhaustive list of the possible configuration elements.

3.43.14 Multi-Get Operations


The Java Hot Rod client does not provide multi-get functionality out of the box but clients can build it
themselves with the given APIs. More information on this topic can be found in the Hot Rod protocol article.

3.43.15 More info


It is highly recommended to read the following Javadocs (this is pretty much all the public API of the client):
RemoteCacheManager
RemoteCache

3.44 Configuring cache


Infinispan offers both Configuring Cache declaratively and Configuring cache programmatically configuration
approaches.

JBoss Community Documentation

Page 244 of 617

Infinispan 6.0
Declarative configuration comes in a form of XML document that adheres to a provided Infinispan
configuration XML schema. Every aspect of Infinispan that can be configured declaratively can also be
configured programmatically. In fact, declarative configuration, behind the scenes, invokes programmatic
configuration API as the XML configuration file is being processed. One can even use combination of these
approaches. For example, you can read static XML configuration files and at runtime programmatically tune
that same configuration. Or you can use a certain static configuration defined in XML as a starting point or
template for defining additional configurations in runtime.
There are two main configuration abstractions in Infinispan: global and default configuration.
Global cache configuration defines global settings shared among all cache instances created by a single
CacheManager. Shared resources like thread pools, serialization/marshalling settings, transport and network
settings, JMX domains are all part of global configuration.
Default cache configuration is more specific to actual caching domain itself. It specifies eviction, locking,
transaction, clustering, cache store settings etc. The default cache can be retrieved via the
CacheManager.getCache() API. However, the real power of default cache mechanism comes to light when
used in conjuction with named caches . Named caches have the same XML schema as the default cache.
Whenever they are specified, named caches inherit settings from the default cache while additional behavior
can be specified or overridden. Named caches are retrieved via CacheManager.getCache(String name) API.
Therefore, note that the name attribute of named cache is both mandatory and unique for every named
cache specified.
Do not forget to refer to Infinispan configuration reference for more details.
For more details, refer to the following documents:
Configuring Cache declaratively
Configuring cache programmatically
Dynamically Start and Stop Clustered Cache
Configuration Migration Tools

3.44.1 Dynamically Start and Stop Clustered Cache


Library Mode
Clustered
Start start/stop cache in non-clustered mode is simple. You can use
EmbeddedCacheManager.defineConfiguration(cacheName, configuration) to define a cache, and then call
EmbeddedCacheManager.getCache(cacheName).
If you don't define a specific configuration for the cache and directly call
EmbeddedCacheManager.getCache(...), then a new cache would be created with default configurations.
To stop a cache, call EmbeddedCacheManager.remove(cacheName);

JBoss Community Documentation

Page 245 of 617

Infinispan 6.0

Clustered
To start a clustered cache, you'll need to do the above on every clustered node, while making sure the
cache mode is clustered, of course.
You can start the cache by calling _EmbeddedCacheManager.getCache(...). _To do this on every single
node though, you could write your own service to do that, or with JMX, or use DistributedExecutorService.
For example, write a StartCacheCallable class:

public class StartCacheCallable<K, V> implements DistributedCallable<K, V, Void>, Serializable {


private static final long serialVersionUID = 8331682008912636780L;
private final String cacheName;
private transient Cache<K, V> cache;

public StartCacheCallable(String cacheName) {


this.cacheName = cacheName;
}
@Override
public Void call() throws Exception {
cache.getCacheManager().getCache(cacheName); // start the cache
return null;
}
@Override
public void setEnvironment(Cache<K, V> cache, Set<K> inputKeys) {
this.cache = cache;
}
}

Then submit the task to all nodes:

DistributedExecutorService des = new DefaultExecutorService(existingCacheSuchAsDefaultCache);


List<Future<Void>> list = des.submitEverywhere(new StartCacheCallable<K, V>(cacheName));
for (Future<Void> future : list) {
try {
future.get(); // wait for task to complete
} catch (InterruptedException e) {
} catch (ExecutionException e) {
}
}

Server Mode
Hot Rod client does not support dynamically start/stop of cache.

JBoss Community Documentation

Page 246 of 617

Infinispan 6.0

3.45 Write-Through And Write-Behind Caching


3.45.1 Introduction
Infinispan can optionally be configured with one or several cache stores allowing it to store data in a
persistent location such as shared JDBC database, a local filesystem...etc. Infinispan can handle updates to
the cache store in two different ways:
Write-Through (Synchronous)
Write-Behind (Asynchronous)

3.45.2 Write-Through (Synchronous)


In this mode, which is supported in version 4.0, when clients update a cache entry, i.e. via a Cache.put()
invocation, the call will not return until Infinispan has gone to the underlying cache store and has updated it.
Normally, this means that updates to the cache store are done within the boundaries of the client thread.
The main advantage of this mode is that the cache store is updated at the same time as the cache, hence
the cache store is consistent with the cache contents. On the other hand, using this mode reduces
performance because the latency of having to access and update the cache store directly impacts the
duration of the cache operation.
Configuring a write-through or synchronous cache store does not require any particular configuration option.
By default, unless marked explicitly as write-behind or asynchronous, all cache stores are write-through or
synchronous. Please find below a sample configuration file of a write-through unshared local file cache store:

<?xml version="1.0" encoding="UTF-8"?>


<infinispan xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="urn:infinispan:config:5.0">
<global />
<default />
<namedCache name="persistentCache">
<loaders shared="false">
<loader
class="org.infinispan.loaders.file.FileCacheStore"
fetchPersistentState="true" ignoreModifications="false"
purgeOnStartup="false">
<properties>
<property name="location" value="${java.io.tmpdir}" />
</properties>
</loader>
</loaders>
</namedCache>
</infinispan>

JBoss Community Documentation

Page 247 of 617

Infinispan 6.0

3.45.3 Write-Behind (Asynchronous)


In this mode, updates to the cache are asynchronously written to the cache store. Normally, this means that
updates to the cache store are done by a separate thread to the client thread interacting with the cache.
One of the major advantages of this mode is that the performance of a cache operation does not get affected
by the update of the underlying store. On the other hand, since the update happens asynchronously, there's
a time window during the which the cache store can contain stale data compared to the cache. Even within
write-behind, there are different strategies that can be used to store data:

3.45.4 Unscheduled Write-Behind Strategy


In this mode, which is supported in version 4.0, Infinispan tries to store changes as quickly as possible by
taking the pending changes and applying them in paralel. Normally, this means that there are several
threads waiting for modifications to occur and once they're available, they apply them to underlying cache
store.
This strategy is suited for cache stores with low latency and cheap operation cost. One such example would
a local unshared file based cache store, where the cache store is local to the cache itself. With this strategy,
the window of inconsistency between the contents of the cache and the cache store are reduced to the
lowest possible time. Please find below a sample configuration file of this strategy:

<?xml version="1.0" encoding="UTF-8"?>


<infinispan xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="urn:infinispan:config:5.0">
<global />
<default />
<namedCache name="persistentCache">
<loaders shared="false">
<loader
class="org.infinispan.loaders.file.FileCacheStore"
fetchPersistentState="true" ignoreModifications="false"
purgeOnStartup="false">
<properties>
<property name="location" value="${java.io.tmpdir}" />
</properties>
<!-- write-behind configuration starts here -->
<async enabled="true" threadPoolSize="10" />
<!-- write-behind configuration ends here -->
</loader>
</loaders>
</namedCache>
</infinispan>

JBoss Community Documentation

Page 248 of 617

Infinispan 6.0

3.45.5 Scheduled Write-Behind Strategy


First of all, please note that this strategy is not included in version 4.0 but it will be implemented at a later
stage. ISPN-328 has been created to track this feature request. If you want it implemented, please vote for it
and don't forget to watch it to be notified of any changes. The following explanation refers to how we
envision it to work.
In this mode, Infinispan would periodically store changes to the underlying cache store. The periodicity could
be defined in seconds, minutes, days...etc.
Since this strategy is oriented at cache stores with high latency or expensive operation cost, it makes sense
to coalesce changes, so that if there are multiple operations queued on the same key, only the latest value is
applied to cache store. With this strategy, the window of inconsistency between the contents of the cache
and the cache store depends on the delay or periodicity configured. The higher the periodicity, the higher the
chance of inconsistency.

3.46 Cassandra CacheStore


Infinispan's CassandraCacheStore leverages Apache Cassandra's distributed database architecture to
provide a virtually unlimited, horizontally scalable persistent store for Infinispan's caches.

3.46.1 Version
The Cassandra CacheStore was added in Infinspan 4.2.0 "Ursus". You'll need this release or later in order to
use it.

3.46.2
Configuration
In order to use this CacheStore you need to create an appropriate keyspace on your Cassandra database.
The following storage-conf.xml excerpt shows the declaration of the keyspace:

<Keyspace Name="Infinispan">
<ColumnFamily CompareWith="BytesType" Name="InfinispanEntries" KeysCached="10%" />
<ColumnFamily CompareWith="LongType" Name="InfinispanExpiration" KeysCached="10%"
ColumnType="Super" CompareSubcolumnsWith="BytesType"/>
<ColumnFamily CompareWith="BytesType" Name="InfinispanEntries" KeysCached="0" />
<ColumnFamily CompareWith="LongType" Name="InfinispanExpiration" KeysCached="0"
ColumnType="Super" CompareSubcolumnsWith="BytesType"/>
<ReplicaPlacementStrategy>org.apache.cassandra.locator.RackUnawareStrategy</ReplicaPlacementStrategy>
<ReplicationFactor>2</ReplicationFactor>
<EndPointSnitch>org.apache.cassandra.locator.EndPointSnitch</EndPointSnitch>
</Keyspace>

JBoss Community Documentation

Page 249 of 617

Infinispan 6.0
The important bits are the CompareWith, ColumnType and CompareSubColumnsWith declarations.
Everything else can be changed at will. You can also have more than one Keyspace to accomodate for
multiple caches. Also bear in mind that the current version of the CassandraCacheStore only supports the
OrderPreservingPartitioner.
You then need to add an appropriate cache declaration to your infinispan.xml (or whichever file you use to
configure Infinispan):

<namedCache name="cassandraCache">
<loaders passivation="false" shared="true" preload="false">
<loader
class="org.infinispan.loaders.cassandra.CassandraCacheStore"
fetchPersistentState="true" ignoreModifications="false"
purgeOnStartup="false">
<properties>
<property name="host" value="localhost" />
<property name="keySpace" value="Infinispan" />
<property name="entryColumnFamily" value="InfinispanEntries" />
<property name="expirationColumnFamily"
value="InfinispanExpiration" />
<property name="sharedKeyspace" value="false" />
<property name="readConsistencyLevel" value="ONE" />
<property name="writeConsistencyLevel" value="ONE" />
<property name="configurationPropertiesFile"
value="cassandrapool.properties" />
<property name="keyMapper"
value="org.infinispan.loaders.keymappers.DefaultTwoWayKey2StringMapper" />
</properties>
</loader>
</loaders>
</namedCache>

It is important the the shared property on the loader element is set to true because all the Infinispan nodes
will share the same Cassandra cluster.
Since the Cassandra client library doesn't provide connection pooling, a separate project has been created
at http://github.com/tristantarrant/cassandra-connection-pool.
Configuration of the connection pool can be done by creating an appropriate properties file and specifying its
name in the configuration (configurationPropertiesFile).
The following is an example file:

socketTimeout = 5000
initialSize = 10
maxActive = 100
maxIdle = 20
minIdle = 10
maxWait = 30000testOnBorrow = false
testOnReturn = false
testWhileIdle = false
timeBetweenEvictionRunsMillis = 5000removeAbandoned = false
removeAbandonedTimeout = 60
logAbandoned = false

JBoss Community Documentation

Page 250 of 617

Infinispan 6.0
Here is a description of the various properties which can be configured:
host

a hostname (or a comma-separated list of hostnames)

port

the thrift port (usually 9160)

keySpace

the keyspace to use (defaults to Infinispan)

entryColumnFamily

the column family where entry values will be stored. Make sure you configure
your keyspace accordingly (defaults to InfinispanEntries)

expirationColumnFamily the column family where element expiration information is stored. Make sure
your (defaults to InfinispanExpiration)
sharedKeyspace

whether multiple caches are to be stored in a single keyspace. In this case the
cache name is prefixed to the key entries (defaults to false).

readConsistencyLevel

The consistency level to use when reading from Cassandra. Possible values are
ONE, QUORUM, DCQUORUM, ALL. For an explanation of these refer to the
Cassandra API documentation. (defaults to ONE)

writeConsistencyLevel

The consistency level to use when writing to Cassandra. Possible values are
ZERO, ANY, ONE, QUORUM, DCQUORUM, ALL. For an explanation of these
refer to the Cassandra API documentation. (defaults to ONE)

keyMapper

A class which implements Infinispan's TwoWayKey2StringMapper interface for


mapping cache keys to Cassandra row keys (defaults to
org.infinispan.loaders.keymappers.DefaultTwoWayKey2StringMapper)

3.47 Infinispan Custom Interceptors


3.47.1 Introduction
It is possible to add custom interceptors to Infinispan, both declaratively and programatically. Custom
interceptors are an way of extending Infinispan by being able to influence or respond to any modifications to
cache. Example of such modifications are: elements are added/removed/updated or transactions are
committed. For a detailed list refer to CommandInterceptor API.

JBoss Community Documentation

Page 251 of 617

Infinispan 6.0

3.47.2 Adding custom interceptors declaratively


Custom interceptors can be added on a per named cache basis. This is because each named cache have
it's own interceptor stack. Following xml snippet depicts the ways in which an custom interceptor can be
added.

<namedCache name="cacheWithCustomInterceptors">
<!-Define custom interceptors. All custom interceptors need to extend
org.jboss.cache.interceptors.base.CommandInterceptor
-->
<customInterceptors>
<interceptor position="FIRST" class="com.mycompany.CustomInterceptor1">
<properties>
<property name="attributeOne" value="value1" />
<property name="attributeTwo" value="value2" />
</properties>
</interceptor>
<interceptor position="LAST" class="com.mycompany.CustomInterceptor2"/>
<interceptor index="3" class="com.mycompany.CustomInterceptor1"/>
<interceptor before="org.infinispanpan.interceptors.CallInterceptor"
class="com.mycompany.CustomInterceptor2"/>
<interceptor after="org.infinispanpan.interceptors.CallInterceptor"
class="com.mycompany.CustomInterceptor1"/>
</customInterceptors>
</namedCache>

Adding custom interceptors programatically


In order to do that one needs to obtain a reference to the AdvancedCache. This can be done ass follows:

CacheManager cm = getCacheManager();//magic
Cache aCache = cm.getCache("aName");
AdvancedCache advCache = aCache.getAdvancedCache();

Then one of the addInterceptor() methods should be used to add the actual interceptor. For further
documentation refer to AdvancedCache javadoc.

3.47.3 Custom interceptor design


Custom interceptors must extend BaseCustomInterceptor
Custom interceptors must declare a public, empty constructor to enable construction.
Custom interceptors will have setters for any property defined through property tag.

JBoss Community Documentation

Page 252 of 617

Infinispan 6.0

3.48 Talking To Infinispan Memcached Servers From


Non-Java Clients
Multi Clustered Server Tutorial
This wiki shows how to talk to Infinispan memcached server via non-java client, such as a python script.

3.48.1 Multi Clustered Server Tutorial


The second example showcases the distribution capabilities of Infinispan memcached severs that are not
available in the original memcached implementation.
Start first Infinispan memcached server giving to it a port number and an Infinispan configuration
supporting distribution. This configuration is the same one used for the GUI demo:

./bin/startServer.sh -r memcached -c etc/config-samples/gui-demo-cache-config.xml -p 12211

Start a second Infinispan memcached server passing to it a different port number:

./bin/startServer.sh -r memcached -c etc/config-samples/gui-demo-cache-config.xml -p 13211

Execute test_memcached_write.py script which basically executes several write operations againts
the Infinispan memcached server bound to port 12211. If the script is executed successfully, you
should see an output similar to this:

<li>Connecting to 127.0.0.1:12211</li><li>Testing set ['Simple_Key': Simple value] ...


OK</li><li>Testing set ['Expiring_Key' : 999 : 3] ... OK</li><li>Testing increment 3 times
['Incr_Key' : starting at 1 ]</li><li>Initialise at 1 ... OK</li><li>Increment by one ...
OK</li><li>Increment again ... OK</li><li>Increment yet again ... OK</li><li>Testing
decrement 1 time ['Decr_Key' : starting at 4 ]</li><li>Initialise at 4 ...
OK</li><li>Decrement by one ... OK</li><li>Testing decrement 2 times in one call
['Multi_Decr_Key' : 3 ]</li><li>Initialise at 3 ... OK</li><li>Decrement by 2 ... OK</li>

Execute test_memcached_read.py script which connects to server bound to 127.0.0.1:13211 and


verifies that it can read the data that was written by the writer script to the first server. If the script is
executed successfully, you should see an output similar to this:

<li>Connecting to 127.0.0.1:13211</li><li>Testing get ['Simple_Key'] should return Simple


value ... OK</li><li>Testing get ['Expiring_Key'] should return nothing...
OK</li><li>Testing get ['Incr_Key'] should return 4 ... OK</li><li>Testing get
['Decr_Key'] should return 3 ... OK</li><li>Testing get ['Multi_Decr_Key'] should return 1
... OK</li>

JBoss Community Documentation

Page 253 of 617

Infinispan 6.0

3.49 Plugging Infinispan With User Defined


Externalizers
Introduction
Benefits of Externalizers
User Friendly Externalizers
Advanced Externalizers
Linking Externalizers with Marshaller Classes
Externalizer Identifier
Registering Advanced Externalizers
Preassigned Externalizer Id Ranges

3.49.1 Introduction
One of the key aspects of Infinispan is that it often needs to marshall/unmarshall objects in order to provide
some of its functionality. For example, if it needs to store objects in a write-through or write-behind cache
store, the stored objects need marshalling. If a cluster of Infinispan nodes is formed, objects shipped around
need marshalling. Even if you enable lazy deserialization, objects need to be marshalled so that they can be
lazily unmarshalled with the correct classloader.
Using standard JDK serialization is slow and produces payloads that are too big and can affect bandwidth
usage. On top of that, JDK serialization does not work well with objects that are supposed to be immutable.
In order to avoid these issues, Infinispan uses JBoss Marshalling for marshalling/unmarshalling objects.
JBoss Marshalling is fast, produces very space efficient payloads, and on top of that during unmarshalling, it
enables users to have full control over how to construct objects, hence allowing objects to carry on being
immutable.
Starting with 5.0, users of Infinispan can now benefit from this marshalling framework as well, and they can
provide their own externalizer implementations, but before finding out how to provide externalizers, let's look
at the benefits they bring.

3.49.2 Benefits of Externalizers


The JDK provides a simple way to serialize objects which, in its simplest form, is just a matter of extending
java.io.Serializable, but as it's well known, this is known to be slow and it generates payloads that are far too
big. An alternative way to do serialization, still relying on JDK serialization, is for your objects to extend
java.io.Externalizable. This allows for users to provide their own ways to marshall/unmarshall classes, but
has some serious issues because, on top of relying on slow JDK serialization, it forces the class that you
want to serialize to extend this interface, which has two side effects: The first is that you're forced to modify
the source code of the class that you want to marshall/unmarshall which you might not be able to do
because you either, don't own the source, or you don't even have it. Secondly, since Externalizable
implementations do not control object creation, you're forced to add set methods in order to restore the state,
hence potentially forcing your immutable objects to become mutable.

JBoss Community Documentation

Page 254 of 617

Infinispan 6.0
Instead of relying on JDK serialization, Infinispan uses JBoss Marshalling to serialize objects and requires
any classes to be serialized to be associated with an Externalizer interface implementation that knows how
to transform an object of a particular class into a serialized form and how to read an object of that class from
a given input. Infinispan does not force the objects to be serialized to implement Externalizer. In fact, it is
recommended that a separate class is used to implement the Externalizer interface because, contrary to
JDK serialization, Externalizer implementations control how objects of a particular class are created when
trying to read an object from a stream. This means that readObject() implementations are responsible of
creating object instances of the target class, hence giving users a lot of flexibility on how to create these
instances (whether direct instantiation, via factory or reflection), and more importantly, allows target classes
to carry on being immutable. This type of externalizer architecture promotes good OOP designs principles,
such as the principle of single responsibility.
It's quite common, and in general recommended, that Externalizer implementations are stored as inner static
public classes within classes that they externalize. The advantages of doing this is that related code stays
together, making it easier to maintain. In Infinispan, there are two ways in which Infinispan can be plugged
with user defined externalizers:

User Friendly Externalizers


In the simplest possible form, users just need to provide an Externalizer implementation for the type that they
want to marshall/unmarshall, and then annotate the marshalled type class with {@link SerializeWith}
annotation indicating the externalizer class to use. For example:

JBoss Community Documentation

Page 255 of 617

Infinispan 6.0

import org.infinispan.marshall.Externalizer;
import org.infinispan.marshall.SerializeWith;
@SerializeWith(Person.PersonExternalizer.class)
public class Person {
final String name;
final int age;
public Person(String name, int age) {
this.name = name;
this.age = age;
}
public static class PersonExternalizer implements Externalizer<Person> {
@Override
public void writeObject(ObjectOutput output, Person person)
throws IOException {
output.writeObject(person.name);
output.writeInt(person.age);
}
@Override
public Person readObject(ObjectInput input)
throws IOException, ClassNotFoundException {
return new Person((String) input.readObject(), input.readInt());
}
}
}

At runtime JBoss Marshalling will inspect the object and discover that's marshallable thanks to the
annotation and so marshall it using the externalizer class passed. To make externalizer implementations
easier to code and more typesafe, make sure you define type <T> as the type of object that's being
marshalled/unmarshalled.
Even though this way of defining externalizers is very user friendly, it has some disadvantages:
Due to several constraints of the model, such as support different versions of the same class or the
need to marshall the Externalizer class, the payload sizes generated via this method are not the most
efficient.
This model requires for the marshalled class to be annotated with {@link SerializeWith} but a user
might need to provide an Externalizer for a class for which source code is not available, or for any
other constraints, it cannot be modified.
The use of annotations by this model might be limiting for framework developers or service providers
that try to abstract lower level details, such as the marshalling layer, away from the user.
If you're affected by any of these disadvantages, an alternative method to provide externalizers is available
via more advanced externalizers:

JBoss Community Documentation

Page 256 of 617

Infinispan 6.0

Advanced Externalizers
AdvancedExternalizer provides an alternative way to provide externalizers for marshalling/unmarshalling
user defined classes that overcome the deficiencies of the more user-friendly externalizer definition model
explained in Externalizer. For example:

import org.infinispan.marshall.AdvancedExternalizer;
public class Person {
final String name;
final int age;
public Person(String name, int age) {
this.name = name;
this.age = age;
}
public static class PersonExternalizer implements AdvancedExternalizer<Person> {
@Override
public void writeObject(ObjectOutput output, Person person)
throws IOException {
output.writeObject(person.name);
output.writeInt(person.age);
}
@Override
public Person readObject(ObjectInput input)
throws IOException, ClassNotFoundException {
return new Person((String) input.readObject(), input.readInt());
}
@Override
public Set<Class<? extends Person>> getTypeClasses() {
return Util.<Class<? extends Person>>asSet(Person.class);
}
@Override
public Integer getId() {
return 2345;
}
}
}

The first noticeable difference is that this method does not require user classes to be annotated in anyway,
so it can be used with classes for which source code is not available or that cannot be modified. The bound
between the externalizer and the classes that are marshalled/unmarshalled is set by providing an
implementation for getTypeClasses() which should return the list of classes that this externalizer can
marshall:

JBoss Community Documentation

Page 257 of 617

Infinispan 6.0

Linking Externalizers with Marshaller Classes


Once the Externalizer's readObject() and writeObject() methods have been implemented, it's time to link
them up together with the type classes that they externalize. To do so, the Externalizer implementation must
provide a getTypeClasses() implementation. For example:

import org.infinispan.util.Util;
...
@Override
public Set<Class<? extends ReplicableCommand>> getTypeClasses() {
return Util.asSet(LockControlCommand.class, RehashControlCommand.class,
StateTransferControlCommand.class, GetKeyValueCommand.class,
ClusteredGetCommand.class, MultipleRpcCommand.class,
SingleRpcCommand.class, CommitCommand.class,
PrepareCommand.class, RollbackCommand.class,
ClearCommand.class, EvictCommand.class,
InvalidateCommand.class, InvalidateL1Command.class,
PutKeyValueCommand.class, PutMapCommand.class,
RemoveCommand.class, ReplaceCommand.class);
}

In the code above, ReplicableCommandExternalizer indicates that it can externalize several type of
commands. In fact, it marshalls all commands that extend ReplicableCommand interface, but currently the
framework only supports class equality comparison and so, it's not possible to indicate that the classes to
marshalled are all children of a particular class/interface.
However there might sometimes when the classes to be externalized are private and hence it's not possible
to reference the actual class instance. In this situations, users can attempt to look up the class with the given
fully qualified class name and pass that back. For example:

@Override
public Set<Class<? extends List>> getTypeClasses() {
return Util.<Class<? extends List>>asSet(
Util.loadClass("java.util.Collections$SingletonList"));
}

JBoss Community Documentation

Page 258 of 617

Infinispan 6.0

Externalizer Identifier
Secondly, in order to save the maximum amount of space possible in the payloads generated, advanced
externalizers require externalizer implementations to provide a positive identified via getId() implementations
or via XML/programmatic configuration that identifies the externalizer when unmarshalling a payload. In
order for this to work however, advanced externalizers require externalizers to be registered on cache
manager creation time via XML or programmatic configuration which will be explained in next section. On the
contrary, externalizers based on Externalizer and SerializeWith require no pre-registration whatsoever.
Internally, Infinispan uses this advanced externalizer mechanism in order to marshall/unmarshall internal
classes.
So, getId() should return a positive integer that allows the externalizer to be identified at read time to figure
out which Externalizer should read the contents of the incoming buffer, or it can return null. If getId() returns
null, it is indicating that the id of this advanced externalizer will be defined via XML/programmatic
configuration, which will be explained in next section.
Regardless of the source of the the id, using a positive integer allows for very efficient variable length
encoding of numbers, and it's much more efficient than shipping externalizer implementation class
information or class name around. Infinispan users can use any positive integer as long as it does not clash
with any other identifier in the system. It's important to understand that a user defined externalizer can even
use the same numbers as the externalizers in the Infinispan Core project because the internal Infinispan
Core externalizers are special and they use a different number space to the user defined externalizers. On
the contrary, users should avoid using numbers that are within the pre-assigned identifier ranges which can
be found at the end of this article. Infinispan checks for id duplicates on startup, and if any are found, startup
is halted with an error.
When it comes to maintaining which ids are in use, it's highly recommended that this is done in a centralized
way. For example, getId() implementations could reference a set of statically defined identifiers in a separate
class or interface. Such class/interface would give a global view of the identifiers in use and so can make it
easier to assign new ids.

Registering Advanced Externalizers


The following example shows the type of configuration required to register an advanced externalizer
implementation for Person object shown earlier stored as a static inner class within it:
XML:

<infinispan>
<global>
<serialization>
<advancedExternalizers>
<advancedExternalizer externalizerClass="Person$PersonExternalizer"/>
</advancedExternalizers>
</serialization>
</global>
...
</infinispan>

JBoss Community Documentation

Page 259 of 617

Infinispan 6.0
Programmatically:

GlobalConfigurationBuilder builder = ...


builder.serialization()
.addAdvancedExternalizer(new Person.PersonExternalizer());

As mentioned earlier, when listing these externalizer implementations, users can optionally provide the
identifier of the externalizer via XML or programmatically instead of via getId() implementation. Again, this
offers a centralized way to maintain the identifiers but it's important that the rules are clear: An
AdvancedExternalizer implementation, either via XML/programmatic configuration or via annotation, needs
to be associated with an identifier. If it isn't, Infinispan will throw an error and abort startup. If a particular
AdvancedExternalizer implementation defines an id both via XML/programmatic configuration and
annotation, the value defined via XML/programmatically is the one that will be used. Here's an example of an
externalizer whose id is defined at registration time:

<infinispan>
<global>
<serialization>
<advancedExternalizers>
<advancedExternalizer id="123"
externalizerClass="Person$PersonExternalizer"/>
</advancedExternalizers>
</serialization>
</global>
...
</infinispan>

Programmatically:

GlobalConfigurationBuilder builder = ...


builder.serialization()
.addAdvancedExternalizer(123, new Person.PersonExternalizer());

Finally, a couple of notes about the programmatic configuration. GlobalConfiguration.addExternalizer() takes


varargs, so it means that it is possible to register multiple externalizers in just one go, assuming that their ids
have already been defined via @Marshalls annotation. For example:

builder.serialization()
.addAdvancedExternalizer(new Person.PersonExternalizer(),
new Address.AddressExternalizer());

JBoss Community Documentation

Page 260 of 617

Infinispan 6.0

Preassigned Externalizer Id Ranges


This is the list of Externalizer identifiers that are used by Infinispan based modules or frameworks. Infinispan
users should avoid using ids within these ranges.
Infinispan Tree Module:

1000 - 1099

Infinispan Server Modules:

1100 - 1199

Hibernate Infinispan Second Level Cache: 1200 - 1299


Infinispan Lucene Directory:

1300 - 1399

Hibernate OGM:

1400 - 1499

Hibernate Search:

1500 - 1599

3.50 Using the Cache API


The Cache interface
Limitations of Certain Map Methods
Mortal and Immortal Data
Example of Using Expiry and Mortal Data
putForExternalRead operation
The AdvancedCache interface
Flags
Custom Interceptors

3.50.1 The Cache interface


Infinispan exposes a simple, JSR-107 compliant Cache interface.

JBoss Community Documentation

Page 261 of 617

Infinispan 6.0

The Cache interface exposes simple methods for adding, retrieving and removing entries, including atomic
mechanisms exposed by the JDK's ConcurrentMap interface. Based on the cache mode used, invoking
these methods will trigger a number of things to happen, potentially even including replicating an entry to a
remote node or looking up an entry from a remote node, or potentially a cache store.

Note: For simple usage, using the Cache API should be no different from using the JDK Map API,
and hence migrating from simple in-memory caches based on a Map to Infinispan's Cache should be
trivial.

Limitations of Certain Map Methods


Certain methods exposed in Map have certain limitations when used with Infinispan, such as size(), values(),
keySet() and entrySet(). Specifically, these methods are unreliable and only provide a best-effort guess.
They do not acquire locks, either local or global, and concurrent modifications, additions and removals will
not be considered in the result of any of these calls. Further, they only operate on the local node, and as
such, do not give you a global(cluster) view of the state.
Attempting to perform these operations globally would have large performance impact as well as become a
scalability bottleneck. As such, these methods should only be used for informational or debugging purposes
only.

Mortal and Immortal Data


Further to simply storing entries, Infinispan's cache API allows you to attach mortality information to data.
For example, simply using put(key, value) would create an immortal entry, i.e., an entry that lives in the
cache forever, until it is removed (or evicted from memory to prevent running out of memory). If, however,
you put data in the cache using put(key, value, lifespan, timeunit), this creates a mortal entry, i.e., an entry
that has a fixed lifespan and expires after that lifespan.
In addition to lifespan , Infinispan also supports maxIdle as an additional metric with which to determine
expiration. Any combination of lifespans or maxIdles can be used.

JBoss Community Documentation

Page 262 of 617

Infinispan 6.0

Example of Using Expiry and Mortal Data


See this page for an example of using mortal data with Infinispan

putForExternalRead operation
Infinispan's Cache class contains a different 'put' operation called putForExternalRead. This operation is
particularly useful when Infinispan is used as a temporary cache for data that is persisted elsewhere. Under
heavy read scenarios, contention in the cache should not delay the real transactions at hand, since caching
should just be an optimization and not something that gets in the way.
To achieve this, putForExternalRead acts as a put call that only operates if the key is not present in the
cache, and fails fast and silently if another thread is trying to store the same key at the same time. In this
particular scenarion, caching data is a way to optimise the system and it's not desirable that a failure in
caching affects the on-going transaction, hence why failure is handled differently. putForExternalRead is
consider to be a fast operation because regardless of whether it's successful or not, it doesn't wait for any
locks, and so returns to the caller promptly.
To understand how to use this operation, let's look at basic example. Imagine a cache of Person instances,
each keyed by a PersonId, whose data originates in a separate data store. The following code shows the
most common pattern of using putForExternalRead within the context of this example:

// Id of the person to look up, provided by the application


PersonId id = ...;
// Get a reference to the cache where person instances will be stored
Cache<PersonId, Person> cache = ...;
// First, check whether the cache contains the person instance
// associated with with the given id
Person cachedPerson = cache.get(id);
if (cachedPerson == null) {
// The person is not cached yet, so query the data store with the id
Person person = dataStore.lookup(id);
// Cache the person along with the id so that future requests can
// retrieve it from memory rather than going to the data store
cache.putForExternalRead(id, person);
} else {
// The person was found in the cache, so return it to the application
return cachedPerson;
}

Please note that putForExternalRead should never be used as a mechanism to update the cache with a new
Person instance originating from application execution (i.e. from a transaction that modifies a Person's
address). When updating cached values, please use the standard put operation, otherwise the possibility of
caching corrupt data is likely.

JBoss Community Documentation

Page 263 of 617

Infinispan 6.0

3.50.2 The AdvancedCache interface


In addition to the simple Cache interface, Infinispan offers an AdvancedCache interface, geared towards
extension authors. The AdvancedCache offers the ability to inject custom interceptors, access certain
internal components and to apply flags to alter the default behavior of certain cache methods. The following
code snippet depicts how an AdvancedCache can be obtained:

AdvancedCache advancedCache = cache.getAdvancedCache();

Flags
Flags are applied to regular cache methods to alter the behavior of certain methods. For a list of all
available flags, and their effects, see the Flag enumeration. Flags are applied using
AdvancedCache.withFlags(). This builder method can be used to apply any number of flags to a cache
invocation, for example:

advancedCache.withFlags(Flag.CACHE_MODE_LOCAL, Flag.SKIP_LOCKING)
.withFlags(Flag.FORCE_SYNCHRONOUS)
.put("hello", "world");

Custom Interceptors
The AdvancedCache interface also offers advanced developers a mechanism with which to attach custom
interceptors. Custom interceptors allow developers to alter the behavior of the cache API methods, and the
AdvancedCache interface allows developers to attach these interceptors programmatically, at run-time. See
the AdvancedCache Javadocs for more details.
For more information on writing custom interceptors, see /javascript:;

3.51 Local mode cache


Introduction
Even though Infinispan's biggest potential is as distributed, in-memory data grid platform, one aspect of it
often gets overlooked - it can be used as a standalone cache node. But why would anyone use Infinispan
over, say, a ConcurrentHashMap? Here are some reasons:
__

JBoss Community Documentation

Page 264 of 617

Infinispan 6.0

Eviction. Built-in eviction ensures you don't run out of memory.


Write-through and write-behind caching. Going beyond memory and onto disk (or any other
pluggable CacheStore) means that your state survives restarts, and preloaded hot caches can be
configured.
JTA support and XA compliance. Participate in ongoing transactions with any JTA-compliant
transaction manager.
MVCC-based concurrency. Highly optimized for fast, non-blocking readers.
Manageability. Simple JMX or rich GUI management console via JOPR, you have a choice.
Not just for the JVM. RESTful API, and upcoming client/server modules speaking Memcached and
HotRodprotocols help non-JVM platforms use Infinispan.
Cluster-ready. Should the need arise.
__
So how do you get started with Infinispan in local mode? The simplest configuration file containing
just

<infinispan/>

is enough to get you started, or you can create DefaultCacheManager with no -argument constructor. Either
approach creates local default cache.
All the features above are exposed via an easy-to-use Cache interface, which extends ConcurrentMap and
is compatible with many other cache systems. Infinispan even ships with migration tools to help you move off
other cache solutions onto Infinispan, whether you need a cache to store data retrieved remotely or simply
as a 2nd level cache for Hibernate.
Performance
In the process of testing and tuning Infinispan on very large clusters, we have started to put together a
benchmarking framework. As a part of this framework, we have the ability to measure cache performance in
standalone, local mode. We compared Infinispan 4.0 in local mode against the latest JBoss Cache release
(3.2.2.GA) and EHCache (1.7.2). Some background on the tests:
Used a latest snapshot of the CacheBenchFwk
Run on a RHEL 5 server with 4 Intel Xeon cores, 4GB of RAM
Sun JDK 1.6.0_18, with -Xms1g -Xmx1g
Test run on a single node, with 25 concurrent threads, using randomly generated Strings as keys and
values and a 1kb payload for each entry, with a 80/20 read/write ratio.
Performance measured in transactions per second (higher = better).

JBoss Community Documentation

Page 265 of 617

Infinispan 6.0

In summary, what we have here is that when run in local mode, Infinispan is a high-performance standalone
caching engine which offers a rich set of features while still being trivially simple to configure and use.

JBoss Community Documentation

Page 266 of 617

Infinispan 6.0

3.52 Infinispan Command-line Console


Documentation for ispncon version 0.8.1
What is ispncon ?
Installation
Basic usage
Configuration
Cache operations
put
get
delete
clear
exists
version
Other commands
help
config
include
Interoperability with java clients
HTTP clients
Hot Rod Java Client
SpyMemcached Java Client

JBoss Community Documentation

Page 267 of 617

Infinispan 6.0

3.52.1 What is ispncon ?


Ispncon (Infinispan Command-Line Console) is a simple command-line interface to infinispan cache written
in python. It accesses the cache in client/server fashion, whereby infinispan server modules (Hot Rod,
Memcached, REST) have to be properly configured. Once you have a running instance of infinispan with
one of the server modules, you can issue simple cache requests via command line, like:

$ ispncon put keyA "Sample value under keyA"


$ ispncon get keyA
$ ispncon delete keyA

Furthermore it creates an abstraction above the specifics of the client/server protocol you use to access the
cache. The basic commands look the same whether you use Hot Rod, memcached or REST. The
client/protocol specifics are handled via protocol-specific configuration options or command arguments.
Your shell scripts should look basically the same for all the client modes, if you don't use any protocol
specific features.
Behind the scenes the console tool uses existing python clients to handle the communication with particular
server modules. The implementations are listed in the following table:
Client

Client implementation

Web

Hot Rod

python-client for hotrod

https://github.com/infinispan/python-client

Memcached python-memcached
REST

https://launchpad.net/python-memcached

httplib (standard module for python) http://docs.python.org/library/httplib.html

The source code and issue reporting for ispncon can be found here: https://github.com/infinispan/ispncon

JBoss Community Documentation

Page 268 of 617

Infinispan 6.0

3.52.2 Installation
Ispncon requires
python 2.6
python modules: python-devel, setuptools, infinispan, python-memcached
Installation steps:

$ git clone <a class="jive-link-external-small" href="https://github.com/infinispan/ispncon.git"


target="_blank">https://github.com/infinispan/ispncon.git</a>
$ cd ispncon/src
$ sudo python setup.py install

Make this part of your .bashrc or whatever so you have ispncon command on path

export ISPNCON_HOME=/path/to/ispncon
export PATH=$ISPNCON_HOME/bin:$PATH

JBoss Community Documentation

Page 269 of 617

Infinispan 6.0

3.52.3 Basic usage


Format

ispncon [options] <operation> [operation_options] <op_arguments>

Options
Option

Meaning

-c --client

Client to use, possible values: memcached, rest, hotrod (default)


Configuration key: ispncon.client_type

-h --host <host> Host/ip address to connect to. Default: localhost.


Configuration key: ispncon.host
-p --port <port>

Port to connect to. Default: 11222 (hotrod default port)


Configuration key: ispncon.port

-C

Named cache to use. Default: use default cache (no value)

--cache-name

Configuration key: ispncon.cache

<name>
-v --version

Print ispncon version and exit

-e

If true and operation fails, then fail with an exit code. If false just print ERROR message

--exit-on-error

and continue. This mostly makes sense for batch files.

-P --config

override configuration option <key> with value <value>. NOTE: the quotes are

"<key>

necessary, because getopt parser needs to get these as one string.

<value>"
The possible Operations are put, get, delete, clear, exists, help, config, include and each one is described in
the sections Cache operations and Other commands .

JBoss Community Documentation

Page 270 of 617

Infinispan 6.0

3.52.4 Configuration
On start-up ispncon reads the file ~/.ispncon to configure some of the default values to use, so that the user
doesn't have to enter the options like host, port, client type and cache name everytime he types a cache
command.
The format of the config file is like this:

[ispncon]
host = localhost
port = 8080
client_type = rest
cache =
exit_on_error = False
default_codec = None
[rest]
server_url = /infinispan-server-rest/rest
content_type = text/plain
[hotrod]
use_river_string_keys = True

The config parameters in the section ispncon are described in the_Basic usage_ section. The rest is
described here:
Config key

Meaning

rest.server_url

location of the REST server service, in the above example the HTTP
requests would be sent tohttp://localhost:8080/infinispan-server-rest/rest

rest.content_type

default MIME content type for entries stored via REST interface

default_codec

Default codec to use to encode/decode values. Possible values: None,


RiverString, RiverByteArray
see section Interoperability with java clients for further info

hotrod.use_river_string_keys If set to True, hotrod client will encode keys with RiverString codec - this is
necessary to be able to access the same data as via Java HotRod Client
using the same string keys.
see section Interoperability with java clients for further info

3.52.5 Cache operations


put
Put data under a specified key.
Format

JBoss Community Documentation

Page 271 of 617

Infinispan 6.0

put [options] <key> <value>

Options
Option

Meaning

-i --input-filename

Don't specify the value, instead put the contents of the specified file.

<filename>
-v --version <version>

Put only if version equals version given. Version format differs between
protocols:
HotRod: 64-bit integer version number
Memcached: 64-bit integer unique version id
REST: ETag string
Not yet implemented for REST client in infinispan, watch ISPN-1084 for more
info.

-l --lifespan <seconds>

Specifies lifespan of the entry. Integer, number of seconds.

-I --max-idle <seconds>

Specifies max idle time for the entry. Integer, number of seconds.

-a --put-if-absent

Return CONFLICT if value already exists and don't put anything in that case

-e --encode <codec>

Encode value using the specified codec

Return values
Exit

Output

Result description

STORED

Entry was stored sucessfully

ERROR

General error occurred

code

<msg>
2

NOT_FOUND -v option was used and entry doesn't exist

CONFLICT

-a option was used and the entry already exists, or -v was used and versions
don't match

NOTE: memcached client won't distinguish between states NOT_FOUND, CONFLICT and ERROR and
always will return ERROR if operation wasn't successfull. this is a limitation of python-memcached client.
see issues:
https://bugs.launchpad.net/python-memcached/+bug/684689
https://bugs.launchpad.net/python-memcached/+bug/684690
for discussion.

JBoss Community Documentation

Page 272 of 617

Infinispan 6.0
In later ispncon versions python-memcached client might get replaced by a customized version.

get
Get the data stored under the specified key.
Format

get [options] <key>

Options
Option

Meaning

-o --output-filename

Stores the output of the get operation into the file specified.

<filename>
-v --version

Get version along with the data. Version format differs between protocols:
HotRod: 64-bit integer version number
Memcached: 64-bit integer unique version id
REST: ETag string

-d --decode <codec>

Decode the value using the specified codec.

Return values
Exit

Output

Result description

In case no filename was specified:

Entry was found and is

<data, possibly multi-line>

returned.

code
0

(NOTE: the data might contain binary content, that is not suitable
for reading in terminal)
In case a filename was specified, nothing is printed on standard
output.
In case -v was specified, the output is prepended with one line:
VERSION <version>
1

ERROR <msg>

General error occurred

NOT_FOUND

Requested entry wasn't found


in the cache

JBoss Community Documentation

Page 273 of 617

Infinispan 6.0

delete
Delete the entry with the specified key.
Format

delete [options] <key>

Options
Option

Meaning

-v --version

Deletes only if the specified version matches the version in the cache

<version>

NOTE: versioned delete is not supported with memcached client. attempt to delete with -v
flag will end in ERROR message.
with REST client the situation is different, the protocol allows this, but it's not yet
implemented in infinispan, watch ISPN-1084 for more info

Return values
Exit code Output

Result description

DELETED

Entry was successfully deleted

ERROR <msg> General error occurred

NOT_FOUND

Entry wasn't found in the cache.

CONFLICT

Option -v was used and versions don't match

clear
Clear the cache
Format

clear

Return values
Exit code Output

Result description

DELETED

Cache was sucessfully cleared

ERROR <msg> General error occurred

JBoss Community Documentation

Page 274 of 617

Infinispan 6.0

exists
Verify if the entry exists in the cache
Format

exists <key>

Return values
Exit code Output

Result description

EXISTS

Entry with the given key exists

ERROR <msg> General error occurred

NOT_FOUND

Entry with the given key wasn't found in the cache

NOTE: memcached protocol doesn't support querying for existence of an entry in the cache so exists
operation is implemented (inefficiently) by get opeartion, that gets the whole entry with all the data from the
server.

JBoss Community Documentation

Page 275 of 617

Infinispan 6.0

version
Get version of the entry. Version format differs between protocols:
HotRod: 64-bit integer version number
Memcached: 64-bit integer unique version id
REST: ETag string
NOTE: The purpose of this command is to facilitate the parsing of the version string. HotRod and
Memcached client don't support efficient implementation of this operation. They transfer the whole entry from
the server to determine the version, so if applicable you are encouraged to use "get -v" command to obtain
version together with the data.
REST client implements this operation efficiently by executing HEAD method.
Format

version <key>

Return values
Exit code Output

Result description

<version>

If the entry exists.

ERROR <msg> General error occurred

NOT_FOUND

Requested entry wasn't found in the cache

3.52.6 Other commands


help
Print help about an operation
Format

help <operation>

NOTE: if no operation is supplied, prints list of supported operations

JBoss Community Documentation

Page 276 of 617

Infinispan 6.0

config
Change internal state/config of the client. This opeartion has only client-side effect.
Format

config
config save
config <key> <value>

- to print current config


- to save config to ~/.ispncon
- to change config for currently running session

Configuration values
see section Configuration for the meaning of different configuration options. Currently supported keys are:
cache
host
port
client_type
exit_on_error
rest.server_url
rest.content_type
These values directly correspond to the keys in the ~/.ispncon config file. The format of the key is

<section>.<config_key>

If no section is given, "ispncon" is implied.


Return values
Exit code Output

Result description

STORED

If configuration/client state was updated successfully.

multi-line output with config values If config command with no parameters was entered.

ERROR <msg>

JBoss Community Documentation

General error occurred

Page 277 of 617

Infinispan 6.0

include
Process cache commands from the specified batch file. The commands will be processed line by line.
Format

include <filename>

Return values
Exit code

Output

Result description

exit code of the last

The output depends on the commands

depends on the commands in

command in the file.

present in the input file

the batch file

NOTE: The name of this command and it's behaviour is going to change in the next version.

JBoss Community Documentation

Page 278 of 617

Infinispan 6.0

3.52.7 Interoperability with java clients


HTTP clients
when exchanging data via REST interface, the values are interpreted by any client as sequence of bytes.
The meaning is given to this byte-sequence by using MIME type specified via "Content-Type" HTTP header.
No special interoperability measures are needed here.

Hot Rod Java Client


If we want to read in ispncon the entries that were put with Hot Rod Java client, we need to use a special
option hotrod.use_river_string_keys = True. This will cause the string keys to be encoded the same way
the Java client does it.
Using hotrod.use_river_string_keys = True we're able to access the data that has been writen by the java
client, but we still see the raw binary values. To be able to see a value that has been put by Hot Rod java
client in a readable form and vice versa - to be able to see in Hot Rod Java client what we've put via ispncon
we need to use a codec. Currently there are two types of codecs: RiverString and RiverByteArray
RiverString - will decode a value that has been put as java.lang.String and vice versa - a value encoded
with this codec will be returned as java.lang.String on the java side
RiverByteArray - analogous to RiverString but works with byte[] (java byte array)
Codecs can be used either by specifying a default_codec option in the ~/.ispncon config file (in section
ispncon) or by specifying a codec on each put resp get using -e (--encode) resp -d (--decode) options.

SpyMemcached Java Client


Tested with spymemcached 2.7.
Value that is put by ispncon is interpreted as an UTF-8 string. meaning if we supply some bytes, on the java
side it will be recreated as new java.lang.String(bytes, "UTF-8")
This also works reversely: values put by java side as java.lang.String will be returned as UTF-8 bytes in
ispncon

3.53 Server Command Line Options


Infinispan ships several server modules, some of which can be started via calling startServer.sh or
startServer.bat scripts from command line. These currently include Hot Rod, Memcached and Web Socket
servers. Please find below the set of common command line parameters that can be passed to these
servers:
Note that starting with Infinispan 4.2.0.CR1, default Hot Rod port has changed from 11311 to 11222.

JBoss Community Documentation

Page 279 of 617

Infinispan 6.0
[g@eq]~/infinispan-4.1.0-SNAPSHOT% ./bin/startServer.sh -h
usage: startServer [options]
options:
-h, --help
Show this help message
-V, --version
Show version information
-Stop processing options
-p, --port=<num>
TCP port number to listen on
(default: 11211 for Memcached, 11222 for Hot Rod
and 8181 for WebSocket server)
-l, --host=<host or ip>
Interface to listen on
(default: 127.0.0.1, localhost)
-m, --master_threads=<num>
Number of threads accepting incoming connections
(default: unlimited while resources are available)
-t, --work_threads=<num>
Number of threads processing incoming requests and sending responses
(default: unlimited while resources are available)
-c, --cache_config=<filename>
Cache configuration file
(default: creates cache with default values)
-r, --protocol=[memcached|hotrod|websocket]
Protocol to understand by the server.
This is a mandatory option and you should choose one of these options
-i, --idle_timeout=<num>
Idle read timeout, in seconds, used to detect stale connections
(default: -1)
If no new messages have been read within this time,
the server disconnects the channel.
Passing -1 disables idle timeout.
-n, --tcp_no_delay=[true|false]
TCP no delay flag switch (default: true)
-s, --send_buf_size=<num>
Send buffer size (default: as defined by the OS).
-e, --recv_buf_size=<num>
Receive buffer size (default: as defined by the OS).
-o, --proxy_host=<host or ip>
Host address to expose in topology information sent to clients.
If not present, it defaults to configured host.
Servers that do not transmit topology information ignore this setting.

JBoss Community Documentation

Page 280 of 617

Infinispan 6.0

-x, --proxy_port=<num>
Port to expose in topology information sent to clients.
If not present, it defaults to configured port.
Servers that do not transmit topology information ignore this setting.
-k, --topo_lock_timeout=<num>
Controls lock timeout (in milliseconds) for those servers that maintain
the topology information in an internal cache.
-u, --topo_repl_timeout=<num>
Sets the maximum replication time (in milliseconds) for transfer of
topology information between servers.
If state transfer is enabled, this setting also controls the topology
cache state transfer timeout.
If state transfer is disabled, it controls the amount of time to wait
for this topology data to be lazily loaded from a different node when
not present locally.
-a, --topo_state_trasfer=[true|false]
Enabling topology information state transfer means that when a server
starts it retrieves this information from a different node.
Otherwise, if set to false, the topology information is lazily loaded
if not available locally.
-D<name>[=<value>]
Set a system property

3.54 Interacting With Hot Rod Server From Within Same


JVM
Introduction
Data Stored Directly Via A Hot Rod Client
Data Stored Via Remote Cache Store

JBoss Community Documentation

Page 281 of 617

Infinispan 6.0

3.54.1 Introduction
Normally, a Hot Rod server is accessed via a Hot Rod protocol client such as the Java Hot Rod client.
However, there might be situations where not only do you want to access the Hot Rod server remotely, you
might also want to access it locally from within the same JVM that the Hot Rod server is running. For
example, you might have an Infinispan cache pushing changes via the RemoteCacheStore to a Hot Rod
server, and if the cache goes down, you might want to access the data directly from the Hot Rod server
itself.
In this situations, we have to remember that the Hot Rod protocol specifies that keys and values are stored
as byte arrays. This means that if the client code, using an existing Hot Rod client, stored Strings or Integers,
or any other complex serializable or externalizable object, you won't be able to retrieve these objects straight
from the cache that the Hot Rod server uses.
To actually get the fully constructed objects that you're after, you're gonna need to take the byte arrays
stored within the Hot Rod server and unmarshall them into something that you can use. In the future, this is
something that might be done for you, as suggested in ISPN-706 (superseded by ISPN-2281), but for the
time being, clients wanting to access Hot Rod server data will have to do it themselves.
Two different use cases need to be differentiated at this stage and to explain how to transform the Hot Rod
server data into something usable, we'll assume that the clients are java clients:

JBoss Community Documentation

Page 282 of 617

Infinispan 6.0

3.54.2 Data Stored Directly Via A Hot Rod Client


The most common case is for a client to use a Hot Rod client library directly to store data in the Hot Rod
server. In this case, assuming that the client used the existing Java Hot Rod client, the default marshaller
used to marshall objects into byte arrays is the GenericJBossMarshaller. So, if a user wants to read data
from the Hot Rod server directly, it would need to execute something along the lines of:

import org.infinispan.marshall.jboss.GenericJBossMarshaller;
import org.infinispan.util.ByteArrayKey;
import org.infinispan.server.core.CacheValue;
...
// Create a new instance of the marshaller:
GenericJBossMarshaller marshaller = new GenericJBossMarshaller();
Object key = ...
// Take the cache key and convert into a byte array,
// and wrap it with an instance of ByteArrayKey
ByteArrayKey bytesKey = new ByteArrayKey(marshaller.objectToByteBuffer(key));
// Internally, Hot Rod stores values wrapped in a CacheValue, so retrieve it
CacheValue cacheValue = (CacheValue) cache.get(bytesKey);
// Take the data part which is byte array and unmarshall it to retrieve the value
Object value = marshaller.objectFromByteBuffer(cacheValue.data());

If you want to store data directly in the HotRod server, you'd have to execute something like this:

import org.infinispan.marshall.jboss.GenericJBossMarshaller;
import org.infinispan.util.ByteArrayKey;
import org.infinispan.server.core.CacheValue;
...
// Create a new instance of the marshaller:
GenericJBossMarshaller marshaller = new GenericJBossMarshaller();
Object key = ...
Object value = ...
// Take the cache key and convert into a byte array,
// and wrap it with an instance of ByteArrayKey
ByteArrayKey bytesKey = new ByteArrayKey(marshaller.objectToByteBuffer(key));
// Internally, Hot Rod stores values wrapped in a CacheValue, so create instance
// Remember that you need to give it a version number, so either:
// 1. Increment previous value's version
// 2. Or generate a new version number that minimises potential clash
//
with a concurrent update to the same key in the cluster
CacheValue cacheValue = new CacheValue(marshaller.objectToByteBuffer(value), 1)
// Finally, store it in the cache
cache.put(bytesKey, cacheValue);

JBoss Community Documentation

Page 283 of 617

Infinispan 6.0

3.54.3 Data Stored Via Remote Cache Store


Other times, Hot Rod server might be storing data coming from a RemoteCacheStore, rather than user code.
In this case, there're a couple of differences to the code above. First of all, the marshaller is slightly different.
Instead, the RemoteCacheStore uses the VersionAwareMarshaller which all it does is add Infinispan version
information to the byte array generated. The second difference is that RemoteCacheStore stores internal
cache entry classes, which apart from the value part, they contain other extra information. So, any code
trying to read these directly from the Hot Rod server would need to take in account. For example, to read
data from such Hot Rod server:

import
import
import
import
...

org.infinispan.marshall.VersionAwareMarshaller;
org.infinispan.util.ByteArrayKey;
org.infinispan.server.core.CacheValue;
org.infinispan.container.entries.CacheEntry;

// Create a new instance of the marshaller


VersionAwareMarshaller marshaller = new VersionAwareMarshaller();
Object key = ...
// Take the cache key and convert into a byte array,
// and wrap it with an instance of ByteArrayKey
ByteArrayKey bytesKey = new ByteArrayKey(marshaller.objectToByteBuffer(key));
// Internally, Hot Rod stores values wrapped in a CacheValue, so retrieve it
CacheValue cacheValue = (CacheValue) cache.get(bytesKey);
// However, in this case the data part of CacheValue does not contain directly
// the value Instead, it contains an instance of CacheEntry, so we need to
// unmarshall that and then get the actual value
CacheEntry cacheEntry = (CacheEntry)
marshaller.objectFromByteBuffer(cacheValue.data());
Object value = cacheEntry.getValue();

And to actually write data back into the Hot Rod server directly:

JBoss Community Documentation

Page 284 of 617

Infinispan 6.0

import
import
import
import
import
...

org.infinispan.marshall.VersionAwareMarshaller;
org.infinispan.util.ByteArrayKey;
org.infinispan.server.core.CacheValue;
org.infinispan.container.entries.CacheEntry;
org.infinispan.container.entries.InternalEntryFactory;

// Create a new instance of the marshaller:


VersionAwareMarshaller marshaller = new VersionAwareMarshaller();
Object key = ...
Object value = ...
// Take the cache key and convert into a byte array
ByteArrayKey bytesKey = new ByteArrayKey(marshaller.objectToByteBuffer(key));
// With the value to store, a new CacheEntry instance needs to be created:
CacheEntry cacheEntry = InternalEntryFactory.create(bytesKey, value, ...)
// Internally, Hot Rod stores values wrapped in a CacheValue, so create instance
// Remember that you need to give it a version number, so either:
// 1. Increment previous value's version
// 2. Or generate a new version number that minimises potential clash
//
with a concurrent update to the same key in the cluster
CacheValue cacheValue = new CacheValue(
marshaller.objectToByteBuffer(cacheEntry), 1)
// Finally, store it in the cache
cache.put(bytesKey, cacheValue);

3.55 Multiple Tiers of Caches


3.55.1 Introduction
The introduction of HotRod protocol and RemoteCacheLoader opened the way for a set of new architectures
in Infinispan, where layers of caches can exists and interact. This article takes a look at such an layered
architecture.

3.55.2 Building blocks


HotRod is a binary protocol defined for exposing an Infinispan cluster as an caching server to multiple
platforms. It has support for load balancing and smart routing.
RemoteCacheLoader is a cache loader that knows how to read/store data in a remote infinispan cluster. For
that it makes use of the java hotrod client.

JBoss Community Documentation

Page 285 of 617

Infinispan 6.0

3.55.3 Sample architecture/near caching

The diagram above shows an Infinispan server cluster running 3 hotrod servers. This cluster is accessed
remotely, through HotRod, by another infinispan cluster: client cluster (upper part of the image). All the
nodes in the server cluster are configured to run HotRod servers, so requests from remote loader are being
balanced between them. The client cluster is configured with invalidation as cluster mode and a
RemoteCacheLoader to acess data stored in the server cluster. Application data is held on the server cluster
which runs in DIST mode for scalability.
In this deployment the client code, running in same address space with the client cluster, holds all its data in
the server cluster. Client cluster acts as an near-cache for frequently accessed entries.

3.55.4 Want to know more?


On the documentation main page:
cache loaders are described in the "Cache loaders" section
Hotrod's specification, server and client in the "Hot Rod" section

3.56 Infinispan REST Server


3.56.1 Introduction
This server provides easy to use RESTful HTTP access to the Infinispan data grid, build on RESTEasy. This
application is delivered (currently) as a war, which you can deploy to a servlet container (as many instances
as you need).

JBoss Community Documentation

Page 286 of 617

Infinispan 6.0

3.56.2 Configuration
Out of the box, Infinispan will create and use a new LOCAL mode cache. To set a custom configuration:
1. Unzip the REST WAR file (or use an exploded deployment)
2. Create an Infinispan configuration XML file and name this infinispan.xml
3. Place this file in infinispan-server-rest.war/WEB-INF/classes
Alternatively, you could:
1. Unzip the REST WAR file (or use an exploded deployment)
2. Create an Infinispan configuration XML file, call it whatever you want and place it wherever you want
3. Edit infinispan-server-rest.war/WEB-INF/web.xml and look for the infinispan.config
init-param. Change the value of this init-param to the full path to your Infinispan configuration.

Please note that the REST server only allows interaction with either the default cache (named
___defaultcache) or one of the named caches in the configuration file. This is because the REST server
starts the default and pre-defined caches on startup in order to provide consistent behaivor.

Warning
Creation of new named caches on the fly is not supported.

As a result, if you don't use a custom configuration file, you'll only be able to interact with the default cache.
To interact with more caches, use a configuration file with the desired named caches.

JBoss Community Documentation

Page 287 of 617

Infinispan 6.0

3.56.3 Accessing Data - via URLs


HTTP PUT and POST methods are used to place data in the cache, with URLs to address the cache name
and key(s) - the data being the body of the request (the data can be anything you like). It is important that a
Content-Type header is set. GET/HEAD are used to retrieve data Please see here for the details. Other
headers are used to control the cache settings and behaviour (detailed in that link).

3.56.4 Client side code


Part of the point of a RESTful service is that you don't need to have tightly coupled client libraries/bindings.
All you need is a HTTP client library. For Java, Apache HTTP Commons Client works just fine (and is used
in the integration tests), or you can use java.net API.

Ruby client code:


# Shows how to interact with Infinispan REST api from ruby.
# No special libraries, just standard net/http
#
# Author: Michael Neale
#
require 'net/http'
http = Net::HTTP.new('localhost', 8080)
#Create new entry
http.post('/infinispan/rest/MyData/MyKey', 'DATA HERE', {"Content-Type" => "text/plain"})
#get it back
puts http.get('/infinispan/rest/MyData/MyKey').body
#use PUT to overwrite
http.put('/infinispan/rest/MyData/MyKey', 'MORE DATA', {"Content-Type" => "text/plain"})
#and remove...
http.delete('/infinispan/rest/MyData/MyKey')
#Create binary data like this... just the same...
http.put('/infinispan/rest/MyImages/Image.png', File.read('/Users/michaelneale/logo.png'),
{"Content-Type" => "image/png"})

#and if you want to do json...


require 'rubygems'
require 'json'
#now for fun, lets do some JSON !
data = {:name => "michael", :age => 42 }
http.put('/infinispan/rest/Users/data/0', data.to_json, {"Content-Type" => "application/json"})

JBoss Community Documentation

Page 288 of 617

Infinispan 6.0

Python client code:


# Sample python code using the standard http lib only
#
import httplib

#putting data in
conn = httplib.HTTPConnection("localhost:8080")
data = "SOME DATA HERE \!" #could be string, or a file...
conn.request("POST", "/infinispan/rest/Bucket/0", data, {"Content-Type": "text/plain"})
response = conn.getresponse()
print response.status
#getting data out
import httplib
conn = httplib.HTTPConnection("localhost:8080")
conn.request("GET", "/infinispan/rest/Bucket/0")
response = conn.getresponse()
print response.status
print response.read()

Java client code:


import
import
import
import
import
import

java.io.BufferedReader;
java.io.IOException;
java.io.InputStreamReader;
java.io.OutputStreamWriter;
java.net.HttpURLConnection;
java.net.URL;

/**
* Rest example accessing Infinispan Cache.
* @author Samuel Tauil (samuel@redhat.com)
*
*/
public class RestExample {
/**
* Method that puts a String value in cache.
* @param urlServerAddress
* @param value
* @throws IOException
*/
public void putMethod(String urlServerAddress, String value) throws IOException {
System.out.println("----------------------------------------");
System.out.println("Executing PUT");
System.out.println("----------------------------------------");
URL address = new URL(urlServerAddress);
System.out.println("executing request " + urlServerAddress);
HttpURLConnection connection = (HttpURLConnection) address.openConnection();

JBoss Community Documentation

Page 289 of 617

Infinispan 6.0
System.out.println("Executing put method of value: " + value);
connection.setRequestMethod("PUT");
connection.setRequestProperty("Content-Type", "text/plain");
connection.setDoOutput(true);
OutputStreamWriter outputStreamWriter = new
OutputStreamWriter(connection.getOutputStream());
outputStreamWriter.write(value);
connection.connect();
outputStreamWriter.flush();
System.out.println("----------------------------------------");
System.out.println(connection.getResponseCode() + " " + connection.getResponseMessage());
System.out.println("----------------------------------------");
connection.disconnect();
}
/**
* Method that gets an value by a key in url as param value.
* @param urlServerAddress
* @return String value
* @throws IOException
*/
public String getMethod(String urlServerAddress) throws IOException {
String line = new String();
StringBuilder stringBuilder = new StringBuilder();
System.out.println("----------------------------------------");
System.out.println("Executing GET");
System.out.println("----------------------------------------");
URL address = new URL(urlServerAddress);
System.out.println("executing request " + urlServerAddress);
HttpURLConnection connection = (HttpURLConnection) address.openConnection();
connection.setRequestMethod("GET");
connection.setRequestProperty("Content-Type", "text/plain");
connection.setDoOutput(true);
BufferedReader&nbsp; bufferedReader = new BufferedReader(new
InputStreamReader(connection.getInputStream()));
connection.connect();
while ((line = bufferedReader.readLine()) \!= null) {
stringBuilder.append(line + '\n');
}
System.out.println("Executing get method of value: " + stringBuilder.toString());
System.out.println("----------------------------------------");
System.out.println(connection.getResponseCode() + " " + connection.getResponseMessage());
System.out.println("----------------------------------------");
connection.disconnect();

JBoss Community Documentation

Page 290 of 617

Infinispan 6.0
return stringBuilder.toString();
}
/**
* Main method example.
* @param args
* @throws IOException
*/
public static void main(String\[\] args) throws IOException {
//Attention to the cache name "cacheX" it was configured in xml file with tag <namedCache
name="cacheX">
RestExample restExample = new RestExample();
restExample.putMethod("http://localhost:8080/infinispan/rest/cacheX/1", "Infinispan REST
Test");
restExample.getMethod("http://localhost:8080/infinispan/rest/cacheX/1");
}
}

3.56.5 Future:
Sample persistence options to make this a long term data grid
Query and indexing (of known MIME types, and JSON, XML etc)
Returning both lists of buckets + entries as <link> relations (where it makes sense)
Monitoring of stats via Web interface
(optional: WADL?)

3.57 CDI Support


Introduction
Maven Dependencies
Embedded cache integration
Inject an embedded cache
Override the default embedded cache manager and configuration
Configure the transport for clustered use
Remote cache integration
Inject a remote cache
Override the default remote cache manager
Use a custom remote/embedded cache manager for one or more cache
Use a JBoss AS 7 configured cache
Use JCache caching annotations

JBoss Community Documentation

Page 291 of 617

Infinispan 6.0

3.57.1 Introduction
Infinispan includes integration with CDI in the infinispan-cdi module. Configuration and injection of the
Inifispan's Cache API is provided, and it is planned to bridge Cache listeners to the CDI event system. The
module also provide partial support of the JCache (JSR-107) caching annotations - for further details see
Chapter 8 of the JCACHE specification.

3.57.2 Maven Dependencies


All you need is org.infinispan:infinispan-cdi

<dependency>
<groupId>org.infinispan</groupId>
<artifactId>infinispan-cdi</artifactId>
<version>${infinispan.version}</version>
</dependency>

Which version of Infinispan should I use?


We recommend using the latest final version of the infinispan-cdi module. This module is
available since Infinispan version 5.0.0.CR8.

3.57.3 Embedded cache integration


Inject an embedded cache
By default you can inject the default Infinispan cache. Let's look at the following example:

JBoss Community Documentation

Page 292 of 617

Infinispan 6.0

...
import javax.inject.Inject;
public class GreetingService {
@Inject
private Cache<String, String> cache;
public String greet(String user) {
String cachedValue = cache.get(user);
if (cachedValue == null) {
cachedValue = "Hello " + user;
cache.put(user, cachedValue);
}
return cachedValue;
}
}

If you want to use a specific cache you just have to provide your own cache configuration and cache
qualifier. For example, if you want to use a custom cache for the GreetingService you should write your
own qualifier (here GreetingCache) and define its configuration:

The new configuration system is used since 5.1.0.CR2


As you probably know Infinispan 5.1.0 comes with a new way to configure your cache
programmatically and a bit more (more information are available here). Now to configure a cache
you must use this new configuration system.

...
import javax.inject.Qualifier;
@Qualifier
@Target({ElementType.FIELD, ElementType.PARAMETER, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface GreetingCache {
}

JBoss Community Documentation

Page 293 of 617

Infinispan 6.0

...
import
import
import
import

org.infinispan.configuration.cache.Configuration;
org.infinispan.configuration.cache.ConfigurationBuilder;
org.infinispan.cdi.ConfigureCache;
javax.enterprise.inject.Produces;

public class Config {


@ConfigureCache("greeting-cache") // This is the cache name.
@GreetingCache // This is the cache qualifier.
@Produces
public Configuration greetingCacheConfiguration() {
return new ConfigurationBuilder()
.eviction()
.strategy(EvictionStrategy.LRU)
.maxEntries(1000)
.build();
}
// The same example without providing a custom configuration.
// In this case the default cache configuration will be used.
@ConfigureCache("greeting-cache")
@GreetingCache
@Produces
public Configuration greetingCacheConfiguration;
}

To use this cache in the GreetingService add the @GeetingCache qualifier on your cache injection
point. Simple!

JBoss Community Documentation

Page 294 of 617

Infinispan 6.0

Override the default embedded cache manager and configuration


Since 5.1.0.CR1 @OverrideDefault is deprecated
To migrate your code remove this annotation from your producers as detailed in the following
section.

You can override the default cache configuration used by the default embedded cache manager. For that,
you just have to create one Configuration producer with the @Default qualifier as illustrated in the
following snippet:

public class Config {


// By default CDI adds the @Default qualifier if no other qualifier is provided.
@Produces
public Configuration defaultEmbeddedCacheConfiguration() {
return new ConfigurationBuilder()
.eviction()
.strategy(EvictionStrategy.LRU)
.maxEntries(100)
.build();
}
}

It's also possible to override the default embedded cache manager used. The new default cache manager
produced must have the @Default qualifier and the scope @ApplicationScoped.

...
import javax.enterprise.context.ApplicationScoped;
public class Config {
@Produces
@ApplicationScoped
public EmbeddedCacheManager defaultEmbeddedCacheManager() {
return new DefaultCacheManager(new ConfigurationBuilder()
.eviction()
.strategy(EvictionStrategy.LRU)
.maxEntries(100)
.build());
}
}

JBoss Community Documentation

Page 295 of 617

Infinispan 6.0

Configure the transport for clustered use


To use Infinispan in a clustered mode you have to configure the transport with the GlobalConfiguration.
To achieve that override the default cache manager as explained in the previous section. Look at the
following snippet:

...
package org.infinispan.configuration.global.GlobalConfigurationBuilder;
@Produces
@ApplicationScoped
public EmbeddedCacheManager defaultClusteredCacheManager() {
return new DefaultCacheManager(
new GlobalConfigurationBuilder().transport().defaultTransport().build(),
new ConfigurationBuilder().eviction().maxEntries(7).build()
);
}

JBoss Community Documentation

Page 296 of 617

Infinispan 6.0

3.57.4 Remote cache integration


Inject a remote cache
With the CDI integration it's also possible to use a remote cache. For example you can inject the default
RemoteCache as illustrated in the following snippet:

public class GreetingService {


@Inject
private RemoteCache<String, String> cache;
public String greet(String user) {
String cachedValue = cache.get(user);
if (cachedValue == null) {
cachedValue = "Hello " + user;
cache.put(user, cachedValue);
}
return cachedValue;
}
}

If you want to use another cache, for example the greeting-cache, add the @Remote qualifier on the cache
injection point which contains the cache name.

public class GreetingService {


@Inject @Remote("greeting-cache")
private RemoteCache<String, String> cache;
...
}

Adding the @Remote cache qualifier on each injection point might be error prone. That's why the remote
cache integration provides another way to achieve the same goal. For that you have to create your own
qualifier annotated with @Remote:

@Remote("greeting-cache")
@Qualifier
@Target({ElementType.FIELD, ElementType.PARAMETER, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface RemoteGreetingCache {
}

To use this cache in the GreetingService add the qualifier @RemoteGreetingCache qualifier on your
cache injection.

JBoss Community Documentation

Page 297 of 617

Infinispan 6.0

Override the default remote cache manager


Like the embedded cache integration, the remote cache integration comes with a default remote cache
manager producer. This default remote cache manager can be overridden as illustrated in the following
snippet:

public class Config {


@Produces
@ApplicationScoped
public RemoteCacheManager defaultRemoteCacheManager() {
return new RemoteCacheManager(localhost, 1544);
}
}

JBoss Community Documentation

Page 298 of 617

Infinispan 6.0

3.57.5 Use a custom remote/embedded cache manager for one


or more cache
It's possible to use a custom cache manager for one or more cache. You just need to annotate the cache
manager producer with the cache qualifiers. Look at the following example:

public class Config {


@GreetingCache
@Produces
@ApplicationScoped
public EmbeddedCacheManager specificEmbeddedCacheManager() {
return new DefaultCacheManager(new ConfigurationBuilder()
.expiration()
.lifespan(60000l)
.build());
}
@RemoteGreetingCache
@Produces
@ApplicationScoped
public RemoteCacheManager specificRemoteCacheManager() {
return new RemoteCacheManager("localhost", 1544);
}
}

With the above code the GreetingCache or the RemoteGreetingCache will be associated with the
produced cache manager.

Producer method scope


To work properly the producers must have the scope @ApplicationScoped. Otherwise each
injection of cache will be associated to a new instance of cache manager.

JBoss Community Documentation

Page 299 of 617

Infinispan 6.0

3.57.6 Use a JBoss AS 7 configured cache


With JBoss AS 7, you can setup an Infinispan cache manager in the server configuration file. This allows you
to externalize your Infinispan configuration and also to lookup the cache manager from JNDI, normally with
the @Resource annotation.
As we mentioned earlier, you can override the default cache manager used by the Infinispan CDI extension.
To use a JBoss AS 7 configured cache, you need to use the cache manager defined in JBoss AS 7. You
only need to annotate the default cache manager producer with @Resource. The following example shows
how use an embedded cache manager configured in JBoss AS 7.

...
import javax.annotation.Resource;
public class Config {
@Produces
@ApplicationScoped
@Resource(lookup="java:jboss/infinispan/my-container-name")
private EmbeddedCacheManager defaultCacheManager;
}

3.57.7 Use JCache caching annotations


The infinispan-cdi module provides a partial support of JCache caching annotations. These
annotations provide a simple way to handle common use cases. The following caching annotations are
defined in this specification:
@CacheResult caches the result of a method call
@CachePut caches a method parameter
@CacheRemoveEntry removes an entry from a cache
@CacheRemoveAll removes all entries from a cache

Annotations target type


These annotations must only be used on methods.

To use these annotations the following interceptors must be declared in your application beans.xml.

JBoss Community Documentation

Page 300 of 617

Infinispan 6.0

<beans xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/beans_1_0.xsd">
<interceptors>
<class>org.infinispan.cdi.interceptor.CacheResultInterceptor</class>
<class>org.infinispan.cdi.interceptor.CachePutInterceptor</class>
<class>org.infinispan.cdi.interceptor.CacheRemoveEntryInterceptor</class>
<class>org.infinispan.cdi.interceptor.CacheRemoveAllInterceptor</class>
</interceptors>
</beans>

The following snippet of code illustrates the use of @CacheResult annotation. As you can see it simplifies
the caching of the Greetingservice#greet method results.

import javax.cache.interceptor.CacheResult;
public class GreetingService {
@CacheResult
public String greet(String user) {
return "Hello" + user;
}
}

The first version of the GreetingService and the above version have exactly the same behavior. The only
difference is the cache used. By default it's the fully qualified name of the annotated method with its
parameter types (e.g. org.infinispan.example.GreetingService.greet(java.lang.String)).

Can I use a different cache?


To use another cache specify its name with the cacheName attribute of the cache annotation. For
example:

@CacheResult(cacheName = "greeting-cache")

JBoss Community Documentation

Page 301 of 617

Infinispan 6.0

3.58 Marshalling
Introduction
The Role Of JBoss Marshalling
Support For Non-Serializable Objects
Store As Binary
Equality Considerations
Store-by-value via defensive copying
Advanced Configuration
Troubleshooting

3.58.1 Introduction
Marshalling is the process of converting Java POJOs into something that can be written in a format that can
be transfered over the wire. Unmarshalling is the reverse process whereby data read from a wire format is
transformed back into Java POJOs. Infinispan uses marshalling/unmarshalling in order to:
Transform data so that it can be send over to other Infinispan nodes in a cluster.
Transform data so that it can be stored in underlying cache stores.
Store data in Infinispan in a wire format to provide lazy deserialization capabilities.

3.58.2 The Role Of JBoss Marshalling


Since performance is a very important factor in this process, Infinispan uses JBoss Marshalling framework
instead of standard Java Serialization in order to marshall/unmarshall Java POJOs. Amongst other things,
this framework enables Infinispan to provide highly efficient ways to marshall internal Infinispan Java POJOs
that are constantly used. Apart from providing more efficient ways to marshall Java POJOs, including
internal Java classes, JBoss Marshalling uses highly performant java.io.ObjectOutput and
java.io.ObjectInput implementations compared to standard java.io.ObjectOutputStream and
java.io.ObjectInputStream.

3.58.3 Support For Non-Serializable Objects


From a users perspective, a very common concern is whether Infinispan supports storing non-Serializable
objects. In 4.0, an Infinispan cache instance can only store non-Serializable key or value objects if, and only
if:
cache is configured to be a local cache and...
cache is not configured with lazy serialization and...
cache is not configured with any write-behind cache store

JBoss Community Documentation

Page 302 of 617

Infinispan 6.0
If either of these options is true, key/value pairs in the cache will need to be marshalled and currently they
require to either to extend java.io.Serializable or java.io.Externalizable. However, since Infinispan 5.0,
marshalling non-Serializable key/value objects is supported as long as users can to provide meaningful
Externalizer implementations for these non-Seralizable objects, see this article to find out more.
If you're unable to retrofit Serializable or Externalizable into the classes whose instances are stored in
Infinispan, you could alternatively use something like XStream to convert your Non-Serializable objects into
an String that can be stored into Infinispan. You can find an example on how to use XStream here. The one
caveat about using XStream is that it slows down the process of storing key/value objects due to the XML
transformation that it needs to do.

Store As Binary
Store as binary enables data to be stored in its serialized form. This can be useful to achieve lazy
deserialization, which is the mechanism by which Infinispan by which serialization and deserialization of
objects is deferred till the point in time in which they are used and needed. This typically means that any
deserialization happens using the thread context class loader of the invocation that requires deserialization,
and is an effective mechanism to provide classloader isolation. By default lazy deserialization is disabled but
if you want to enable it, you can do it like this:
Via XML at the Cache level, either under <namedCache> or <default> elements:

<storeAsBinary enabled="true"/>

Programmatically:

ConfigurationBuilder builder = ...


builder.storeAsBinary().enable();

JBoss Community Documentation

Page 303 of 617

Infinispan 6.0

Equality Considerations
When using lazy deserialization/storing as binary, keys and values are wrapped as MarshalledValues. It is
this wrapper class that transparently takes care of serialization and deserialization on demand, and internally
may have a reference to the object itself being wrapped, or the serialized, byte array representation of this
object.
This has a particular effect on the behavior of equality. The equals() method of this class will either compare
binary representations (byte arrays) or delegate to the wrapped object instance's equals() method,
depending on whether both instances being compared are in serialized or deserialized form at the time of
comparison. If one of the instances being compared is in one form and the other in another form, then one
instance is either serialized or deserialized. The preference will be to compare object representations,
unless the cache is compacted, in which case byte array comparison is favored.
This will affect the way keys stored in the cache will work, when {{storeAsBinary]} is used, since
comparisons happen on the key which will be wrapped by a MarshalledValue. Implementers of equals()
methods on their keys need to be aware of the behavior of equality comparison, when a key is wrapped as a
MarshalledValue, as detailed above.

Store-by-value via defensive copying


Starting with Infinispan 5.3.0.Final, storeAsBinary configuration offers the possibility to enable defensive
copying, which allows for store-by-value like behaviour.
When defensive copying is disabled (default), Infinispan keeps object references around and stores them in
a binary format lazily. So clients can still modify entries via original object references, and marshalling only
happens when entries are to be replicated/distributed, or stored in a cache store. Since client references are
valid, clients can make changes to entries in the cache using those references, but these modifications are
only local and you still need to call one of the cache's put/replace... methods in order for changes to
replicate. This is essentially store-by-reference. This is the default mode for performance reasons.
When defensive copies are enabled, Infinispan marshalls objects the moment they're stored, hence changes
made to object references are not stored in the cache, not even for local caches. This provides
store-by-value like behaviour. Enabling defensive copying can be achieved:
Via XML at the Cache level, either under <namedCache> or <default> elements:

<storeAsBinary enabled="true" defensive="true"/>

Programmatically:

ConfigurationBuilder builder = ...


builder.storeAsBinary().enable().defensive(true);

JBoss Community Documentation

Page 304 of 617

Infinispan 6.0

3.58.4 Advanced Configuration


Internally, Infinispan uses an implementation of this Marshaller interface in order to marshall/unmarshall
Java objects so that they're sent other nodes in the grid, or so that they're stored in a cache store, or even so
to transform them into byte arrays for lazy deserialization.
By default, Infinispan uses the VersionAwareMarshaller which, as the name suggests, adds a version short
to the start of any stream when writing, enabling similar VersionAwareMarshaller instances to read the
version short and know which specific marshaller implementation to delegate the call to. Using a
VersionAwareMarshaller helps achieve wire protocol compatibility between minor releases but still affords us
the flexibility to tweak and improve the wire protocol between minor or micro releases. Optionally, Infinispan
users to optionally provide their own marshaller, for example:
Via XML at the CacheManager level, under <global> element:

<serialization marshallerClass="com.acme.MyMarshaller"/>

Programatically:

GlobalConfigurationBuilder builder = ...


builder.serialization().marshaller(myMarshaller); // needs an instance of the marshaller

Troubleshooting
Sometimes it might happen that the Infinispan marshalling layer, and in particular JBoss Marshalling, might
have issues marshalling/unmarshalling some user object. In Infinispan 4.0, marshalling exceptions will
contain further information on the objects that were being marshalled. Example:

<code class="jive-code jive-java">java.io.NotSerializableException: java.lang.Object


at org.jboss.marshalling.river.RiverMarshaller.doWriteObject(RiverMarshaller.java:857)
at org.jboss.marshalling.AbstractMarshaller.writeObject(AbstractMarshaller.java:407)
at
org.infinispan.marshall.exts.ReplicableCommandExternalizer.writeObject(ReplicableCommandExternalizer.java:54)a
org.infinispan.marshall.jboss.ConstantObjectTable$ExternalizerAdapter.writeObject(ConstantObjectTable.java:267
org.jboss.marshalling.river.RiverMarshaller.doWriteObject(RiverMarshaller.java:143)
at org.jboss.marshalling.AbstractMarshaller.writeObject(AbstractMarshaller.java:407)
at org.infinispan.marshall.jboss.JBossMarshaller.objectToObjectStream(JBossMarshaller.java:167)
at org.infinispan.marshall.VersionAwareMarshaller.objectToBuffer(VersionAwareMarshaller.java:92)
at
org.infinispan.marshall.VersionAwareMarshaller.objectToByteBuffer(VersionAwareMarshaller.java:170)at
org.infinispan.marshall.VersionAwareMarshallerTest.testNestedNonSerializable(VersionAwareMarshallerTest.java:4
by: an exception which occurred:
in object java.lang.Object@b40ec4
in object org.infinispan.commands.write.PutKeyValueCommand@df661da7
... Removed 22 stack frames
</code>

JBoss Community Documentation

Page 305 of 617

Infinispan 6.0
The way the "in object" messages are read is the same in which stacktraces are read. The highest "in
object" being the most inner one and the lowest "in object" message being the most outer one. So, the
above example indicates that a java.lang.Object instance contained in an instance of
org.infinispan.commands.write.PutKeyValueCommand could not be serialized because
java.lang.Object@b40ec4 is not serializable.
This is not all though! If you enable DEBUG or TRACE logging levels, marshalling exceptions will contain
show the toString() representations of objects in the stacktrace. For example:

<code class="jive-code jive-java">java.io.NotSerializableException: java.lang.Object


...
Caused by: an exception which occurred:
in object java.lang.Object@b40ec4
-> toString = java.lang.Object@b40ec4
in object org.infinispan.commands.write.PutKeyValueCommand@df661da7
-> toString = PutKeyValueCommand{key=k, value=java.lang.Object@b40ec4, putIfAbsent=false,
lifespanMillis=0, maxIdleTimeMillis=0}
</code>

With regards to unmarshalling exceptions, showing such level of information it's a lot more complicated but
where possible. Infinispan will provide class type information. For example:

<code class="jive-code jive-java">java.io.IOException: Injected failue!


at
org.infinispan.marshall.VersionAwareMarshallerTest$1.readExternal(VersionAwareMarshallerTest.java:426)at
org.jboss.marshalling.river.RiverUnmarshaller.doReadNewObject(RiverUnmarshaller.java:1172)
at org.jboss.marshalling.river.RiverUnmarshaller.doReadObject(RiverUnmarshaller.java:273)
at org.jboss.marshalling.river.RiverUnmarshaller.doReadObject(RiverUnmarshaller.java:210)
at org.jboss.marshalling.AbstractUnmarshaller.readObject(AbstractUnmarshaller.java:85)
at
org.infinispan.marshall.jboss.JBossMarshaller.objectFromObjectStream(JBossMarshaller.java:210)
at
org.infinispan.marshall.VersionAwareMarshaller.objectFromByteBuffer(VersionAwareMarshaller.java:104)at
org.infinispan.marshall.VersionAwareMarshaller.objectFromByteBuffer(VersionAwareMarshaller.java:177)at
org.infinispan.marshall.VersionAwareMarshallerTest.testErrorUnmarshalling(VersionAwareMarshallerTest.java:431)
by: an exception which occurred:
in object of type org.infinispan.marshall.VersionAwareMarshallerTest$1
</code>

In this example, an IOException was thrown when trying to unmarshall a instance of the inner class
org.infinispan.marshall.VersionAwareMarshallerTest$1. In similar fashion to marshalling exceptions, when
DEBUG or TRACE logging levels are enabled, classloader information of the class type is provided. For
example:

JBoss Community Documentation

Page 306 of 617

Infinispan 6.0

<code class="jive-code jive-java">java.io.IOException: Injected failue!


...
Caused by: an exception which occurred:
in object of type org.infinispan.marshall.VersionAwareMarshallerTest$1
-> classloader hierarchy:
-> type classloader = sun.misc.Launcher$AppClassLoader@198dfaf
->...file:/opt/eclipse/configuration/org.eclipse.osgi/bundles/285/1/.cp/eclipse-testng.jar
->...file:/opt/eclipse/configuration/org.eclipse.osgi/bundles/285/1/.cp/lib/testng-jdk15.jar
->...file:/home/galder/jboss/infinispan/code/trunk/core/target/test-classes/
->...file:/home/galder/jboss/infinispan/code/trunk/core/target/classes/
->...file:/home/galder/.m2/repository/org/testng/testng/5.9/testng-5.9-jdk15.jar
->...file:/home/galder/.m2/repository/net/jcip/jcip-annotations/1.0/jcip-annotations-1.0.jar
->...file:/home/galder/.m2/repository/org/easymock/easymockclassextension/2.4/easymockclassextension-2.4.jar->
parent classloader = sun.misc.Launcher$ExtClassLoader@1858610
->...file:/usr/java/jdk1.5.0_19/jre/lib/ext/localedata.jar
->...file:/usr/java/jdk1.5.0_19/jre/lib/ext/sunpkcs11.jar
->...file:/usr/java/jdk1.5.0_19/jre/lib/ext/sunjce_provider.jar
->...file:/usr/java/jdk1.5.0_19/jre/lib/ext/dnsns.jar
... Removed 22 stack frames
</code>

Finding the root cause of marshalling/unmarshalling exceptions can sometimes be really daunting but we
hope that the above improvements would help get to the bottom of those in a more quicker and efficient
manner.

3.59 Batching
3.59.1 Introduction
Generally speaking, one should use batching API whenever the only participant in the transaction is an
Infinispan cluster. On the other hand, JTA transactions (involving TransactionManager) should be used
whenever the transactions involves multiple systems. E.g. considering the "Hello world!" of transactions:
transferring money from one bank account to the other. If both accounts are stored within Infinispan, then
batching can be used. If one account is in a database and the other is Infinispan, then distributed
transactions are required.

JBoss Community Documentation

Page 307 of 617

Infinispan 6.0

3.59.2 Configuring batching


To use batching, you need to enable invocation batching in your cache configuration, either on the
Configuration object:

Configuration.setInvocationBatchingEnabled(true);

or in your XML file:

<invocationBatching enabled="true" />

By default, invocation batching is disabled.


Note that you do not have to have a transaction manager defined to use batching.

3.59.3 Batching API


Once you have configured your cache to use batching, you use it by calling startBatch() and endBatch() on
Cache. E.g.,

Cache cache = cacheManager.getCache();


// not using a batch
cache.put("key", "value"); // will replicate immediately
// using a batch
cache.startBatch();
cache.put("k1", "value");
cache.put("k2", "value");
cache.put("k2", "value");
cache.endBatch(true); // This will now replicate the modifications since the batch was started.
cache.startBatch();
cache.put("k1", "value");
cache.put("k2", "value");
cache.put("k3", "value");
cache.endBatch(false); // This will "discard" changes made in the batch

JBoss Community Documentation

Page 308 of 617

Infinispan 6.0

3.59.4 Advanced: batching and JTA


Behinds the scene, the batching functionality starts a JTA transactions, and all the invocations in that scope
are associated with it. For this it uses a very simple (e.g. no recovery) TransactionManager implementation
behind the scene. From this you get all sorts of nice behaviour, including:
1. Locks you acquire during an invocation are held until the transaction commits or rolls back.
2. Changes are all replicated around the cluster in a batch as part of the transaction commit process.
Reduces replication chatter if multiple changes occur during the transaction.
3. If synchronous replication or invalidation are used, a failure in replication/invalidation will cause the
transaction to roll back.
4. If a CacheLoader is used, and that cache loader works with a JTA resource (e.g. a JTA DataSource), the
JTA resource can also participate in the transaction.
5. All the transaction related configurations apply for batching as well:

<transaction
syncRollbackPhase="false" syncCommitPhase="false"
useEagerLocking="true" eagerLockSingleNode="true" />

JBoss Community Documentation

Page 309 of 617

Infinispan 6.0

3.60 Hot Rod Hash Functions


Infinispan makes use of a consistent hash function to place nodes on a hash wheel, and to place keys of
entries on the same wheel to determine where entries live.
In Infinispan 4.2 and earlier, the hash space was hardcoded to 10240, but since 5.0, the hash space is
Integer.MAX_INT. Please note that since Hot Rod clients should not assume a particular hash space by
default, everytime a hash-topology change is detected, this value is sent back to the client via the Hot Rod
protocol.
When interacting with Infinispan via the Hot Rod protocol, it is mandated that keys (and values) are byte
arrays, to ensure platform neutral behavior. As such, smart-clients which are aware of hash distribution on
the backend would need to be able to calculate the hash codes of such byte array keys, again in a
platform-neutral manner. To this end, the hash functions used by Infinispan are versioned and documented,
so that it can be re-implemented by non-Java clients if needed.
The version of the hash function in use is provided in the Hot Rod protocol, as the hash function version
parameter.
1. Version 1 (single byte, 0x01)
The initial version of the hash function in use is Austin Appleby's MurmurHash 2.0 algorithm, a fast,
non-cryptographic hash that exhibits excellent distribution, collision resistance and avalanche
behavior. The specific version of the algorithm used is the slightly slower, endian-neutral version that
allows consistent behavior across both big- and little-endian CPU architectures. Infinispan's version
also hard-codes the hash seed as -1. For details of the algorithm, please visit Austin Appleby's
MurmurHash 2.0 page. Other implementations are detailed on Wikipedia. This hash function was the
default one used by the Hot Rod server until Infinispan 4.2.1.
1. Version 2 (single byte, 0x02)
Since Infinispan 5.0, a new hash function is used by default which is Austin Appleby's MurmurHash
3.0 algorithm. Detailed information about the hash function can be found in this wiki. Compared to 2.0,
it provides better performance and spread.

3.61 Hot Rod Protocol


1. Hot Rod protocol version 1.0
2. Hot Rod protocol version 1.1
3. Hot Rod protocol version 1.2

JBoss Community Documentation

Page 310 of 617

Infinispan 6.0

3.61.1 Hot Rod Protocol - Version 1.0


Introduction
Request Header
Response Header
Topology Change Headers
Topology-Aware Client Topology Change Header
Hash-Distribution-Aware Client Topology Change Header
Operations
Get/Remove/ContainsKey/GetWithVersion
BulkGet
Put/PutIfAbsent/Replace
ReplaceIfUnmodified
RemoveIfUnmodified
Clear
Stats
Ping
Error Handling
Multi-Get Operations
Example - Put request

Introduction
This article provides detailed information about the first version of the custom TCP client/server Hot Rod
protocol.

Infinispan versions
This version of the protocol is implemented since Infinispan 4.1.0.Final

All key and values are sent and stored as byte arrays. Hot Rod makes no assumptions about their
types. Some clarifications about the other types:
vInt: Refers to unsigned variable length integer values as specified in here. They're
between 1 and 5 bytes long.
vLong: Refers to unsigned variable length long values similar to vInt but applied to longer
values. They're between 1 and 9 bytes long.
String: Strings are always represented using UTF-8 encoding.

JBoss Community Documentation

Page 311 of 617

Infinispan 6.0

Request Header
The header for a request is composed of:
Magic Message Version Opcode Cache

Cache

Flags Client

[1b]

Name [

Id [

[1b]

[1b]

vLong]

Name

Length string vInt


[vInt]

Topology Transaction

Intelligence Id [vInt]

Type [1b]

[1b]

Magic : Possible values are:


0xA0 - Infinispan Cache Request Marker
0xA1 - Infinispan Cache Response Marker
Message Id : Id of the message that will be copied back in the response. This allows for hot rod
clients to implement the protocol in an asynchronous way.
Version : Infinispan hot rod server version. In this particular case, this is 10
Opcode : Possible values are only the ones on the request column:
Request operation codes

Response operation codes

0x01 - put request

0x02 - put response

0x03 - get request

0x04 - get response

0x05 - putIfAbsent request

0x06 - putIfAbsent response

0x07 - replace request

0x08 - replace response

0x09 - replaceIfUnmodified request 0x0A - replaceIfUnmodified response


0x0B - remove request

0x0C - remove response

0x0D - removeIfUnmodified request 0x0E - removeIfUnmodified response


0x0F - containsKey request

0x10 - containsKey response

0x11 - getWithVersion request

0x12 - getWithVersion response

0x13 - clear request

0x14 - clear response

0x15 - stats request

0x16 - stats response

0x17 - ping request

0x18 - ping response

0x19 - bulkGet request

0x1A - bulkGet response

0x50 - error response

Cache Name Length : Length of cache name. If the passed length is 0 (followed by no cache name),
the operation will interact with the default cache.
Cache Name : Name of cache on which to operate. This name must match the name of predefined
cache in the Infinispan configuration file.

JBoss Community Documentation

Page 312 of 617

Infinispan 6.0
Flags : A variable length number representing flags passed to the system. Each flags is represented
by a bit. Note that since this field is sent as variable length, the most significant bit in a byte is used to
determine whether more bytes need to be read, hence this bit does not represent any flag. Using this
model allows for flags to be combined in a short space. Here are the current values for each flag:
0x0001 ForceReturnPreviousValue
Client Intelligence : This byte hints the server on the client capabilities:
0x01 - basic client, interested in neither cluster nor hash information
0x02 - topology-aware client, interested in cluster information
0x03 - hash-distribution-aware client, that is interested in both cluster and hash information
Topology Id : This field represents the last known view in the client. Basic clients will only send 0 in
this field. When topology-aware or hash-distribution-aware clients will send 0 until they have received
a reply from the server with the current view id. Afterwards, they should send that view id until they
receive a new view id in a response
Transaction Type : This is a 1 byte field, containing one of the following well-known supported
transaction types (For this version of the protocol, the only supported transaction type is 0):
0 - Non-transactional call, or client does not support transactions. The subsequent TX_ID field
will be omitted.
1 - X/Open XA transaction ID (XID). This is a well-known, fixed-size format.
Transaction Id : The byte array uniquely identifying the transaction associated to this call. It's length
is determined by the transaction type. If transaction type is 0, no transaction id will be present.

Response Header
Magic [1b] Message Id [vLong] Op code [1b] Status [1b] Topology Change Marker [1b]
Opcode : Op code representing a response to a particular operation, or error condition.
Status : Status of the response, possible values:
0x00 - No error

0x01 - Not

0x02 - Key does not exist

put/removed/replaced
0x81 - Invalid magic or message

0x82 - Unknown command

0x83 - Unknown version

0x85 - Server Error

0x86 - Command timed

id
0x84 - Request parsing error

out
Exceptional error status responses, those that start with 0x8..., are followed by the length of the error
message (as a vInt) and error message itself as String.
Topology Change Marker : This is a marker byte that indicates whether the response is prepended
with topology change information. When no topology change follows, the content of this byte is 0. If a
topology change follows, its contents are 1.

JBoss Community Documentation

Page 313 of 617

Infinispan 6.0

Topology Change Headers


The following section discusses how the response headers look for topology-aware or
hash-distribution-aware clients when there's been a cluster or view formation change. Note that it's the
server that makes the decision on whether it sends back the new topology based on the current topology id
and the one the client sent. If they're different, it will send back the new topology.

Topology-Aware Client Topology Change Header


This is what topology-aware clients receive as response header when a topology change is sent back:
Response header with topology change

Topology Id [vInt]

marker
m1: Host/IP length [vInt]

m2: Host/IP length [vInt]

Num servers in topology [


vInt]

m1: Host/IP address [

m1: Port [2b - Unsigned

string]

Short]

m2: Host/IP address [

m2: Port [2b - Unsigned

string]

Short]

...etc
Num servers in topology : Number of Infinispan Hot Rod servers running within the cluster. This
could be a subset of the entire cluster if only a fraction of those nodes are running Hot Rod servers.
Host/IP address length : Length of hostname or IP address of individual cluster member that Hot
Rod client can use to access it. Using variable length here allows for covering for hostnames, IPv4
and IPv6 addresses.
Host/IP address : String containing hostname or IP address of individual cluster member that Hot
Rod client can use to access it.
Port : Port that Hot Rod clients can use to communicat with this cluster member.

JBoss Community Documentation

Page 314 of 617

Infinispan 6.0

Hash-Distribution-Aware Client Topology Change Header


This is what hash-distribution-aware clients receive as response header when a topology change is sent
back:
Response header

Topology Id

Num Key Owners [

Hash

Hash

Num servers

with topology change [vInt]

2b - Unsigned

Function

space

in topology

marker

Short]

Version [1b] size [

[vInt]

vInt]
m1: Host/IP length [

m1: Host/IP

m1: Port [2b -

m1:

vInt]

address [

unsigned short]

Hashcode [

string]

4b]

m2: Host/IP length [

m2: Host/IP

m2: Port [2b -

m2:

vInt]

address [

unsigned short]

Hashcode [

string]

4b]

...etc
It's important to note that since hash headers rely on the consistent hash algorithm used by the server and
this is a factor of the cache interacted with, hash-distribution-aware headers can only be returned to
operations that target a particular cache. Currently ping command does not target any cache (this is to
change as per ISPN-424, hence calls to ping command with hash-topology-aware client settings will return a
hash-distribution-aware header with "Num Key Owners", "Hash Function Version", "Hash space size" and
each individual host's hash code all set to 0. This type of header will also be returned as response to
operations with hash-topology-aware client settings that are targeting caches that are not configured with
distribution.
Number key owners : Globally configured number of copies for each Infinispan distributed key
Hash function version : Hash function version, pointing to a specific hash function in use. See Hot
Rod hash functions for details.
Hash space size : Modulus used by Infinispan for for all module arithmetic related to hash code
generation. Clients will likely require this information in order to apply the correct hash calculation to
the keys.
Num servers in topology : If virtual nodes are disabled, this number represents the number of Hot
Rod servers in the cluster. If virtual nodes are enabled, this number represents all the virtual nodes in
the cluster which are calculated as (num configured virtual nodes) * (num cluster members).
Regardless of whether virtual nodes are configured or not, the number represented by this field
indicates the number of 'host:port:hashId' tuples to be read in the response.
Hashcode : 32 bit integer representing the hashcode of a cluster member that a Hot Rod client can
use indentify in which cluster member a key is located having applied the CSA to it.

JBoss Community Documentation

Page 315 of 617

Infinispan 6.0

Operations
Get/Remove/ContainsKey/GetWithVersion
Common request format:
Header Key Length [vInt] Key [byte-array]
Key Length : Length of key. Note that the size of a vint can be up to 5 bytes which in theory
can produce bigger numbers than Integer.MAX_VALUE. However, Java cannot create a
single array that's bigger than Integer.MAX_VALUE, hence the protocol is limiting vint array
lengths to Integer.MAX_VALUE.
Key : Byte array containing the key whose value is being requested.
Response status:
0x00 - success, if key present/retrieved/removed
0x02 - if key does not exist
Get response:
Header Value Length [vInt] Value [byte-array]
Value Length : Length of value
Value : The requested value. If key does not exist, status returned in 0x02. See encoding
section for more info.
Remove response:
If ForceReturnPreviousValue has been passed, remove response will contain previous value
(including value length) for that key. If the key does not exist or previous was null, value length would
be 0. Otherwise, if no ForceReturnPreviousValue was sent, the response would be empty.
ContainsKey response:
Empty
GetWithVersion response:
Header Entry Version [8b] Value Length [vInt] Value [byte-array]
Entry Version : Unique value of an existing entry's modification. The protocol does not
mandate that entry_version values are sequential. They just need to be unique per update at
the key level.

JBoss Community Documentation

Page 316 of 617

Infinispan 6.0

BulkGet
Request format:
Header Entry Count [vInt]
Entry Count : Maximum number of Infinispan entries to be returned by the server (entry ==
key + associated value). Needed to support CacheLoader.load(int). If 0 then all entries are
returned (needed for CacheLoader.loadAll()).
Response:
Header More
[1b]

Key

Key Value

Value More

Key

Key Value

Value More [

Size 1

Size 2

Size 1

[1b]

Size 2

1b] ...

More : One byte representing whether more entries need to be read from the stream. So, when
it's set to 1, it means that an entry followes, whereas when it's set to 0, it's the end of stream
and no more entries are left to read.
For more information on BulkGet look here

Put/PutIfAbsent/Replace
Common request format:
Header Key Length [ Key [
vInt]

Lifespan [

byte-array vInt]

Max Idle [

Value Length

Value [

vInt]

[vInt]

byte-array]

]
Lifespan : Number of seconds that a entry during which the entry is allowed to life. If number
of seconds is bigger than 30 days, this number of seconds is treated as UNIX time and so,
represents the number of seconds since 1/1/1970. If set to 0, lifespan is unlimited.
Max Idle : Number of seconds that a entry can be idle before it's evicted from the cache. If 0,
no max idle time.
Put response status:
0x00 if stored
Replace response status:
0x00 if stored
0x01 if store did not happen because key does not exist
PutIfAbsent response status:
0x00 if stored
0x01 if store did not happen because key was present
Put/PutIfAbsent/Replace response:
If ForceReturnPreviousValue has been passed, these responses will contain previous value
(and corresponding value length) for that key. If the key does not exist or previous was null, value
length would be 0. Otherwise, if no ForceReturnPreviousValue was sent, the response would be
empty.

JBoss Community Documentation

Page 317 of 617

Infinispan 6.0

ReplaceIfUnmodified
Request format:
Header Key

Key [

Lifespan Max

Entry

Value

Value [

Length [

byte-array [vInt]

Idle [

Version [

Length [

byte-array

vInt]

vInt]

8b]

vInt]

Entry Version : Use the value returned by GetWithVersion operation.


Response status
0x00 status if replaced/removed
0x01 status if replace/remove did not happen because key had been modified
0x02 status if key does not exist
Response:
If ForceReturnPreviousValue has been passed, this responses will contain previous value (and
corresponding value length) for that key. If the key does not exist or previous was null, value length
would be 0. Otherwise, if no ForceReturnPreviousValue was sent, the response would be empty.

RemoveIfUnmodified
Request format:
Header Key Length [vInt] Key [byte-array] Entry Version [8b]
Response status
0x00 status if replaced/removed
0x01 status if replace/remove did not happen because key had been modified
0x02 status if key does not exist
Response:
If ForceReturnPreviousValue has been passed, this responses will contain previous value (and
corresponding value length) for that key. If the key does not exist or previous was null, value length
would be 0. Otherwise, if no ForceReturnPreviousValue was sent, the response would be empty.

Clear
Request format:
Header
Response status:
0x00 status if infinispan was cleared

JBoss Community Documentation

Page 318 of 617

Infinispan 6.0

Stats
Returns a summary of all available statistics. For each statistic returned, a name and a value is returned
both in String UTF-8 format. The supported stats are the following:
Name

Explanation

timeSinceStart

Number of seconds since Hot Rod started.

currentNumberOfEntries Number of entries currently in the Hot Rod server.


totalNumberOfEntries

Number of entries stored in Hot Rod server.

stores

Number of put operations.

retrievals

Number of get operations.

hits

Number of get hits.

misses

Number of get misses.

removeHits

Number of removal hits.

removeMisses

Number of removal misses.

Response
Header Number

Name1

Name1

of stats [ length [ [
vInt]

vInt]

Value1

Value1

length [ [

string vInt]

String

Name2 Name2 Value2 Value2 ...


length

length

Number of stats : Number of individual stats returned


Name length : Length of named statistic
Name : String containing statistic name
Value length : Length of value field
Value : String containing statistic value.

Ping
Application level request to see if the server is available.
Response status:
0x00 - if no errors

JBoss Community Documentation

Page 319 of 617

Infinispan 6.0

Error Handling
Response header Error Message Length vInt Error Message string
Response header contains error op code response and corresponding error status number as well as the
following two:
Error Message Length : Length of error message
Error message : Error message. In the case of 0x84, this error field contains the latest version
supported by the hot rod server. Length is defined by total body length.

Multi-Get Operations
A multi-get operation is a form of get operation that instead of requesting a single key, requests a set of
keys. The Hot Rod protocol does not include such operation but remote Hot Rod clients could easily
implement this type of operations by either parallelizing/pipelining individual get requests. Another possibility
would be for remote clients to use async or non-blocking get requests. For example, if a client wants N keys,
it could send send N async get requests and then wait for all the replies. Finally, multi-get is not to be
confused with bulk-get operations. In bulk-gets, either all or a number of keys are retrieved, but the client
does not know which keys to retrieve, whereas in multi-get, the client defines which keys to retrieve.

JBoss Community Documentation

Page 320 of 617

Infinispan 6.0

Example - Put request


Coded request
Byte 0

0x09

0x41

0x01

0x07

0x4D

0x79

0x43

('M')

('y')

('C')

0x00

0x03

0x00

0x00

0x00

16

24

32

0xA0

0x61

0x63

0x68

0x65

('a')

('c')

('h')

('e')

0x00

0x05

0x48

0x65

0x6C

0x6C

0x6F

('H')

('e')

('l')

('l')

('o')

0x57

0x6F

0x72

0x6C

0x64

('W')

('o')

('r')

('l')

('d')

0x00

0x05

Field explanation
Field Name

Value

Field Name

Value

Magic (0)

0xA0

Message Id (1)

0x09

Version (2)

0x41

Opcode (3)

0x01

Cache name length (4) 0x07

Cache name(5-11)

'MyCache'

Flag (12)

0x00

Client Intelligence (13) 0x03

Topology Id (14)

0x00

Transaction Type (15)

0x00

Transaction Id (16)

0x00

Key field length (17)

0x05

Key (18 - 22)

'Hello' Lifespan (23)

Max idle (24)

0x00

Value (26-30)

'World'

JBoss Community Documentation

Value field length (25)

0x00
0x05

Page 321 of 617

Infinispan 6.0

Coded response
Byte 0
8

5 6 7

0xA1 0x09 0x01 0x00 0x00

Field Explanation
Field Name

Value Field Name

Value

Magic (0)

0xA1

Message Id (1) 0x09

Opcode (2)

0x01

Status (3)

0x00

Topology change marker (4) 0x00

3.61.2 Hot Rod Protocol - Version 1.1


Introduction
Request Header
Response Header
Topology Change Headers
Topology-Aware Client Topology Change Header
Hash-Distribution-Aware Client Topology Change Header
Server node hash code calculation
Operations
Get/Remove/ContainsKey/GetWithVersion
BulkGet
Put/PutIfAbsent/Replace
ReplaceIfUnmodified
RemoveIfUnmodified
Clear
Stats
Ping
Error Handling
Multi-Get Operations
Example - Put request

JBoss Community Documentation

Page 322 of 617

Infinispan 6.0

Introduction
This article provides detailed information about the first version of the custom TCP client/server Hot Rod
protocol.

Infinispan versions
This version of the protocol is implemented since Infinispan 5.1.0.FINAL

All key and values are sent and stored as byte arrays. Hot Rod makes no assumptions about their
types. Some clarifications about the other types:
vInt: Refers to unsigned variable length integer values as specified in here. They're
between 1 and 5 bytes long.
vLong: Refers to unsigned variable length long values similar to vInt but applied to longer
values. They're between 1 and 9 bytes long.
String: Strings are always represented using UTF-8 encoding.

Request Header
The header for a request is composed of:
Magic Message Version Opcode Cache

Cache

Flags Client

[1b]

Name [

Id [

[1b]

[1b]

vLong]

Name

Length string vInt


[vInt]

Topology Transaction

Intelligence Id [vInt]

Type [1b]

[1b]

Magic : Possible values are:


0xA0 - Infinispan Cache Request Marker
0xA1 - Infinispan Cache Response Marker
Message Id : Id of the message that will be copied back in the response. This allows for hot rod
clients to implement the protocol in an asynchronous way.
Version : Infinispan hot rod server version.

Updated for 1.1


The value of this field in version 1.1 is 11

JBoss Community Documentation

Page 323 of 617

Infinispan 6.0
Opcode : Possible values are only the ones on the request column:
Request operation codes

Response operation codes

0x01 - put request

0x02 - put response

0x03 - get request

0x04 - get response

0x05 - putIfAbsent request

0x06 - putIfAbsent response

0x07 - replace request

0x08 - replace response

0x09 - replaceIfUnmodified request 0x0A - replaceIfUnmodified response


0x0B - remove request

0x0C - remove response

0x0D - removeIfUnmodified request 0x0E - removeIfUnmodified response


0x0F - containsKey request

0x10 - containsKey response

0x11 - getWithVersion request

0x12 - getWithVersion response

0x13 - clear request

0x14 - clear response

0x15 - stats request

0x16 - stats response

0x17 - ping request

0x18 - ping response

0x19 - bulkGet request

0x1A - bulkGet response

0x50 - error response

Cache Name Length : Length of cache name. If the passed length is 0 (followed by no cache name),
the operation will interact with the default cache.
Cache Name : Name of cache on which to operate. This name must match the name of predefined
cache in the Infinispan configuration file.
Flags : A variable length number representing flags passed to the system. Each flags is represented
by a bit. Note that since this field is sent as variable length, the most significant bit in a byte is used to
determine whether more bytes need to be read, hence this bit does not represent any flag. Using this
model allows for flags to be combined in a short space. Here are the current values for each flag:
0x0001 ForceReturnPreviousValue
Client Intelligence : This byte hints the server on the client capabilities:
0x01 - basic client, interested in neither cluster nor hash information
0x02 - topology-aware client, interested in cluster information
0x03 - hash-distribution-aware client, that is interested in both cluster and hash information
Topology Id : This field represents the last known view in the client. Basic clients will only send 0 in
this field. When topology-aware or hash-distribution-aware clients will send 0 until they have received
a reply from the server with the current view id. Afterwards, they should send that view id until they
receive a new view id in a response

JBoss Community Documentation

Page 324 of 617

Infinispan 6.0
Transaction Type : This is a 1 byte field, containing one of the following well-known supported
transaction types (For this version of the protocol, the only supported transaction type is 0):
0 - Non-transactional call, or client does not support transactions. The subsequent TX_ID field
will be omitted.
1 - X/Open XA transaction ID (XID). This is a well-known, fixed-size format.
Transaction Id : The byte array uniquely identifying the transaction associated to this call. It's length
is determined by the transaction type. If transaction type is 0, no transaction id will be present.

Response Header
Magic [1b] Message Id [vLong] Op code [1b] Status [1b] Topology Change Marker [1b]
Opcode : Op code representing a response to a particular operation, or error condition.
Status : Status of the response, possible values:
0x00 - No error

0x01 - Not

0x02 - Key does not exist

put/removed/replaced
0x81 - Invalid magic or message

0x82 - Unknown command

0x83 - Unknown version

0x85 - Server Error

0x86 - Command timed

id
0x84 - Request parsing error

out
Exceptional error status responses, those that start with 0x8..., are followed by the length of the error
message (as a vInt) and error message itself as String.
Topology Change Marker : This is a marker byte that indicates whether the response is prepended
with topology change information. When no topology change follows, the content of this byte is 0. If a
topology change follows, its contents are 1.

Topology Change Headers


The following section discusses how the response headers look for topology-aware or
hash-distribution-aware clients when there's been a cluster or view formation change. Note that it's the
server that makes the decision on whether it sends back the new topology based on the current topology id
and the one the client sent. If they're different, it will send back the new topology.

JBoss Community Documentation

Page 325 of 617

Infinispan 6.0

Topology-Aware Client Topology Change Header


This is what topology-aware clients receive as response header when a topology change is sent back:
Response header with topology change

Topology Id [vInt]

marker
m1: Host/IP length [vInt]

m2: Host/IP length [vInt]

Num servers in topology [


vInt]

m1: Host/IP address [

m1: Port [2b - Unsigned

string]

Short]

m2: Host/IP address [

m2: Port [2b - Unsigned

string]

Short]

...etc
Num servers in topology : Number of Infinispan Hot Rod servers running within the cluster. This
could be a subset of the entire cluster if only a fraction of those nodes are running Hot Rod servers.
Host/IP address length : Length of hostname or IP address of individual cluster member that Hot
Rod client can use to access it. Using variable length here allows for covering for hostnames, IPv4
and IPv6 addresses.
Host/IP address : String containing hostname or IP address of individual cluster member that Hot
Rod client can use to access it.
Port : Port that Hot Rod clients can use to communicat with this cluster member.

Hash-Distribution-Aware Client Topology Change Header

Updated for 1.1


This section has been modified to be more efficient when talking to distributed caches with virtual
nodes enabled.

This is what hash-distribution-aware clients receive as response header when a topology change is sent
back:

JBoss Community Documentation

Page 326 of 617

Infinispan 6.0

Response header

Topology

Num Key

Hash

Hash

Num

Num Virtual

with topology

Id [vInt]

Owners [2b -

Function

space

servers in

Nodes

Unsigned

Version [

size [

topology

Owners [

Short]

1b]

vInt]

[vInt]

vInt]

change marker

m1: Host/IP length

m1:

m1: Port [2b -

m1:

[vInt]

Host/IP

unsigned

Hashcode

address [

short]

[4b]

string]
m2: Host/IP length

m2:

m2: Port [2b -

m1:

[vInt]

Host/IP

unsigned

Hashcode

address [

short]

[4b]

string]
...etc
Number key owners : Globally configured number of copies for each Infinispan distributed key. If the
cache is not configured with distribution, this field will return 0.
Hash function version : Hash function version, pointing to a specific hash function in use. See Hot
Rod hash functions for details. If cache is not configured with distribution, this field will contain 0.
Hash space size : Modulus used by Infinispan for for all module arithmetic related to hash code
generation. Clients will likely require this information in order to apply the correct hash calculation to
the keys. If cache is not configured with distribution, this field will contain 0.
Num servers in topology : Represents the number of servers in the Hot Rod cluster which
represents the number of host:port pairings to be read in the header.
Number virtual nodes : Field added in version 1.1 of the protocol that represents the number of
configured virtual nodes. If no virtual nodes are configured or the cache is not configured with
distribution, this field will contain 0.

JBoss Community Documentation

Page 327 of 617

Infinispan 6.0
Server node hash code calculation
Adding support for virtual nodes has made version 1.0 of the Hot Rod protocol impractical due to bandwidth
it would have taken to return hash codes for all virtual nodes in the clusters (this number could easily be in
the millions). So, as of version 1.1 of the Hot Rod protocol, clients are given the base hash id or hash code
of each server, and then they have to calculate the real hash position of each server both with and without
virtual nodes configured. Here are the rules clients should follow when trying to calculate a node's hash
code:
1. With virtual nodes disabled:
Once clients have received the base hash code of the server, they need to normalize it in order to find
the exact position of the hash wheel. The process of normalization involves passing the base hash
code to the hash function, and then do a small calculation to avoid negative values. The resulting
number is the node's position in the hash wheel:

public static int getNormalizedHash(int nodeBaseHashCode, Hash hashFct) {


return hashFct.hash(nodeBaseHashCode) & Integer.MAX_VALUE; // make sure no negative
numbers are involved.
}

2. With virtual nodes enabled:


In this case, each node represents N different virtual nodes, and to calculate each virtual node's hash
code, we need to take the the range of numbers between 0 and N-1 and apply the following logic:
For virtual node with 0 as id, use the technique used to retrieve a node's hash code, as shown
in the previous section.
For virtual nodes from 1 to N-1 ids, execute the following logic:

public static int virtualNodeHashCode(int nodeBaseHashCode, int id, Hash hashFct) {


int virtualNodeBaseHashCode = id;
virtualNodeBaseHashCode = 31 * virtualNodeBaseHashCode + nodeBaseHashCode;
return getNormalizedHash(virtualNodeBaseHashCode, hashFct);
}

JBoss Community Documentation

Page 328 of 617

Infinispan 6.0

Operations
Get/Remove/ContainsKey/GetWithVersion
Common request format:
Header Key Length [vInt] Key [byte-array]
Key Length : Length of key. Note that the size of a vint can be up to 5 bytes which in theory
can produce bigger numbers than Integer.MAX_VALUE. However, Java cannot create a
single array that's bigger than Integer.MAX_VALUE, hence the protocol is limiting vint array
lengths to Integer.MAX_VALUE.
Key : Byte array containing the key whose value is being requested.
Response status:
0x00 - success, if key present/retrieved/removed
0x02 - if key does not exist
Get response:
Header Value Length [vInt] Value [byte-array]
Value Length : Length of value
Value : The requested value. If key does not exist, status returned in 0x02. See encoding
section for more info.
Remove response:
If ForceReturnPreviousValue has been passed, remove response will contain previous value
(including value length) for that key. If the key does not exist or previous was null, value length would
be 0. Otherwise, if no ForceReturnPreviousValue was sent, the response would be empty.
ContainsKey response:
Empty
GetWithVersion response:
Header Entry Version [8b] Value Length [vInt] Value [byte-array]
Entry Version : Unique value of an existing entry's modification. The protocol does not
mandate that entry_version values are sequential. They just need to be unique per update at
the key level.

JBoss Community Documentation

Page 329 of 617

Infinispan 6.0

BulkGet
Request format:
Header Entry Count [vInt]
Entry Count : Maximum number of Infinispan entries to be returned by the server (entry ==
key + associated value). Needed to support CacheLoader.load(int). If 0 then all entries are
returned (needed for CacheLoader.loadAll()).
Response:
Header More
[1b]

Key

Key Value

Value More

Key

Key Value

Value More [

Size 1

Size 2

Size 1

[1b]

Size 2

1b] ...

More : One byte representing whether more entries need to be read from the stream. So, when
it's set to 1, it means that an entry followes, whereas when it's set to 0, it's the end of stream
and no more entries are left to read.
For more information on BulkGet look here

Put/PutIfAbsent/Replace
Common request format:
Header Key Length [ Key [
vInt]

Lifespan [

byte-array vInt]

Max Idle [

Value Length

Value [

vInt]

[vInt]

byte-array]

]
Lifespan : Number of seconds that a entry during which the entry is allowed to life. If number
of seconds is bigger than 30 days, this number of seconds is treated as UNIX time and so,
represents the number of seconds since 1/1/1970. If set to 0, lifespan is unlimited.
Max Idle : Number of seconds that a entry can be idle before it's evicted from the cache. If 0,
no max idle time.
Put response status:
0x00 if stored
Replace response status:
0x00 if stored
0x01 if store did not happen because key does not exist
PutIfAbsent response status:
0x00 if stored
0x01 if store did not happen because key was present
Put/PutIfAbsent/Replace response:
If ForceReturnPreviousValue has been passed, these responses will contain previous value
(and corresponding value length) for that key. If the key does not exist or previous was null, value
length would be 0. Otherwise, if no ForceReturnPreviousValue was sent, the response would be
empty.

JBoss Community Documentation

Page 330 of 617

Infinispan 6.0

ReplaceIfUnmodified
Request format:
Header Key

Key [

Lifespan Max

Entry

Value

Value [

Length [

byte-array [vInt]

Idle [

Version [

Length [

byte-array

vInt]

vInt]

8b]

vInt]

Entry Version : Use the value returned by GetWithVersion operation.


Response status
0x00 status if replaced/removed
0x01 status if replace/remove did not happen because key had been modified
0x02 status if key does not exist
Response:
If ForceReturnPreviousValue has been passed, this responses will contain previous value (and
corresponding value length) for that key. If the key does not exist or previous was null, value length
would be 0. Otherwise, if no ForceReturnPreviousValue was sent, the response would be empty.

RemoveIfUnmodified
Request format:
Header Key Length [vInt] Key [byte-array] Entry Version [8b]
Response status
0x00 status if replaced/removed
0x01 status if replace/remove did not happen because key had been modified
0x02 status if key does not exist
Response:
If ForceReturnPreviousValue has been passed, this responses will contain previous value (and
corresponding value length) for that key. If the key does not exist or previous was null, value length
would be 0. Otherwise, if no ForceReturnPreviousValue was sent, the response would be empty.

Clear
Request format:
Header
Response status:
0x00 status if infinispan was cleared

JBoss Community Documentation

Page 331 of 617

Infinispan 6.0

Stats
Returns a summary of all available statistics. For each statistic returned, a name and a value is returned
both in String UTF-8 format. The supported stats are the following:
Name

Explanation

timeSinceStart

Number of seconds since Hot Rod started.

currentNumberOfEntries Number of entries currently in the Hot Rod server.


totalNumberOfEntries

Number of entries stored in Hot Rod server.

stores

Number of put operations.

retrievals

Number of get operations.

hits

Number of get hits.

misses

Number of get misses.

removeHits

Number of removal hits.

removeMisses

Number of removal misses.

Response
Header Number

Name1

Name1

of stats [ length [ [
vInt]

vInt]

Value1

Value1

length [ [

string vInt]

String

Name2 Name2 Value2 Value2 ...


length

length

Number of stats : Number of individual stats returned


Name length : Length of named statistic
Name : String containing statistic name
Value length : Length of value field
Value : String containing statistic value.

Ping
Application level request to see if the server is available.
Response status:
0x00 - if no errors

JBoss Community Documentation

Page 332 of 617

Infinispan 6.0

Error Handling
Response header Error Message Length vInt Error Message string
Response header contains error op code response and corresponding error status number as well as the
following two:
Error Message Length : Length of error message
Error message : Error message. In the case of 0x84, this error field contains the latest version
supported by the hot rod server. Length is defined by total body length.

Multi-Get Operations
A multi-get operation is a form of get operation that instead of requesting a single key, requests a set of
keys. The Hot Rod protocol does not include such operation but remote Hot Rod clients could easily
implement this type of operations by either parallelizing/pipelining individual get requests. Another possibility
would be for remote clients to use async or non-blocking get requests. For example, if a client wants N keys,
it could send send N async get requests and then wait for all the replies. Finally, multi-get is not to be
confused with bulk-get operations. In bulk-gets, either all or a number of keys are retrieved, but the client
does not know which keys to retrieve, whereas in multi-get, the client defines which keys to retrieve.

JBoss Community Documentation

Page 333 of 617

Infinispan 6.0

Example - Put request


Coded request
Byte 0

0x09

0x41

0x01

0x07

0x4D

0x79

0x43

('M')

('y')

('C')

0x00

0x03

0x00

0x00

0x00

16

24

32

0xA0

0x61

0x63

0x68

0x65

('a')

('c')

('h')

('e')

0x00

0x05

0x48

0x65

0x6C

0x6C

0x6F

('H')

('e')

('l')

('l')

('o')

0x57

0x6F

0x72

0x6C

0x64

('W')

('o')

('r')

('l')

('d')

0x00

0x05

Field explanation
Field Name

Value

Field Name

Value

Magic (0)

0xA0

Message Id (1)

0x09

Version (2)

0x41

Opcode (3)

0x01

Cache name length (4) 0x07

Cache name(5-11)

'MyCache'

Flag (12)

0x00

Client Intelligence (13) 0x03

Topology Id (14)

0x00

Transaction Type (15)

0x00

Transaction Id (16)

0x00

Key field length (17)

0x05

Key (18 - 22)

'Hello' Lifespan (23)

Max idle (24)

0x00

Value (26-30)

'World'

JBoss Community Documentation

Value field length (25)

0x00
0x05

Page 334 of 617

Infinispan 6.0

Coded response
Byte 0
8

5 6 7

0xA1 0x09 0x01 0x00 0x00

Field Explanation
Field Name

Value Field Name

Value

Magic (0)

0xA1

Message Id (1) 0x09

Opcode (2)

0x01

Status (3)

0x00

Topology change marker (4) 0x00

3.61.3 Hot Rod Protocol - Version 1.2


Introduction
Request Header
Response Header
Topology Change Headers
Topology-Aware Client Topology Change Header
Hash-Distribution-Aware Client Topology Change Header
Server node hash code calculation
Operations
Get/Remove/ContainsKey/GetWithVersion/GetWithMetadata
BulkGet
BulkKeysGet
Put/PutIfAbsent/Replace
ReplaceIfUnmodified
RemoveIfUnmodified
Clear
Stats
Ping
Error Handling
Multi-Get Operations
Example - Put request

JBoss Community Documentation

Page 335 of 617

Infinispan 6.0

Introduction
This article provides detailed information about the first version of the custom TCP client/server Hot Rod
protocol.

Infinispan versions
This version of the protocol is implemented since Infinispan 5.2.0.Final. Since Infinispan 5.3.0,
HotRod supports encryption via SSL. However, since this only affects the transport, the version
number of the protocol has not been incremented.

All key and values are sent and stored as byte arrays. Hot Rod makes no assumptions about their
types. Some clarifications about the other types:
vInt: Refers to unsigned variable length integer values as specified in here. They're
between 1 and 5 bytes long.
vLong: Refers to unsigned variable length long values similar to vInt but applied to longer
values. They're between 1 and 9 bytes long.
String: Strings are always represented using UTF-8 encoding.

Request Header
The header for a request is composed of:
Magic Message Version Opcode Cache

Cache

Flags Client

[1b]

Name [

Id [

[1b]

[1b]

vLong]

Name

Length string vInt


[vInt]

Topology Transaction

Intelligence Id [vInt]

Type [1b]

[1b]

Magic : Possible values are:


0xA0 - Infinispan Cache Request Marker
0xA1 - Infinispan Cache Response Marker
Message Id : Id of the message that will be copied back in the response. This allows for hot rod
clients to implement the protocol in an asynchronous way.
Version : Infinispan hot rod server version.

Updated for 1.2


The value of this field in version 1.2 is 12

JBoss Community Documentation

Page 336 of 617

Infinispan 6.0
Opcode : Possible values are only the ones on the request column:
Request operation codes

Response operation codes

0x01 - put request

0x02 - put response

0x03 - get request

0x04 - get response

0x05 - putIfAbsent request

0x06 - putIfAbsent response

0x07 - replace request

0x08 - replace response

0x09 - replaceIfUnmodified request 0x0A - replaceIfUnmodified response


0x0B - remove request

0x0C - remove response

0x0D - removeIfUnmodified request 0x0E - removeIfUnmodified response


0x0F - containsKey request

0x10 - containsKey response

0x11 - getWithVersion request

0x12 - getWithVersion response

0x13 - clear request

0x14 - clear response

0x15 - stats request

0x16 - stats response

0x17 - ping request

0x18 - ping response

0x19 - bulkGet request

0x1A - bulkGet response

0x1B - getWithMetadata request

0x1C - getWithMetadata response

0x1D - bulkKeysGet request

0x1E - bulkKeysGet response

0x50 - error response

Cache Name Length : Length of cache name. If the passed length is 0 (followed by no cache name),
the operation will interact with the default cache.
Cache Name : Name of cache on which to operate. This name must match the name of predefined
cache in the Infinispan configuration file.
Flags : A variable length number representing flags passed to the system. Each flags is represented
by a bit. Note that since this field is sent as variable length, the most significant bit in a byte is used to
determine whether more bytes need to be read, hence this bit does not represent any flag. Using this
model allows for flags to be combined in a short space. Here are the current values for each flag:
0x0001 ForceReturnPreviousValue
0x0002 DefaultLifespan
0x0004 DefaultMaxIdle

JBoss Community Documentation

Page 337 of 617

Infinispan 6.0
Client Intelligence : This byte hints the server on the client capabilities:
0x01 - basic client, interested in neither cluster nor hash information
0x02 - topology-aware client, interested in cluster information
0x03 - hash-distribution-aware client, that is interested in both cluster and hash information
Topology Id : This field represents the last known view in the client. Basic clients will only send 0 in
this field. When topology-aware or hash-distribution-aware clients will send 0 until they have received
a reply from the server with the current view id. Afterwards, they should send that view id until they
receive a new view id in a response
Transaction Type : This is a 1 byte field, containing one of the following well-known supported
transaction types (For this version of the protocol, the only supported transaction type is 0):
0 - Non-transactional call, or client does not support transactions. The subsequent TX_ID field
will be omitted.
1 - X/Open XA transaction ID (XID). This is a well-known, fixed-size format.
Transaction Id : The byte array uniquely identifying the transaction associated to this call. It's length
is determined by the transaction type. If transaction type is 0, no transaction id will be present.

Response Header
Magic [1b] Message Id [vLong] Op code [1b] Status [1b] Topology Change Marker [1b]
Opcode : Op code representing a response to a particular operation, or error condition.
Status : Status of the response, possible values:
0x00 - No error

0x01 - Not

0x02 - Key does not exist

put/removed/replaced
0x81 - Invalid magic or message

0x82 - Unknown command

0x83 - Unknown version

0x85 - Server Error

0x86 - Command timed

id
0x84 - Request parsing error

out
Exceptional error status responses, those that start with 0x8..., are followed by the length of the error
message (as a vInt) and error message itself as String.
Topology Change Marker : This is a marker byte that indicates whether the response is prepended
with topology change information. When no topology change follows, the content of this byte is 0. If a
topology change follows, its contents are 1.

Topology Change Headers


The following section discusses how the response headers look for topology-aware or
hash-distribution-aware clients when there's been a cluster or view formation change. Note that it's the
server that makes the decision on whether it sends back the new topology based on the current topology id
and the one the client sent. If they're different, it will send back the new topology.

JBoss Community Documentation

Page 338 of 617

Infinispan 6.0

Topology-Aware Client Topology Change Header


This is what topology-aware clients receive as response header when a topology change is sent back:
Response header with topology change

Topology Id [vInt]

Num servers in topology [

marker

vInt]

m1: Host/IP length [vInt]

m2: Host/IP length [vInt]

m1: Host/IP address [

m1: Port [2b - Unsigned

string]

Short]

m2: Host/IP address [

m2: Port [2b - Unsigned

string]

Short]

...etc
Num servers in topology : Number of Infinispan Hot Rod servers running within the cluster. This
could be a subset of the entire cluster if only a fraction of those nodes are running Hot Rod servers.
Host/IP address length : Length of hostname or IP address of individual cluster member that Hot
Rod client can use to access it. Using variable length here allows for covering for hostnames, IPv4
and IPv6 addresses.
Host/IP address : String containing hostname or IP address of individual cluster member that Hot
Rod client can use to access it.
Port : Port that Hot Rod clients can use to communicat with this cluster member.

Hash-Distribution-Aware Client Topology Change Header


This is what hash-distribution-aware clients receive as response header when a topology change is sent
back:
Response header

Topology

Num Key

Hash

Hash

Num

Num Virtual

with topology

Id [vInt]

Owners [2b -

Function

space

servers in

Nodes

Unsigned

Version [

size [

topology

Owners [

Short]

1b]

vInt]

[vInt]

vInt]

change marker

m1: Host/IP length

m1:

m1: Port [2b -

m1:

[vInt]

Host/IP

unsigned

Hashcode

address [

short]

[4b]

string]
m2: Host/IP length

m2:

m2: Port [2b -

m1:

[vInt]

Host/IP

unsigned

Hashcode

address [

short]

[4b]

string]
...etc

JBoss Community Documentation

Page 339 of 617

Infinispan 6.0

Number key owners : Globally configured number of copies for each Infinispan distributed key. If the
cache is not configured with distribution, this field will return 0.
Hash function version : Hash function version, pointing to a specific hash function in use. See Hot
Rod hash functions for details. If cache is not configured with distribution, this field will contain 0.
Hash space size : Modulus used by Infinispan for for all module arithmetic related to hash code
generation. Clients will likely require this information in order to apply the correct hash calculation to
the keys. If cache is not configured with distribution, this field will contain 0.
Num servers in topology : Represents the number of servers in the Hot Rod cluster which
represents the number of host:port pairings to be read in the header.
Number virtual nodes : Field added in version 1.1 of the protocol that represents the number of
configured virtual nodes. If no virtual nodes are configured or the cache is not configured with
distribution, this field will contain 0.
Server node hash code calculation
Adding support for virtual nodes has made version 1.0 of the Hot Rod protocol impractical due to bandwidth
it would have taken to return hash codes for all virtual nodes in the clusters (this number could easily be in
the millions). So, as of version 1.1 of the Hot Rod protocol, clients are given the base hash id or hash code
of each server, and then they have to calculate the real hash position of each server both with and without
virtual nodes configured. Here are the rules clients should follow when trying to calculate a node's hash
code:
1. With virtual nodes disabled:
Once clients have received the base hash code of the server, they need to normalize it in order to find
the exact position of the hash wheel. The process of normalization involves passing the base hash
code to the hash function, and then do a small calculation to avoid negative values. The resulting
number is the node's position in the hash wheel:

public static int getNormalizedHash(int nodeBaseHashCode, Hash hashFct) {


return hashFct.hash(nodeBaseHashCode) & Integer.MAX_VALUE; // make sure no negative
numbers are involved.
}

2. With virtual nodes enabled:


In this case, each node represents N different virtual nodes, and to calculate each virtual node's hash
code, we need to take the the range of numbers between 0 and N-1 and apply the following logic:
For virtual node with 0 as id, use the technique used to retrieve a node's hash code, as shown
in the previous section.
For virtual nodes from 1 to N-1 ids, execute the following logic:

public static int virtualNodeHashCode(int nodeBaseHashCode, int id, Hash hashFct) {


int virtualNodeBaseHashCode = id;
virtualNodeBaseHashCode = 31 * virtualNodeBaseHashCode + nodeBaseHashCode;
return getNormalizedHash(virtualNodeBaseHashCode, hashFct);
}

JBoss Community Documentation

Page 340 of 617

Infinispan 6.0

Operations
Get/Remove/ContainsKey/GetWithVersion/GetWithMetadata
Common request format:
Header Key Length [vInt] Key [byte-array]
Key Length : Length of key. Note that the size of a vint can be up to 5 bytes which in theory
can produce bigger numbers than Integer.MAX_VALUE. However, Java cannot create a
single array that's bigger than Integer.MAX_VALUE, hence the protocol is limiting vint array
lengths to Integer.MAX_VALUE.
Key : Byte array containing the key whose value is being requested.
Response status:
0x00 - success, if key present/retrieved/removed
0x02 - if key does not exist
Get response:
Header Value Length [vInt] Value [byte-array]
Value Length : Length of value
Value : The requested value. If key does not exist, status returned in 0x02. See encoding
section for more info.
Remove response:
If ForceReturnPreviousValue has been passed, remove response will contain previous value
(including value length) for that key. If the key does not exist or previous was null, value length would
be 0. Otherwise, if no ForceReturnPreviousValue was sent, the response would be empty.
ContainsKey response:
Empty
GetWithVersion response:
Header Entry Version [8b] Value Length [vInt] Value [byte-array]
Entry Version : Unique value of an existing entry's modification. The protocol does not
mandate that entry_version values are sequential. They just need to be unique per update at
the key level.

JBoss Community Documentation

Page 341 of 617

Infinispan 6.0

GetWithMetadata response:
Header Flag

Created

(byte) [Long]

Lifespan

LastUsed

MaxIdle

Entry

[vInt]

[Long]

[vInt]

Version Length byte-array

(optional) (optional) (optional) (optional) [8b]

Value

Value [

[vInt]

Flag : a flag indicating whether the response contains expiration information. The value of the
flag is obtained as a bitwise OR operation between INFINITE_LIFESPAN (0x01) and
INFINITE_MAXIDLE (0x02)
Created : a Long representing the timestamp when the entry was created on the server. This
value is returned only if the flag's INFINITE_LIFESPAN bit is not set
Lifespan : a vInt representing the lifespan of the entry in seconds. This value is returned only if
the flag's INFINITE_LIFESPAN bit is not set
LastUsed : a Long representing the timestamp when the entry was last accessed on the
server. This value is returned only if the flag's INFINITE_MAXIDLE bit is not set
MaxIdle : a vInt representing the maxIdle of the entry in seconds. This value is returned only if
the flag's INFINITE_MAXIDLE bit is not set
Entry Version : Unique value of an existing entry's modification. The protocol does not
mandate that entry_version values are sequential. They just need to be unique per update at
the key level.

BulkGet
Request format:
Header Entry Count [vInt]
Entry Count : Maximum number of Infinispan entries to be returned by the server (entry ==
key + associated value). Needed to support CacheLoader.load(int). If 0 then all entries are
returned (needed for CacheLoader.loadAll()).
Response:
Header More
[1b]

Key

Key Value

Value More

Key

Key Value

Value More [

Size 1

Size 2

Size 1

[1b]

Size 2

1b] ...

More : One byte representing whether more entries need to be read from the stream. So, when
it's set to 1, it means that an entry followes, whereas when it's set to 0, it's the end of stream
and no more entries are left to read.
For more information on BulkGet look here

JBoss Community Documentation

Page 342 of 617

Infinispan 6.0

BulkKeysGet
Request format:
Header Scope [vInt]
Scope :
0 - Default Scope - This scope is used by RemoteCache.keySet() method. If the remote cache
is a distributed cache, the server launch a map/reduce operation to retrieve all keys from all of
the nodes. (Remember, a topology-aware Hot Rod Client could be load balancing the request
to any one node in the cluster). Otherwise, it'll get keys from the cache instance local to the
server receiving the request (that is because the keys should be the same across all nodes in a
replicated cache).
1 - Global Scope - This scope behaves the same to Default Scope.
2 - Local Scope - In case when remote cache is a distributed cache, the server will not launch
a map/reduce operation to retrieve keys from all nodes. Instead, it'll only get keys local from
the cache instance local to the server receiving the request.
Response:
Header More [1b] Key Size 1 Key 1 More [1b] Key Size 2 Key 2 More [1b] ...
More : One byte representing whether more keys need to be read from the stream. So, when
it's set to 1, it means that a key followes, whereas when it's set to 0, it's the end of stream and
no more entries are left to read.

JBoss Community Documentation

Page 343 of 617

Infinispan 6.0

Put/PutIfAbsent/Replace
Common request format:
Header Key Length [ Key [
vInt]

Lifespan [

byte-array vInt]

Max Idle [

Value Length

Value [

vInt]

[vInt]

byte-array]

]
Lifespan : Number of seconds that a entry during which the entry is allowed to life. If number
of seconds is bigger than 30 days, this number of seconds is treated as UNIX time and so,
represents the number of seconds since 1/1/1970. If set to 0, lifespan is unlimited.
Max Idle : Number of seconds that a entry can be idle before it's evicted from the cache. If 0,
no max idle time.
Put response status:
0x00 if stored
Replace response status:
0x00 if stored
0x01 if store did not happen because key does not exist
PutIfAbsent response status:
0x00 if stored
0x01 if store did not happen because key was present
Put/PutIfAbsent/Replace response:
If ForceReturnPreviousValue has been passed, these responses will contain previous value
(and corresponding value length) for that key. If the key does not exist or previous was null, value
length would be 0. Otherwise, if no ForceReturnPreviousValue was sent, the response would be
empty.

ReplaceIfUnmodified
Request format:
Header Key

Entry

Value

Value [

Length [

Key [

byte-array [vInt]

Lifespan Max
Idle [

Version [

Length [

byte-array

vInt]

vInt]

8b]

vInt]

Entry Version : Use the value returned by GetWithVersion operation.


Response status
0x00 status if replaced/removed
0x01 status if replace/remove did not happen because key had been modified
0x02 status if key does not exist
Response:
If ForceReturnPreviousValue has been passed, this responses will contain previous value (and
corresponding value length) for that key. If the key does not exist or previous was null, value length
would be 0. Otherwise, if no ForceReturnPreviousValue was sent, the response would be empty.

JBoss Community Documentation

Page 344 of 617

Infinispan 6.0

RemoveIfUnmodified
Request format:
Header Key Length [vInt] Key [byte-array] Entry Version [8b]
Response status
0x00 status if replaced/removed
0x01 status if replace/remove did not happen because key had been modified
0x02 status if key does not exist
Response:
If ForceReturnPreviousValue has been passed, this responses will contain previous value (and
corresponding value length) for that key. If the key does not exist or previous was null, value length
would be 0. Otherwise, if no ForceReturnPreviousValue was sent, the response would be empty.

Clear
Request format:
Header
Response status:
0x00 status if infinispan was cleared

JBoss Community Documentation

Page 345 of 617

Infinispan 6.0

Stats
Returns a summary of all available statistics. For each statistic returned, a name and a value is returned
both in String UTF-8 format. The supported stats are the following:
Name

Explanation

timeSinceStart

Number of seconds since Hot Rod started.

currentNumberOfEntries Number of entries currently in the Hot Rod server.


totalNumberOfEntries

Number of entries stored in Hot Rod server.

stores

Number of put operations.

retrievals

Number of get operations.

hits

Number of get hits.

misses

Number of get misses.

removeHits

Number of removal hits.

removeMisses

Number of removal misses.

Response
Header Number

Name1

Name1

of stats [ length [ [
vInt]

vInt]

Value1

Value1

length [ [

string vInt]

String

Name2 Name2 Value2 Value2 ...


length

length

Number of stats : Number of individual stats returned


Name length : Length of named statistic
Name : String containing statistic name
Value length : Length of value field
Value : String containing statistic value.

Ping
Application level request to see if the server is available.
Response status:
0x00 - if no errors

JBoss Community Documentation

Page 346 of 617

Infinispan 6.0

Error Handling
Response header Error Message Length vInt Error Message string
Response header contains error op code response and corresponding error status number as well as the
following two:
Error Message Length : Length of error message
Error message : Error message. In the case of 0x84, this error field contains the latest version
supported by the hot rod server. Length is defined by total body length.

Multi-Get Operations
A multi-get operation is a form of get operation that instead of requesting a single key, requests a set of
keys. The Hot Rod protocol does not include such operation but remote Hot Rod clients could easily
implement this type of operations by either parallelizing/pipelining individual get requests. Another possibility
would be for remote clients to use async or non-blocking get requests. For example, if a client wants N keys,
it could send send N async get requests and then wait for all the replies. Finally, multi-get is not to be
confused with bulk-get operations. In bulk-gets, either all or a number of keys are retrieved, but the client
does not know which keys to retrieve, whereas in multi-get, the client defines which keys to retrieve.

JBoss Community Documentation

Page 347 of 617

Infinispan 6.0

Example - Put request


Coded request
Byte 0

0x09

0x41

0x01

0x07

0x4D

0x79

0x43

('M')

('y')

('C')

0x00

0x03

0x00

0x00

0x00

16

24

32

0xA0

0x61

0x63

0x68

0x65

('a')

('c')

('h')

('e')

0x00

0x05

0x48

0x65

0x6C

0x6C

0x6F

('H')

('e')

('l')

('l')

('o')

0x57

0x6F

0x72

0x6C

0x64

('W')

('o')

('r')

('l')

('d')

0x00

0x05

Field explanation
Field Name

Value

Field Name

Value

Magic (0)

0xA0

Message Id (1)

0x09

Version (2)

0x41

Opcode (3)

0x01

Cache name length (4) 0x07

Cache name(5-11)

'MyCache'

Flag (12)

0x00

Client Intelligence (13) 0x03

Topology Id (14)

0x00

Transaction Type (15)

0x00

Transaction Id (16)

0x00

Key field length (17)

0x05

Key (18 - 22)

'Hello' Lifespan (23)

Max idle (24)

0x00

Value (26-30)

'World'

JBoss Community Documentation

Value field length (25)

0x00
0x05

Page 348 of 617

Infinispan 6.0

Coded response
Byte 0
8

5 6 7

0xA1 0x09 0x01 0x00 0x00

Field Explanation
Field Name

Value Field Name

Value

Magic (0)

0xA1

Message Id (1) 0x09

Opcode (2)

0x01

Status (3)

0x00

Topology change marker (4) 0x00

3.62 Cross site replication


Sample deployment
Configuration
Infinispan XML configuration file
Local cluster's jgroups .xml configuration
RELAY2 configuration file
Data replication
Non transactional caches
Transactional caches
Synchronous local cluster with async backup
Synchronous local cluster with sync backup
Asynchronous local cluster
Taking a site offline
Configuration
Taking a site back online
Reference
Cross site (x-site) replication allows backing up the data from one cluster to other clusters, potentially
situated in different geographical location. The cross-site replication is built on top of JGroups' RELAY2
protocol. This document describes the technical design of cross site replication in more detail.

JBoss Community Documentation

Page 349 of 617

Infinispan 6.0

3.62.1 Sample deployment


The diagram below depicts a possible setup of replicated sites, followed by a description of individual
elements present in the deployment. Options are then explained at large in future paragraphs.
Comments on the diagram above:

JBoss Community Documentation

Page 350 of 617

Infinispan 6.0

there are 3 sites: LON, NYC and SFO.


in each site there is a running Infinispan cluster with a (potentially) different number of physical nodes:
3 nodes in LON, 4 nodes in NYC and 3 nodes in SFO
the "users" cache is active in LON, NYC and SFO. Updates on the "users" cache in any of these sites
gets replicated to the other sites as well
it is possible to use different replication mechanisms between sites. E.g. One can configure SFO to
backup data synchronously to NYC and asynchronously to LON
the "users" cache can have a different configuration from one site to the other. E.g. it might be
configured as distributed with numOwners=2 in the LON site, REPL in the NYC site and distributed
with numOwners=1 in the SFO site
JGroups is used for both inter-site and intra-site communication. RELAY2 is used for inter-site
communication
"orders" is a site local to LON, i.e. updates to the data in "orders" don't get replicated to the remote
sites
The following sections discuss specific aspects of cross site replication into more detail. The
foundation of the cross-site replication functionality is RELAY2 so it highly recommended to read
JGroups' RELAY2 documentation before moving on into cross-site.

3.63 Configuration
The cross-site replication configuration spreads over the following files:

JBoss Community Documentation

Page 351 of 617

Infinispan 6.0

1. the backup policy for each individual cache is defined in infinispan's .xml configuration file (
infinispan.xml in attachment)
2. cluster's jgroups xml configuration file: RELAY2 protocol needs to be added to the JGroups protocol
stack (jgroups.xml)
3. RELAY2 configuration file: RELAY2 has an own configuration file (relay2.xml)
4. the jgroups channel that is used by RELAY2 has its own configuration file ( jgroups-relay2.xml)

3.63.2 Infinispan XML configuration file


The local site is defined in the the global configuration section. The local is the site where the node
using this configuration file resides (in the example above local site is "LON").

<global>
...
<site local="LON"/>
...
</global>

The same setup can be achieved programatically:

GlobalConfigurationBuilder lonGc = GlobalConfigurationBuilder.defaultClusteredBuilder();


lonGc.site().localSite("LON");

The names of the site (case sensitive) should match the name of a site as defined within JGroups'
RELAY2 protocol configuration file.
Besides the global configuration, each cache specifies its backup policy in the "site" element:

<namedCache name="users">
<sites>
<backups>
<backup site="NYC" backupFailurePolicy="WARN" strategy="SYNC" timeout="12000"/>
<backup site="SFO" backupFailurePolicy="IGNORE" strategy="ASYNC"/>
<backup site="LON" strategy="SYNC" enabled="false"/>
</backups>
</sites>
</namedCache>

The "users" cache backups its data to the "NYC" and "SFO" sites. Even though the "LON" appears as
a backup site, it has the "enabled" attribute set to false so it will be ignored .
For each site backup, the following configuration attributes can be specified:

JBoss Community Documentation

Page 352 of 617

Infinispan 6.0

strategy - the strategy used for backing up data, either "SYNC" or "ASYNC". Defaults to "ASYNC"
backupFailurePolicy - Decides what the system would do in case of failure during backup. Possible
values are:
IGNORE - allow the local operation/transaction to succeed
WARN - same as IGNORE but also logs an warning message. Default.
FAIL - only in effect if "strategy" is "SYNC" - fails local cluster operation/transaction by throwing
an exception to the user
CUSTOM - user provided, see "failurePolicyClass" below
failurePolicyClass - If the 'backupFailurePolicy' is set to 'CUSTOM' then this attribute is required and
should contain the fully qualified name of a class implementing
org.infinispan.xsite.CustomFailurePolicy
timeout - The timeout(milliseconds) to be used when backing up data remotely. Defaults to 10000 (10
seconds)
The same setup can be achieved programatically:

ConfigurationBuilder lon = new ConfigurationBuilder();


lon.sites().addBackup()
.site("NYC")
.backupFailurePolicy(BackupFailurePolicy.WARN)
.strategy(BackupConfiguration.BackupStrategy.SYNC)
.replicationTimeout(12000)
.sites().addInUseBackupSite("NYC")
.sites().addBackup()
.site("SFO")
.backupFailurePolicy(BackupFailurePolicy.IGNORE)
.strategy(BackupConfiguration.BackupStrategy.ASYNC)
.sites().addInUseBackupSite("SFO")

The "users" cache above doesn't know on which cache on the remote sites its data is being replicated. By
default the remote site writes the backup data to a cache having the same name as the originator, i.e.
"users". This behaviour can be overridden with an "backupFor" element. For example the following
configuration in SFO makes the "usersLONBackup" cache act as the backup cache for the "users" cache
defined above in the LON site:

<infinispan>
<namedCache name="usersLONBackup">
<sites>
<backupFor remoteCache="users" remoteSite="LON"/>
</sites>
</namedCache>
</infinispan>

The same setup can be achieved programatically:

ConfigurationBuilder cb = new ConfigurationBuilder();


cb.sites().backupFor().remoteCache("users").remoteSite("LON");

JBoss Community Documentation

Page 353 of 617

Infinispan 6.0

Local cluster's jgroups .xml configuration


This is the configuration file for the local (intra-site) infinispan cluster. It is referred from the infinispan
configuration file, see "configurationFile" below:

<infinispan>
..
<global>
<transport clusterName="infinispan-cluster">
<properties>
<property name="configurationFile" value="jgroups.xml"/>
</properties>
</transport>
</global>
..
</infinispan>

In order to allow inter-site calls, the RELAY2 protocol needs to be added to the protocol stack defined in the
jgroups configuration (see attached jgroups.xml for an example).

RELAY2 configuration file


The RELAY2 configuration file is linked from the jgroups.xml (see attached relay2.xml). It defines the sites
seen by this cluster and also the jgroups configuration file that is used by RELAY2 in order to communicate
with the remote sites.

3.63.3 Data replication


For both transactional and non-transactional caches, the backup calls are performed in parallel with local
cluster calls, e.g. if we write data to node N1 in LON then replication to the local nodes N2 and N3 and
remote backup sites SFO and NYC happen in parallel.

Non transactional caches


In the case of non-transactional caches the replication happens during each operation. Given that data is
sent in parallel to backups and local caches, it is possible for the operations to succeed locally and fail
remotely, or the other way, causing inconsistencies

JBoss Community Documentation

Page 354 of 617

Infinispan 6.0

Transactional caches
For synchronous transactional caches, Infinispan internally uses a two phase commit protocol: lock
acquisition during the 1st phase (prepare) and apply changes during the 2nd phase (commit). For
asynchronous caches the two phases are merged, the "apply changes" message being sent asynchronously
to the owners of data. This 2PC protocol maps to 2PC received from the JTA transaction manager.
For transactional caches, both optimistic and pessimistic, the backup to remote sites happens during the
prepare and commit phase only.

Synchronous local cluster with async backup


In this scenario the backup call happens during local commit phase(2nd phase). That means that if the local
prepare fails, no remote data is being sent to the remote backup.

Synchronous local cluster with sync backup


In this case there are two backup calls:
during prepare a message is sent across containing all the modifications that happened within this
transaction
if the remote backup cache is transactional then a transaction is started remotely and all these
modifications are being written within this transaction's scope. The transaction is not committed
yet (see below)
if the remote backup cache is not transactional, then the changes are applied remotely
during the commit/rollback, a commit/rollback message is sent across
if the remote backups cache is transactional then the transaction started at the previous phase
is committed/rolled back
if the remote backup is not transactional then this call is ignored
Both the local and the backup call(if the "backupFailurePolicy" is set to "FAIL") can veto transaction's
prepare outcome

Asynchronous local cluster


In the case of asynchronous local clusters, the backup data is sent during the commit phase. If the
backup call fails and the "backupFailurePolicy" is set to "FAIL" then the user is notified through an
exception.

JBoss Community Documentation

Page 355 of 617

Infinispan 6.0

3.63.4 Taking a site offline


If backing up to a site fails for a certain number of times during an time interval, then it is possible to
automatically mark that site as offline. When a site is marked as offline the local site won't try to backup data
to it anymore. In order to be taken online a system administrator intervention being required.

Configuration
The taking offline of a site can be configured as follows:

<namedCache name="bestEffortBackup">
...
<sites>
<backups>
<backup site="NYC" strategy="SYNC" backupFailurePolicy="FAIL">
<takeOffline afterFailures="500" minTimeToWait="10000"/>
</backup>
</backups>
</sites>
...
</namedCache>

The takeOfline element under the backup configures the taking offline of a site:
*afterFailure - the number of failed backup operations after which this site should be taken offline. Defaults to
0 (never). A negative value would mean that the site will be taken offline after minTimeToWait
*minTimeToWait - the number of milliseconds in which a site is not marked offline even if it is unreachable
for 'afterFailures' number of times. If smaller or equal to 0, then only afterFailures is considered.
The equivalent programmatic configuration is:

lon.sites().addBackup()
.site("NYC")
.backupFailurePolicy(BackupFailurePolicy.FAIL)
.strategy(BackupConfiguration.BackupStrategy.SYNC)
.takeOffline()
.afterFailures(500)
.minTimeToWait(10000);

Taking a site back online


In order to bring a site back online after being taken offline, one can use the JMX console and invoke the
"bringSiteOnline(siteName)" operation on the XSiteAdmin managed bean. At the moment this method would
need to be invoked on all the nodes within the site(further releases will overcome this limitation).

JBoss Community Documentation

Page 356 of 617

Infinispan 6.0

3.63.5 Reference
This document (Sept 2012) describes the technical design of cross site replication in more detail.

3.64 Map Reduce framework


Introduction
MapReduce API
Map Reduce task timeout
Mapper and CDI
MapReduceTask distributed execution
Examples

3.64.1 Introduction
MapReduce is a programming model allowing transparent distributed processing of very large data sets over
data grids. The name MapReduce comes from an idea of using two distinct computational phases of map
and reduce. In the map phase, master node that initiates a task takes the task input, divides it and sends
tasks for map phase execution on the grid. Each node in turns executes a map function on its input returning
intermediate results back to master node. Master node task collects all intermediate results from map
phase combines them by intermediate result keys and sends intermediate keys/values for reduction on the
grid. Finally master tasks node receives all results from reduction phases and returns the final result to
invoker of the MapReduce task.

3.64.2 MapReduce API


Infinispan's own MapReduce model is an adaptation of Google's original MapReduce. There are four main
components in each map reduce task: Mapper, Reducer, Collator and MapReduceTask.
Implementation of a Mapper class is a component of MapReduceTask invoked once for each input entry
K,V. Every Mapper instance is migrated to an Infinispan node, given a cache entry K,V input pair which it
transforms into an intermediate key/value pair emitted into Infinispan provided Collector instance.
Intermediate results are further reduced using a Reducer.

public interface Mapper<KIn, VIn, KOut, VOut> extends Serializable {


/**
* Invoked once for each input cache entry KIn,VOut pair.
*/
void map(KIn key, VIn value, Collector<KOut, VOut> collector);
}

JBoss Community Documentation

Page 357 of 617

Infinispan 6.0
The Reducer, as its name implies, reduces a list of intermediate results from map phase of
MapReduceTask. Infinispan distributed execution environment creates one instance of Reducer per
execution node.

public interface Reducer<KOut, VOut> extends Serializable {


/**
* Combines/reduces all intermediate values for a particular intermediate key to a single
value.
* <p>
*
*/
VOut reduce(KOut reducedKey, Iterator<VOut> iter);
}

Collator coordinates results from Reducers executed on Infinispan cluster and assembles a final result
returned to an invoker of MapReduceTask. Collator is applied to final Map<KOut,VOut> result of
MapReduceTask.

public interface Reducer<KOut, VOut> extends Serializable {


/**
* Combines/reduces all intermediate values for a particular intermediate key to a single
value.
* <p>
*
*/
VOut reduce(KOut reducedKey, Iterator<VOut> iter);
}

Finally, MapReduceTask is a distributed task unifying Mapper, Reducer and Collator into a cohesive large
scale computation to be transparently parallelized across Infinispan cluster nodes. Users of MapReduceTask
need to provide a cache whose data is used as input for this task. Infinispan execution environment will
instantiate and migrate instances of provided mappers and reducers seamlessly across Infinispan nodes.
Unless otherwise specified using onKeys method input keys filter all available key value pairs of a specified
cache will be used as input data for this task.

JBoss Community Documentation

Page 358 of 617

Infinispan 6.0

Map Reduce task timeout


The timeout per Map/Reduce task is only available for Infinispan 5.3.0.CR2 and higher.

It is possible to set a timeout value for each Map/Reduce tasks. However, if no timeout is specified, it uses
the replication timeout as a default timeout (the same behavior as the previous Infinispan versions).
You can set the timeout in your task by doing the following:

MapReduceTask task = new MapReduceTask(cache);


task.timeout(1, TimeUnit.MINUTES);

Also, it is possible to know which is the current timeout value for the task:

System.out.println("Map/Reduce task timeout is " + task.timeout(TimeUnit.MILLISECONDS) + "


millseconds");

For more information about this, please check the java doc in Map Reduce Task API Documentation

3.64.3 Mapper and CDI


Although Mapper gets invoked with an appropriate input key/value pairs on an executing node, Infinispan
also provides CDI injection of an input Cache in case users might need some additional data from input
cache in order to complete map transformation. Upon arrival of user's Mapper to an Infinispan executing
node, Infinispan CDI mechanism will provide appropriate cache reference and inject it to executing Mapper.
All one has to do is to declare a Cache field in Mapper and annotate it with @org.infinispan.cdi.Input
annotation along with the mandatory @Inject annotation.

public class WordCountCacheInjectedMapper implements Mapper<String, String, String, Integer> {


@Inject
@Input
private Cache<String, String> cache;
@Override
public void map(String key, String value, Collector<String, Integer> collector) {
//use injected cache if needed
StringTokenizer tokens = new StringTokenizer(value);
while (tokens.hasMoreElements()) {
String s = (String) tokens.nextElement();
collector.emit(s, 1);
}
}
}

JBoss Community Documentation

Page 359 of 617

Infinispan 6.0

3.64.4 MapReduceTask distributed execution


As our MapReduce implementation grew out of the proof of concept phase (and especially after our users
had already production tested it), we needed to remove the most prominent impediment to an industrial
grade MapReduce solution that we strive for: distributing reduce phase execution.
Reduce phase prior to the Infinispan 5.2 release was done on a single Infinispan master task node.
Therefore, the size of map reduce problems we could support (data size wise) was effectively shrunk to a
working memory of a single Infinispan node. Starting with the Infinispan 5.2 release, we have removed this
limitation, and reduce phase execution is distributed across the cluster as well. Of course, users still have an
option to use MapReduceTask the old way, and we even recommend that particular approach for smaller
sized input tasks. We have achieved distribution of reduce phase by relying on Infinispan's consistent
hashing and DeltaAware cache insertion. Here is how we distributed reduce phase execution:
Map phase
MapReduceTask, as it currently does, will hash task input keys and group them by execution node N they
are hashed to*. After key node mapping, MapReduceTask sends map function and input keys to each node
N. Map function is invoked using given keys and locally loaded corresponding values.

Results are collected with an Infinispan supplied Collector, and combine phase is initiated. A Combiner, if
specified, takes KOut keys and immediately invokes reduce phase on keys. The result of mapping phase
executed on each node is KOut/VOut map. There will be one resulting map per execution node N per
launched MapReduceTask.
Intermediate KOut/VOut migration phase

JBoss Community Documentation

Page 360 of 617

Infinispan 6.0
In order to proceed with reduce phase, all intermediate keys and values need to be grouped by intermediate
KOut keys. More specifically, as map phases around the cluster can produce identical intermediate keys, all
those identical intermediate keys and their values need to be grouped before reduce is executed on any
particular intermediate key.
Therefore at the end of combine phase, instead of returning map with intermediate keys and values to the
master task node, we instead hash each intermediate key KOut and migrate it with its VOut values to
Infinispan node where keys KOut are hashed to. We achieve this using a temporary DIST cache and
underlying consistent hashing mechanism. Using DeltaAware cache insertion we effectively collect all VOut
values under each KOut for all executed map functions across the cluster

At this point, map and combine phase have finished its execution; list of KOut keys is returned to a master
node and its initiating MapReduceTask. We do not return VOut values as we do not need them at master
task node. MapReduceTask is ready to start with reduce phase.
Reduce phase
Reduce phase is easy to accomplish now as Infinispan's consistent hashing already finished all the hard
lifting for us. To complete reduce phase, MapReduceTask groups KOut keys by execution node N they are
hashed to. For each node N and its grouped input KOut keys, MapReduceTask sends a reduce command to
a node N where KOut keys are hashed. Once reduce command arrives on target execution node, it looks up
temporary cache belonging to MapReduce task - and for each KOut key, grabs a list of VOut values, wraps it
with an Iterator and invokes reduce on it.

JBoss Community Documentation

Page 361 of 617

Infinispan 6.0

A result of each reduce is a map where each key is KOut and value is VOut. Each Infinispan execution node
N returns one map with KOut/VOut result values. As all initiated reduce commands return to a calling node,
MapReduceTask simply combines all resulting maps into map M and returns M as a result of
MapReduceTask.
Distributed reduce phase is turned on by using a MapReduceTask constructor specifying cache to use as
input data for the task and boolean parameter distributeReducePhase set to true. Map/Reduce API javadoc
and demos are included in distribution.

3.64.5 Examples
Word count is a classic, if not overused, example of map/reduce paradigm. Assume we have a mapping of
key-->sentence stored on Infinispan nodes. Key is a String, each sentence is also a String, and we have to
count occurrence of all words in all sentences available. The implementation of such a distributed task could
be defined as follows:

public class WordCountExample {


/**
* In this example replace c1 and c2 with
* real Cache references
*
* @param args
*/
public static void main(String[] args) {
Cache c1 = null;
Cache c2 = null;
c1.put("1",
c2.put("2",
c1.put("3",
c2.put("4",

"Hello world here I am");


"Infinispan rules the world");
"JUDCon is in Boston");
"JBoss World is in Boston as well");

JBoss Community Documentation

Page 362 of 617

Infinispan 6.0
c1.put("12","JBoss Application Server");
c2.put("15", "Hello world");
c1.put("14", "Infinispan community");
c2.put("15", "Hello world");
c1.put("111",
c2.put("112",
c1.put("113",
c2.put("114",
c1.put("211",
c2.put("212",
c1.put("213",
c2.put("214",

"Infinispan open source");


"Boston is close to Toronto");
"Toronto is a capital of Ontario");
"JUDCon is cool");
"JBoss World is awesome");
"JBoss rules");
"JBoss division of RedHat ");
"RedHat community");

MapReduceTask<String, String, String, Integer> t =


new MapReduceTask<String, String, String, Integer>(c1);
t.mappedWith(new WordCountMapper())
.reducedWith(new WordCountReducer());
Map<String, Integer> wordCountMap = t.execute();
}
static class WordCountMapper implements Mapper<String,String,String,Integer> {
/** The serialVersionUID */
private static final long serialVersionUID = -5943370243108735560L;
@Override
public void map(String key, String value, Collector<String, Integer> c) {
StringTokenizer tokens = new StringTokenizer(value);
while (tokens.hasMoreElements()) {
String s = (String) tokens.nextElement();
c.emit(s, 1);
}
}
}
static class WordCountReducer implements Reducer<String, Integer> {
/** The serialVersionUID */
private static final long serialVersionUID = 1901016598354633256L;
@Override
public Integer reduce(String key, Iterator<Integer> iter) {
int sum = 0;
while (iter.hasNext()) {
Integer i = (Integer) iter.next();
sum += i;
}
return sum;
}
}
}

As we have seen it is relatively easy to specify map reduce task counting number of occurrences for each
word in all sentences. Best of all result is returned to task invoker in the form of Map<KOut,VOut> rather
than being written to a stream.

JBoss Community Documentation

Page 363 of 617

Infinispan 6.0
What if we need to find the most frequent word in our word count example? All we have to do is to define a
Collator that will transform the result of MapReduceTask Map<KOut,VOut> into a String which in turn is
returned to a task invoker. We can think of Collator as transformation function applied to a final result of
MapReduceTask.

MapReduceTask<String, String, String, Integer> t = new MapReduceTask<String, String, String,


Integer>(cache);
t.mappedWith(new WordCountMapper()).reducedWith(new WordCountReducer());
String mostFrequentWord = t.execute(
new Collator<String,Integer,String>() {
@Override
public String collate(Map<String, Integer> reducedResults) {
String mostFrequent = "";
int maxCount = 0;
for (Entry<String, Integer> e : reducedResults.entrySet()) {
Integer count = e.getValue();
if(count > maxCount) {
maxCount = count;
mostFrequent = e.getKey();
}
}
return mostFrequent;
}
});
System.out.println("The most frequent word is " + mostFrequentWord);

3.65 Rolling upgrades for remote clients using Hot Rod


This process is used for installations making use of Infinispan as a remote grid, via Hot Rod. This assumes
an upgrade of the Infinispan grid, and not the client application.
In the following description we will refer to the Source and Target clusters, where the Source cluster is the
old cluster which is currently in use and the Target cluster is the new cluster to which the data will be
migrated to.

JBoss Community Documentation

Page 364 of 617

Infinispan 6.0

3.65.1 Steps
1. Start a new cluster (Target Cluster) with the new version of Infinispan, using either different network
settings or JGroups cluster name so that the old cluster (Source Cluster) and the new one don't
overlap.
2. For each cache to be migrated, the Target Cluster is configured with a RemoteCacheStore with the
following settings:
1. servers should point to the Source Cluster
2. remoteCacheName must coincide with the name of the cache on the Source Cluster
3. hotRodWrapping must be enabled (true)
3. Configure clients to point to the Target Cluster instead of the Source Cluster, and one by one,
restart each client node. Gradually, all requests will be handled by the Target Cluster rather than the
Source Cluster. The Target Cluster will lazily load data from the Source Cluster on demand via the
RemoteCacheStore.
4. Once all connections have switched to using the Target Cluster the keyset on the Source Cluster
must be dumped. This can be achieved either via a JMX operation or via the CLI:
1. JMX: invoke the recordKnownGlobalKeyset operation on the RollingUpgradeManager MBean
on the Source Cluster for all of the caches that need to be migrated
2. CLI: invoke the upgrade --dumpkeys command on the Source Cluster for all of the caches
that need to be migrated (additionally the --all switch can be used to dump all caches in the
cluster)
5. At this point the Target Cluster needs to fetch all remaining data from the Source Cluster:
1. JMX: invoke the synchronizeData operation specifying the "hotrod" parameter on the
RollingUpgradeManager MBean on the Target Cluster for all of the caches that need to be
migrated
2. CLI: invoke the upgrade --synchronize=hotrod command on the Target Cluster for all of the
caches that need to be migrated (additionally the --all switch can be used to synchronize all
caches in the cluster)
6. Once the above operation is complete, the RemoteCacheStore on the Target Cluster must be
disabled as follows:
1. JMX: invoke the disconnectSource operation specifying the "hotrod" parameter on the
RollingUpgradeManager MBean on the Target Cluster for all of the caches that have been
migrated
2. CLI: invoke the upgrade --disconnectsource=hotrod command on the Target Cluster for all of
the caches that have been migrated (additionally the --all switch can be used to disconnect all
caches in the cluster)
7. The Source Cluster can be decomissioned now.

JBoss Community Documentation

Page 365 of 617

Infinispan 6.0

3.66 Command-Line Interface (CLI)


Infinispan offers a simple Command-Line Interface (CLI) with which it is possible to interact with the data
within the caches and with most of the internal components (e.g. transactions, cross-site backups, rolling
upgrades).
The CLI is built out of two elements: a server-side module and the client command tool. The server-side
module (infinispan-cli-server-$VERSION.jar) provides the actual interpreter for the commands and needs to
be included alongside your application. If you are using the startServer.[sh.bat] script it is included by default.
Currently the server (and the client) use the JMX protocol to communicate, but in a future release we plan to
support other communication protocols (in particular our own HotRod).
The CLI offers both an interactive and a batch mode. To invoke the client, just run the provided
bin/ispn-cli.[sh|bat] script. The following is a list of command-line switches which affect how the CLI can be
started:

-c, --connect=URL

connects to a running instance of Infinispan.


JMX over RMI jmx://[username[:password]]@host:port[/container[/cache]]
JMX over JBoss remoting
remoting://[username[:password]]@host:port[/container[/cache]]
-f, --file=FILE
reads input from the specified file instead of using

-h, --help
-v, --version

interactive mode. If FILE is '-', then commands will be read


from stdin
shows this help page
shows version information

* JMX over RMI is the traditional way in which JMX clients connect to MBeanServers. Please refer to the
JDK Monitoring and Management documentation for details on how to configure the process to be monitored
JMX over JBoss Remoting is the protocol of choice when your Infinispan application is running within
JBoss AS7 or EAP6.
The connection to the application can also be initiated from within the CLI using the connect command.

[disconnected//]> connect jmx://localhost:12000


[jmx://localhost:12000/MyCacheManager/>

The CLI prompt will show the active connection information, including the currently selected CacheManager.
Initially no cache is selected so, before performing any cache operations, one must be selected. For this the
cache command is used. The CLI supports tab-completion for all commands and options and for most
parameters where it makes sense to do so. Therefore typing cache and pressing TAB will show a list of
active caches:

JBoss Community Documentation

Page 366 of 617

Infinispan 6.0

[jmx://localhost:12000/MyCacheManager/> cache
___defaultcache namedCache
[jmx://localhost:12000/MyCacheManager/]> cache ___defaultcache
[jmx://localhost:12000/MyCacheManager/___defaultcache]>

Pressing TAB at an empty prompt will show the list of all available commands:

alias
upgrade
abort
version
begin

cache

container

encoding

get

locate

remove

site

clear

create

end

help

put

replace

start

commit

disconnect

evict

info

quit

rollback

stats

The CLI is based on sh and therefore offers many keyboard shortcuts to navigate and search the history
of commands, to manipulate the cursor at the prompt, including both Emacs and VI modes of operation.

3.66.1 Commands

abort
The abort command is used to abort a running batch initiated by the start command

[jmx://localhost:12000/MyCacheManager/namedCache]>
[jmx://localhost:12000/MyCacheManager/namedCache]>
[jmx://localhost:12000/MyCacheManager/namedCache]>
[jmx://localhost:12000/MyCacheManager/namedCache]>
null

start
put a a
abort
get a

begin
The begin command starts a transaction. In order for this command to work, the cache(s) on which the
subsequent operations are invoked must have transactions enabled.

[jmx://localhost:12000/MyCacheManager/namedCache]>
[jmx://localhost:12000/MyCacheManager/namedCache]>
[jmx://localhost:12000/MyCacheManager/namedCache]>
[jmx://localhost:12000/MyCacheManager/namedCache]>

JBoss Community Documentation

begin
put a a
put b b
commit

Page 367 of 617

Infinispan 6.0

cache
The cache command selects the cache to use as default for all subsequent operations. If it is invoked
without parameters it shows the currently selected cache.

[jmx://localhost:12000/MyCacheManager/namedCache]> cache ___defaultcache


[jmx://localhost:12000/MyCacheManager/___defaultcache]> cache
___defaultcache
[jmx://localhost:12000/MyCacheManager/___defaultcache]>

clear
The clear command clears a cache from all content.

[jmx://localhost:12000/MyCacheManager/namedCache]> put a a
[jmx://localhost:12000/MyCacheManager/namedCache]> clear
[jmx://localhost:12000/MyCacheManager/namedCache]> get a
null

commit
The commit command commits an ongoing transaction

[jmx://localhost:12000/MyCacheManager/namedCache]>
[jmx://localhost:12000/MyCacheManager/namedCache]>
[jmx://localhost:12000/MyCacheManager/namedCache]>
[jmx://localhost:12000/MyCacheManager/namedCache]>

begin
put a a
put b b
commit

container
The container command selects the default container (cache manager). Invoked without parameters it lists
all available containers

[jmx://localhost:12000/MyCacheManager/namedCache]> container
MyCacheManager OtherCacheManager
[jmx://localhost:12000/MyCacheManager/namedCache]> container OtherCacheManager
[jmx://localhost:12000/OtherCacheManager/]>

create
The create command creates a new cache based on the configuration of an existing cache definition

[jmx://localhost:12000/MyCacheManager/namedCache]> create newCache like namedCache


[jmx://localhost:12000/MyCacheManager/namedCache]> cache newCache
[jmx://localhost:12000/MyCacheManager/newCache]>

JBoss Community Documentation

Page 368 of 617

Infinispan 6.0

disconnect
The disconnect command disconnects the currently active connection allowing the CLI to connect to another
instance.

[jmx://localhost:12000/MyCacheManager/namedCache]> disconnect
[disconnected//]

encoding
The encoding command is used to set a default codec to use when reading/writing entries from/to a cache.
When invoked without arguments it shows the currently selected codec.
This command is useful since currently remote protocols such as HotRod and Memcached wrap keys and
values in specialized structures.

[jmx://localhost:12000/MyCacheManager/namedCache]> encoding
none
[jmx://localhost:12000/MyCacheManager/namedCache]> encoding --list
memcached
hotrod
none
rest
[jmx://localhost:12000/MyCacheManager/namedCache]> encoding hotrod

end
The end command is used to successfully end a running batch initiated by the start command

[jmx://localhost:12000/MyCacheManager/namedCache]>
[jmx://localhost:12000/MyCacheManager/namedCache]>
[jmx://localhost:12000/MyCacheManager/namedCache]>
[jmx://localhost:12000/MyCacheManager/namedCache]>
a

start
put a a
end
get a

evict
The evict command is used to evict from the cache the entry associated with a specific key.

[jmx://localhost:12000/MyCacheManager/namedCache]> put a a
[jmx://localhost:12000/MyCacheManager/namedCache]> evict a

JBoss Community Documentation

Page 369 of 617

Infinispan 6.0

get
The get command is used to show the value associated to a specified key. For primitive types and Strings,
the get command will simply print the default representation. For other objects, a JSON representation of the
object will be printed.

[jmx://localhost:12000/MyCacheManager/namedCache]> put a a
[jmx://localhost:12000/MyCacheManager/namedCache]> get a
a

info
The info command is used to show the configuration of the currently selected cache or container.

[jmx://localhost:12000/MyCacheManager/namedCache]> info
GlobalConfiguration{asyncListenerExecutor=ExecutorFactoryConfiguration{factory=org.infinispan.executors.Defaul
asyncTransportExecutor=ExecutorFactoryConfiguration{factory=org.infinispan.executors.DefaultExecutorFactory@7b
evictionScheduledExecutor=ScheduledExecutorFactoryConfiguration{factory=org.infinispan.executors.DefaultSchedu
replicationQueueScheduledExecutor=ScheduledExecutorFactoryConfiguration{factory=org.infinispan.executors.Defau
globalJmxStatistics=GlobalJmxStatisticsConfiguration{allowDuplicateDomains=true, enabled=true,
jmxDomain='jboss.infinispan',
mBeanServerLookup=org.jboss.as.clustering.infinispan.MBeanServerProvider@6c0dc01,
cacheManagerName='local', properties={}}, transport=TransportConfiguration{clusterName='ISPN',
machineId='null', rackId='null', siteId='null', strictPeerToPeer=false,
distributedSyncTimeout=240000, transport=null, nodeName='null', properties={}},
serialization=SerializationConfiguration{advancedExternalizers={1100=org.infinispan.server.core.CacheValue$Ext
1101=org.infinispan.server.memcached.MemcachedValue$Externalizer@720bffd,
1104=org.infinispan.server.hotrod.ServerAddress$Externalizer@771c7eb2},
marshaller=org.infinispan.marshall.VersionAwareMarshaller@6fc21535, version=52,
classResolver=org.jboss.marshalling.ModularClassResolver@2efe83e5},
shutdown=ShutdownConfiguration{hookBehavior=DONT_REGISTER}, modules={},
site=SiteConfiguration{localSite='null'}}

locate
The locate command shows the physical location of a specified entry in a distributed cluster.

[jmx://localhost:12000/MyCacheManager/namedCache]> locate a
[host/node1,host/node2]

JBoss Community Documentation

Page 370 of 617

Infinispan 6.0

put
The put command inserts an entry in the cache. If the cache previously contained a mapping for the key, the
old value is replaced by the specified value. The user can control the type of data that the CLI will use to
store the key and value. See the Data Types paragraph.

[jmx://localhost:12000/MyCacheManager/namedCache]>
[jmx://localhost:12000/MyCacheManager/namedCache]>
[jmx://localhost:12000/MyCacheManager/namedCache]>
[jmx://localhost:12000/MyCacheManager/namedCache]>
[jmx://localhost:12000/MyCacheManager/namedCache]>
null, "b": true } }

put
put
put
put
put

a
b
c
d
e

a
100
4139l
true
{ "package.MyClass": {"i": 5, "x":

The put command can optionally specify a lifespan and a maximum idle time.

[jmx://localhost:12000/MyCacheManager/namedCache]> put a a expires 10s


[jmx://localhost:12000/MyCacheManager/namedCache]> put a a expires 10m maxidle 1m

replace
The replace command replaces an existing entry in the cache. If an old value is specified, then the
replacement happens only if the value in the cache coincides.

[jmx://localhost:12000/MyCacheManager/namedCache]>
[jmx://localhost:12000/MyCacheManager/namedCache]>
[jmx://localhost:12000/MyCacheManager/namedCache]>
b
[jmx://localhost:12000/MyCacheManager/namedCache]>
[jmx://localhost:12000/MyCacheManager/namedCache]>
c
[jmx://localhost:12000/MyCacheManager/namedCache]>
[jmx://localhost:12000/MyCacheManager/namedCache]>
c

put a a
replace a b
get a
replace a b c
get a
replace a b d
get a

rollback
The rollback command rolls back an ongoing transaction

[jmx://localhost:12000/MyCacheManager/namedCache]>
[jmx://localhost:12000/MyCacheManager/namedCache]>
[jmx://localhost:12000/MyCacheManager/namedCache]>
[jmx://localhost:12000/MyCacheManager/namedCache]>

JBoss Community Documentation

begin
put a a
put b b
rollback

Page 371 of 617

Infinispan 6.0

site
The site command performs operations related to the administration of cross-site replication. It can be used
to obtain information related to the status of a site and to change the status (online/offline)

[jmx://localhost:12000/MyCacheManager/namedCache]>
online
[jmx://localhost:12000/MyCacheManager/namedCache]>
ok
[jmx://localhost:12000/MyCacheManager/namedCache]>
offline
[jmx://localhost:12000/MyCacheManager/namedCache]>

site --status NYC


site --offline NYC
site --status NYC
site --online NYC

start
The start command initiates a batch of operations.

[jmx://localhost:12000/MyCacheManager/namedCache]>
[jmx://localhost:12000/MyCacheManager/namedCache]>
[jmx://localhost:12000/MyCacheManager/namedCache]>
[jmx://localhost:12000/MyCacheManager/namedCache]>

start
put a a
put b b
end

stats
The stats command displays statistics about a cache

[jmx://localhost:12000/MyCacheManager/namedCache]> stats
Statistics: {
averageWriteTime: 143
evictions: 10
misses: 5
hitRatio: 1.0
readWriteRatio: 10.0
removeMisses: 0
timeSinceReset: 2123
statisticsEnabled: true
stores: 100
elapsedTime: 93
averageReadTime: 14
removeHits: 0
numberOfEntries: 100
hits: 1000
}
LockManager: {
concurrencyLevel: 1000
numberOfLocksAvailable: 0
numberOfLocksHeld: 0
}

JBoss Community Documentation

Page 372 of 617

Infinispan 6.0

upgrade
The ugrade command performs operations used during the rolling upgrade procedure. For a detailed
description of this procedure please see Rolling upgrades

[jmx://localhost:12000/MyCacheManager/namedCache]> upgrade --synchronize=hotrod --all


[jmx://localhost:12000/MyCacheManager/namedCache]> upgrade --disconnectsource=hotrod --all

version
The version command displays version information about both the CLI client and the server

[jmx://localhost:12000/MyCacheManager/namedCache]> version
Client Version 5.2.1.Final
Server Version 5.2.1.Final

3.66.2 Data Types


The CLI understands the following types:
string
strings can either be quoted between single (') or double (") quotes, or left unquoted. In this case it
must not contain spaces, punctuation and cannot begin with a number e.g. 'a string', key001
int
an integer is identified by a sequence of decimal digits, e.g. 256
long
a long is identified by a sequence of decimal digits suffixed by 'l', e.g. 1000l
double
a double precision number is identified by a floating point number(with optional exponent part) and an
optional 'd' suffix, e.g.3.14
float
a single precision number is identified by a floating point number(with optional exponent part) and an
'f' suffix, e.g. 10.3f
boolean
a boolean is represented either by the keywords true and false
UUID
a UUID is represented by its canonical form XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX
JSON
serialized Java classes can be represented using JSON notation, e.g.
{"package.MyClass":{"i":5,"x":null,"b":true}}. Please note that the specified class must be available to
the CacheManager's class loader.

JBoss Community Documentation

Page 373 of 617

Infinispan 6.0

3.66.3 Time Values


A time value is an integer number followed by time unit suffix: days (d), hours (h), minutes (m), seconds (s),
milliseconds (ms).

3.67 Total Order based commit protocol


Introduction
Overview
Commit in one phase
Commit in two phases
Transaction Recovery
Total order executor service
State Transfer
Configuration
Total Order protocols in JGroups.
SEQUENCER
TOA - Total Order Anycast
Benchmark results

3.67.1 Introduction
The Total Order based protocol is a multi-master scheme (in this context, multi-master scheme means that
all nodes can update all the data) as the (optimistic/pessimist) locking model implemented in Infinispan. This
commit protocol relies on the concept of totally ordered delivery of messages which, informally, implies that
each node which delivers a set of messages, delivers them in the same order.
This protocol comes with this advantages.
1. transactions can be committed in one phase, as they are delivered in the same order by the nodes
that receive them.
2. it mitigates distributed deadlocks.
The weaknesses of this approach are the fact that its implementation relies on a single thread per node
which delivers the transaction and its modification, and the slightly higher number of messages exchanged
by JGroups.
Thus, this protocol delivers best performance in scenarios of high contention, in which it can benefit from
the single-phase commit and the deliver thread is not the bottleneck.
Currently, the Total Order based protocol is available only in transactional caches for replicated and
distributed modes.

JBoss Community Documentation

Page 374 of 617

Infinispan 6.0

3.67.2 Overview
The Total Order based commit protocol only affects how transactions are committed and it depends of the
isolation level configured, more precisely the write skew check. Note that it only provides the same
isolation levels as the locking model, i.e. read-committed and repeatable-read. If the write skew check is
not enabled, then all the transaction are committed in one phase (independently if Infinispan is enlisted as
Synchronization or XaResource). In this case, the isolation level is not violated because it is ensured during
the transaction execution. Also the transactions always commit successfully because they do not need to
perform any validation in prepare phase.
On other hand, when write skew check is enabled, the protocol adapts using one phase commit when it is
safe. However, if Infinispan is enlisted as Synchronization, it always commit in two phases, because the
Transaction Manager does not provide any information if Infinispan is the only resource enlisted or not. In
XaResource enlistment, we can use one phase if the Transaction Manager request a commit in one phase
(i.e. one-phase optimization, usually used when the transaction has a single XaResource registered, see
XaResource.commit()) and the Infinispan cache is configured in replicated mode or in distributed mode (the
last one, when the writeSkew==false). This optimization is not safe in distributed mode when
writeSkew==true because each node performs the validation in different keys subset.

JBoss Community Documentation

Page 375 of 617

Infinispan 6.0

Commit in one phase


When the transaction ends, Infinispan sends the transaction (and its modification) in total order. This
ensures all the transactions are deliver in the same order in all the involved Infinispan nodes. As a result,
when a transaction is delivered, it performs a deterministic validation over the same state, leading to the
same outcome (transaction commit or rollback). Also, if the transactional mode is configured with
syncCommitPhase==false, the node that sent the transaction still needs to wait for the self-deliver of the
transaction because it needs to know the transaction outcome. In other hand, it does not need to wait for the
replies from other nodes because they will reply with the same outcome. Although, if
syncCommitPhase==true, it needs to wait for the replies in order to respect the semantic of the flag.

The figure above demonstrates a high level example with 3 nodes. Node1 and Node3 are running one
transaction each and lets assume that both transaction writes on the same key. To make it more interesting,
lets assume that both nodes tries to commit at the same time, represented by the first colored circle in the
figure. The blue circle represents the transaction tx1 and the green the transaction tx2. Both nodes do a
remote invocation in total order (to-send) with the transaction's modifications. At this moment, all the nodes
will agree in the same deliver order, for example, tx1 followed by tx2. Then, each node delivers tx1, perform
the validation and commits the modifications. The same steps are performed for tx2 but, in this case, the
validation will fail and the transaction is rollback in all the involved nodes.

JBoss Community Documentation

Page 376 of 617

Infinispan 6.0

Commit in two phases


The first phase is the same as described above except that the nodes will not apply the modifications after
the validation, including the modifications sent in total order and the same scheme to wait for the replies. As
soon as it has the confirmation that all keys are successfully validated, it give a positive response to the
Transaction Manager (remember that the Transaction Manager is responsive to invoke the prepare() of the
transaction). On other hand, if it receives a negative reply, it returns a negative response to the Transaction
Manager. Finally, the transaction is committed or aborted in the second phase depending of the Transaction
Manager.

The figure above shows the scenario described in the first figure but now committing the transactions using
two phases. When tx1 is deliver, it performs the validation and it replies to the Transaction Manager. Next,
lets assume that tx2 is deliver before the Transaction Manager request the second phase for tx1. In this
case, tx2 will be enqueued and it will be validated only when tx1 is completed. Eventually, the Transaction
Manager for tx1 will request the second phase (the commit) and all the nodes are free to perform the
validation of tx2.

Transaction Recovery
Transaction Recovery is currently not available for Total Order based commit protocol

JBoss Community Documentation

Page 377 of 617

Infinispan 6.0

Total order executor service


As previous said, only one thread is delivering the transactions, which makes this thread a possible
bottleneck of the system. Although, only conflicting transactions (i.e. which the write set intercepts) needs to
be validated in order. For example, if a node delivers tx1(write(A)), tx2(write(A)) and tx3(write(B)), tx2 must
wait until the tx1 is completed, but tx3 can be validated concurrently with tx1 and tx2. After analyzing the
transaction dependencies, is possible to enqueue the transactions that conflicts to non-completed
transactions and move to a executor service the transaction that can be concurrently validated.

Warning
The total order executor service needs an ExecutorService (see the Configuration section). Please
make sure that the ExecutorService does not reject tasks otherwise your data becomes
inconsistent.

JBoss Community Documentation

Page 378 of 617

Infinispan 6.0

State Transfer
For simplicity reasons, the total order based commit protocol uses a blocking version of the current state
transfer. The main differences are:
1. enqueue the transaction deliver while the state transfer is in progress;
2. the state transfer control messages (CacheTopologyControlCommand) are sent in total order.
This way, it provides a synchronization between the state transfer and the transactions deliver that is the
same all the nodes. Although, the transactions caught in the middle of state transfer (i.e. sent before the
state transfer start and deliver after it) needs to be re-sent to find a new total order involving the new joiners.

The figure above describes a node joining. In the scenario, the tx2 is sent in topologyId=1 but when it is
received, it is in topologyId=2. So, the transaction is re-sent involving the new nodes.

3.67.3 Configuration
To use Total Order based commit protocol in your Infinispan cache, you need to configure a couple of thing:
add the total order protocols in JGroups configuration file:

JBoss Community Documentation

Page 379 of 617

Infinispan 6.0

<SEQUENCER />
<tom.TOA />

Check the JGroups manual for more detail in here: JGroups Manual
configure the Infinispan cache as a transactional cache and set the transaction protocol to total order:

<namedCache >
<transaction
transactionMode="TRANSACTIONAL"
transactionProtocol="TOTAL_ORDER" />
</namedCache>

You can build the same configuration programmatically in the following way:

ConfigurationBuilder cb = new ConfigurationBuilder();


cb.transaction().transactionMode(TransactionMode.TRANSACTIONAL).transactionProtocol(TransactionProtocol.TOTAL_

Optionally, you can configure the total order executor to use your own executor services. By default, it
creates an executor service with coreThreads=1 and maxThreads=32. It can be configured in the following
way:

<global>
<totalOrderExecutor factory="org.infinispan.executor.DefaultExecutorFactory>
<property name="coreThreads" value="1" />
<property name="maxThreads" value="32" />
</totalOrderExecutor>
</global>

or programmaticaly:

GlobalConfigurationBuilder gcb = new GlobalConfigurationBuilder();


gcb.totalOrderExectutor().factory(new DefaultExecutorFactory()).addProperty("coreThread",
"1").addProperty("maxThreads", "32");

Beside the coreThreads and the maxThreads, the DefaultExecutorFactory also accepts as properties as the
queueSize, keepAliveTime (in milliseconds), threadPriority, threadNamePrefix and threadNameSuffix. Note
that, this parameters are used by the ExecutorService. The total order executor uses an unbouded queue.
Also, when you provide an ExecutorService, make sure that it will no reject tasks, otherwise your data can
became inconsistent.

JBoss Community Documentation

Page 380 of 617

Infinispan 6.0

3.67.4 Total Order protocols in JGroups.


SEQUENCER
The SEQUENCER protocol ensures total order involving all the members in the cluster. It is a
sequencer-based implementation in which the sender forwards the messages to a sequencer (the current
cluster coordinator), and the sequencer sends it back to the cluster on behalf of the original sender. Because
it is always the same sender (whose messages are delivered in FIFO order), a global (or total) order is
established.

The figure above shows the the communication steps to total order broadcast two messages M1 and M2
from different senders. Below, the figure shows the communication steps needed to commit a single
transaction, when two phase are used. The dotted line represents the communications steps performed by
the SEQUENCER. As it is possible to see, ensure total order is not a cheap operation and it has a cost of an
extra communication step comparing with the lock based implementation.

JBoss Community Documentation

Page 381 of 617

Infinispan 6.0

More information about the SEQUENCER in JGroups manual: SEQUENCER - JGroups Manual page

TOA - Total Order Anycast


The TOA protocol is implemented based on the Skeen Algorithm. Each node has an ordered (by the
message logical clock) queue with the messages and a local logical clock and it works in a centralized way.
The sender sends N unicast messages with the data to all destination nodes. When the message is
received, each replica increments it logical clock and it sends back the value to the sender. Meanwhile, the
message is put on the queue with the value of logical clock and marked as temporary. The sender collects
all values and calculates the maximum value of them. Finally it sends other N unicast message with the final
value of the message. This number indicates the final order number of deliver for the message. Each replica
updates it logical clock, if the value is lower than the final value received, and updates the message in the
queue, re-ordered if necessary. Then the message is marked as final. The messages are delivered when it
is on the top of the queue and is final. The figure below explains in a graphical way how it is done.

JBoss Community Documentation

Page 382 of 617

Infinispan 6.0

The next figure show one transaction to be committed in detail, including all the communication steps. The
dotted line represents the messages exchanged by TOA and the solid lines a single unicast message. This
figure shows that the total order protocol has 2 more communications steps than the lock based
implementation.

JBoss Community Documentation

Page 383 of 617

Infinispan 6.0

More information about the Total Order Anycast in JGroups manual: TOA - JGroups Manual page

3.67.5 Benchmark results


In order to compare the performance of total order with the locking model, RadarGun was used to perform a
benchmark evaluation in two different scenarios: a no contention scenario and a contention scenario.
The Infinispan configuration used is:

JBoss Community Documentation

Page 384 of 617

Infinispan 6.0

<?xml version="1.0" encoding="UTF-8"?>


<infinispan xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="urn:infinispan:config:5.3">
<global>
<transport clusterName="x">
<properties>
<property name="configurationFile" value="jgroups/jgroups.xml"/>
</properties>
</transport>
</global>
<default>
<transaction
transactionManagerLookupClass="org.infinispan.transaction.lookup.GenericTransactionManagerLookup"
transactionMode="TRANSACTIONAL"
transactionProtocol="TOTAL_ORDER"> <!-- transactionProtocol="DEFAULT" for the
locking model -->
<recovery enabled="false"/>
</transaction>
<locking concurrencyLevel="1000" useLockStriping="false"
isolationLevel="REPEATABLE_READ" writeSkewCheck="true"/> <!-- writeSkewCheck="false" for the no
write skew experiments -->
<clustering mode="r"> <!-- mode="d" for distributed mode -->
<sync replTimeout="10000"/>
<stateTransfer fetchInMemoryState="false"/>
<hash numOwners="2" /> <!-- for distributed mode only -->
</clustering>
</default>
<namedCache name="testCache"/>
</infinispan>

and the benchmark configuration is:

JBoss Community Documentation

Page 385 of 617

Infinispan 6.0

...
<benchmark initSize="2" maxSize="${10:slaves}" increment="2">
<DestroyWrapper runOnAllSlaves="true"/>
<StartCluster staggerSlaveStartup="true" delayAfterFirstSlaveStarts="5000"
delayBetweenStartingSlaves="500"/>
<ClusterValidation partialReplication="false"/>
<StressTestWarmup duration="1m" opsCountStatusLog="5000" numThreads="8"
transactionSize="10"
useTransactions="true" writePercentage="50" numEntries="1000"
sharedKeys="false"/>
<StressTest duration="5m" opsCountStatusLog="5000" numThreads="8" transactionSize="10"
useTransactions="true" writePercentage="50" numEntries="1000"
sharedKeys="false"/>
<CsvReportGeneration targetDir="no_contention"/>
<ClearCluster/>
<StressTestWarmup duration="1m" opsCountStatusLog="5000" numThreads="8"
transactionSize="10"
useTransactions="true" writePercentage="50" numEntries="1000"
sharedKeys="true"/>
<StressTest duration="5m" opsCountStatusLog="5000" numThreads="8" transactionSize="10"
useTransactions="true" writePercentage="50" numEntries="1000"
sharedKeys="true"/>
<CsvReportGeneration targetDir="contention"/>
</benchmark>
...

The difference between the contention and no contention is the pool of key. In the first case the pool of keys
are shared among all the threads (and nodes) and in the last case each threads has it own private pool of
keys.
The first group of plots shows the performance in the contented scenario:

JBoss Community Documentation

Page 386 of 617

Infinispan 6.0

and the next group of plots the no contended scenario:

JBoss Community Documentation

Page 387 of 617

Infinispan 6.0

3.68 Using Infinispan as a JCache provider


Dependencies
Create a local cache
Store and retrieve data
Comparing java.util.concurrent.ConcurrentMap and javax.cache.Cache APIs
Clustering JCache instances
Expire cached data
Annotations
Atomic compound operations on cache entry
Using cache listeners
Quickstarts
Starting with version 5.3, Infinispan provides an implementation of JCache API ( JSR-107). JCache specifies
a standard Java API for caching temporary Java objects in memory. Caching java objects can help get
around bottlenecks arising from using data that is expensive to retrieve (i.e. DB or web service), or data that
is hard to calculate. Caching these type of objects in memory can help speed up application performance by
retrieving the data directly from memory instead of doing an expensive roundtrip or recalculation. This
document specifies how to use JCache with Infinispan's implementation of the specification, and explains
key aspects of the API.

At the time of writing, Infinispan 6.0.0.Alpha4 implements version 0.8 of the JCache specification.

3.68.1 Dependencies
In order to start using Infinispan JCache implementation, a single dependency needs to be added to the
Maven pom.xml file:

<dependency>
<groupId>org.infinispan</groupId>
<artifactId>infinispan-jcache</artifactId>
<version>...</version> <!-- i.e. 6.0.0.Alpha4 -->
<scope>test</scope>
</dependency>

JBoss Community Documentation

Page 388 of 617

Infinispan 6.0

3.68.2 Create a local cache


Creating a local cache, using default configuration options as defined by the JCache API specification, is as
simple as doing the following:

import
import
import
import

javax.cache.Cache;
javax.cache.CacheManager;
javax.cache.Caching;
javax.cache.configuration.MutableConfiguration;

// Retrieve the system wide cache manager


CacheManager cacheManager = Caching.getCachingProvider().getCacheManager();
// Define a named cache with default JCache configuration
Cache<String, String> cache = cacheManager.configureCache("namedCache", new
MutableConfiguration<String, String>());

By default, the JCache API specifies that data should be stored as storeByValue, so that object
state mutations outside of operations to the cache, won't have an impact in the objects stored in the
cache. Infinispan has so far implemented this using serialization/marshalling to make copies to
store in the cache, and that way adhere to the spec. Hence, if using default JCache configuration
with Infinispan, data stored must be marshallable. Instructions on how to make data stored in
Infinispan marshallable can be found here.

Alternatively, JCache can be configured to store data by reference (just like Infinispan or JDK Collections
work). To do that, simply call:

Cache<String, String> cache = cacheManager.configureCache("namedCache", new


SimpleConfiguration<String, String>().setStoreByValue(false));

JBoss Community Documentation

Page 389 of 617

Infinispan 6.0

3.68.3 Store and retrieve data


Even though JCache API does not extend neither java.util.Map not
java.util.concurrent.ConcurrentMap, it providers a key/value API to store and retrieve data:

import
import
import
import

javax.cache.Cache;
javax.cache.CacheManager;
javax.cache.Caching;
javax.cache.configuration.MutableConfiguration;

CacheManager cacheManager = Caching.getCachingProvider().getCacheManager();


Cache<String, String> cache = cacheManager.configureCache("namedCache", new
MutableConfiguration<String, String>());
cache.put("hello", "world"); // Notice that javax.cache.Cache.put(K) returns void!
String value = cache.get("hello"); // Returns "world"

Contrary to standard java.util.Map, javax.cache.Cache comes with two basic put methods called
put and getAndPut. The former returns void whereas the latter returns the previous value associated with
the key. So, the equivalent of java.util.Map.put(K) in JCache is
javax.cache.Cache.getAndPut(K).

Even though JCache API only convers standalone caching, it can be plugged with a persistence
store, and has been designed with clustering or distribution in mind. The reason why
javax.cache.Cache offers two put methods is because standard java.util.Map put call
forces implementors to calculate the previous value. When a persistent store is in use, or the cache
is distributed, returning the previous value could be an expensive operation, and often users call
standard java.util.Map.put(K) without using the return value. Hence, JCache users need to
think about whether the return value is relevant to them, in which case they need to call
javax.cache.Cache.getAndPut(K), otherwise they can call javax.cache.Cache.put(K)
which avoids returning the potentially expensive operation of returning the previous value.

3.68.4 Comparing java.util.concurrent.ConcurrentMap and


javax.cache.Cache APIs
Here's a brief comparison of the data manipulation APIs provided by
java.util.concurrent.ConcurrentMap and javax.cache.Cache APIs.

JBoss Community Documentation

Page 390 of 617

Infinispan 6.0

Operation

java.util.concurrent.ConcurrentMap<K, javax.cache.Cache<K, V>


V>

store and no return


store and return

void put(K key)


V put(K key)

V getAndPut(K key)

V putIfAbsent(K key, V value)

boolean putIfAbsent(K

previous value
store if not present

key, V value)
retrieve

V get(Object key)

V get(K key)

delete if present

V remove(Object key)

boolean remove(K key)

delete and return

V remove(Object key)

V getAndRemove(K key)

boolean remove(Object key, Object

boolean remove(K key, V

value)

oldValue)

V replace(K key, V value)

boolean replace(K key,

previous value
delete conditional

replace if present

V value)
replace and return

V replace(K key, V value)

previous value
replace conditional

V getAndReplace(K key,
V value)

boolean replace(K key, V oldValue, V

boolean replace(K key,

newValue)

V oldValue, V newValue)

Comparing the two APIs, it's obvious to see that where possible JCache avoids returning the previous value
to avoid operations doing expensive network or IO operations. This is an overriding principle in the design of
JCache API. In fact, there's a set of operations that are present in
java.util.concurrent.ConcurrentMap, but are not present in the javax.cache.Cache because
they could be expensive to compute in a distributed cache. The only exception is iterating over the contents
of the cache:

JBoss Community Documentation

Page 391 of 617

Infinispan 6.0

Operation

java.util.concurrent.ConcurrentMap<K, javax.cache.Cache<K, V>


V>

calculate size of

int size()

cache
return all keys in the

Set<K> keySet()

cache
return all values in

Collection<V> values()

the cache
return all entries in

Set<Map.Entry<K, V>> entrySet()

the cache
iterate over the cache use iterator() method on keySet, values or
entrySet

Iterator<Cache.Entry<K,
V>> iterator()

3.68.5 Clustering JCache instances


Infinispan JCache implementation goes beyond the specification in order to provide the possibility to cluster
caches using the standard API. Given a Infinispan configuration file configured to replicate caches like this:

<?xml version="1.0" encoding="UTF-8"?>


<infinispan xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="urn:infinispan:config:5.3"
xsi:schemaLocation="urn:infinispan:config:5.3
http://www.infinispan.org/schemas/infinispan-config-5.3.xsd">
<global>
<transport
transportClass="org.infinispan.remoting.transport.jgroups.JGroupsTransport"
clusterName="jcache-cluster">
</transport>
</global>
<default />
<namedCache name="namedCache">
<clustering mode="replication" />
</namedCache>
</infinispan>

You can create a cluster of caches using this code:

JBoss Community Documentation

Page 392 of 617

Infinispan 6.0

import
import
import
import

javax.cache.Cache;
javax.cache.CacheManager;
javax.cache.Caching;
java.net.URI;

// For multiple cache managers to be constructed with the standard JCache API and live in the
same JVM, either their names, or their classloaders, must be different.
// This example shows how to force their classloaders to be different. An alternative method
would have been to duplicate the XML file and give it a different name,
// but this results in unnecessary file duplication.
ClassLoader tccl = Thread.currentThread().getContextClassLoader();
CacheManager cacheManager1 =
Caching.getCachingProvider().getCacheManager(URI.create("infinispan-jcache-cluster.xml"), new
TestClassLoader(tccl));
CacheManager cacheManager2 =
Caching.getCachingProvider().getCacheManager(URI.create("infinispan-jcache-cluster.xml"), new
TestClassLoader(tccl));
Cache<String, String> cache1 = cacheManager1.getCache("namedCache");
Cache<String, String> cache2 = cacheManager2.getCache("namedCache");
cache1.put("hello", "world");
String value = cache2.get("hello"); // Returns "world" if clustering is working
// -public static class TestClassLoader extends ClassLoader {
public TestClassLoader(ClassLoader parent) {
super(parent);
}
}

If using custom objects, make sure they are serializable/marshallable as per the instructions here.

3.68.6 Expire cached data


TODO

3.68.7 Annotations
TODO

3.68.8 Atomic compound operations on cache entry


TODO - invokeEntryProcessor

JBoss Community Documentation

Page 393 of 617

Infinispan 6.0

3.68.9 Using cache listeners


TODO

3.68.10 Quickstarts
TODO

3.69 Infinispan Server


3.69.1 Introduction
Infinispan Server is a standalone server which exposes any number of caches to clients over a variety of
protocols, including HotRod, Memcached and REST. The server itself is built on top of the robust foundation
provided by JBoss AS 7.2, therefore delegating services such as configuration, datasources, transactions,
logging and security to the respective subsystems. Because Infinispan Server is closely tied to the latest
releases of Infinispan and JGroups, the subsystems which control these components are slightly different, in
that they introduce new features and change some existing ones (e.g. cross-site replication, etc). For this
reason, the configuration of these subsystems should use the Infinispan Server-specific schema. See the
Configuration section for more information.

3.69.2 Protocols
Hot Rod
Hot Rod is Infinispan's own topology-aware high-performance remote protocol. See Hot Rod

Memcached
Memcached is a very popular caching server with its own protocol. See Memcached

Rest
Rest uses HTTP methods to perform operations on a cache. See Accessing data in Infinispan via RESTful
interface

WebSocket
The WebSocket protocol is a technology used to provide persistent bidirectional communication between
(but not limited to) a web browser and a server. See WebSocket Server

JBoss Community Documentation

Page 394 of 617

Infinispan 6.0

3.69.3 Getting Started


To get started using the server, download the Infinispan Server distribution, unpack it to a local directory and
launch it using the bin/standalone.sh or bin/standalone.bat scripts depending on your platform.
This will start a single-node server using the standalone/configuration/standalone.xml
configuration file, with four endpoints, one for each of the supported protocols. These endpoints allow access
to all of the caches configured in the Infinispan subsystem (apart from the Memcached endpoint which,
because of the protocol's design, only allows access to a single cache). The server also comes with a script
(clustered.sh/clustered.bat) which provides an easy way to start a clustered server by using the
standalone/configuration/clustered.xml configuration file. If you start the server in clustered
mode on multiple hosts, they should automatically discover each other using UDP multicast and form a
cluster. If you want to start multiple nodes on a single host, start each one by specifying a port offset using
the jboss.socket.binding.port-offset property together with a unique jboss.node.name as
follows:
bin/clustered.sh -Djboss.socket.binding.port-offset=100 -Djboss.node.name=nodeA
If, for some reason, you cannot use UDP multicast, you can use TCP discovery. Read the JGroups
subsystem configuration section for details on how to configure TCP discovery.
The server distribution also provides a set of example configuration files in the docs/examples/configs
which illustrate a variety of possible configurations and use-cases. To use them, just copy them to the
standalone/configuration directory and start the server using the following syntax:
bin/standalone.sh -c configuration_file_name.xml
For more information regarding the parameters supported by the startup scripts, refer to the JBoss AS 7.2
documentation on Command line parameters, bearing in mind that Infinispan Server does not currently
support managed servers, also known as domain mode.

3.69.4 CLI
The Infinispan CLI can be used to connect to the server. You need to use the remoting protocol and connect
to port 9999. By default the CLI will use the special silent SASL authenticator, which won't require a
username/password:

bin/ispn-cli.sh
[disconnected//]> connect localhost
[remoting://localhost:9999/local/]> cache default
[remoting://localhost:9999/local/default]> encoding hotrod
[remoting://localhost:9999/local/default]> put a a
[remoting://localhost:9999/local/default]> get a
a

JBoss Community Documentation

Page 395 of 617

Infinispan 6.0

3.69.5 Configuration
Since the server is based on the JBoss AS 7.2 codebase, it must configured be using the AS configuration
schema, apart from the JGroups, Infinispan and Endpoint subsytems.

JGroups subsystem configuration


The JGroups subsystem configures the network transport and is only required when clustering multiple
Infinispan Server nodes together.
The subsystem declaration is enclosed in the following XML element:

<subsystem xmlns="urn:jboss:domain:jgroups:1.2"
default-stack="${jboss.default.jgroups.stack:udp}">
...
</subsystem>

Within the subsystem, you need to declare the stacks that you wish to use and name them. The
default-stack attribute in the subsystem declaration must point to one of the declared stacks. You can switch
stacks from the command-line using the jboss.default.jgroups.stack property:
bin/clustered.sh -Djboss.default.jgroups.stack=tcp
A stack declaration is composed of a transport (UDP or TCP) followed by a list of protocols. For each of
these elements you can tune specific properties adding child <property
name="prop_name">prop_value</property> elements. Since the amount of protocols and their
configuration options in JGroups is huge, please refer to the appropriate JGroups Protocol documentation.
The following are the default stacks:

JBoss Community Documentation

Page 396 of 617

Infinispan 6.0

<stack name="udp">
<transport type="UDP" socket-binding="jgroups-udp"/>
<protocol type="PING"/>
<protocol type="MERGE2"/>
<protocol type="FD_SOCK" socket-binding="jgroups-udp-fd"/>
<protocol type="FD_ALL"/>
<protocol type="pbcast.NAKACK"/>
<protocol type="UNICAST2"/>
<protocol type="pbcast.STABLE"/>
<protocol type="pbcast.GMS"/>
<protocol type="UFC"/>
<protocol type="MFC"/>
<protocol type="FRAG2"/>
<protocol type="RSVP"/>
</stack>
<stack name="tcp">
<transport type="TCP" socket-binding="jgroups-tcp"/>
<protocol type="MPING" socket-binding="jgroups-mping"/>
<protocol type="MERGE2"/>
<protocol type="FD_SOCK" socket-binding="jgroups-tcp-fd"/>
<protocol type="FD"/>
<protocol type="VERIFY_SUSPECT"/>
<protocol type="pbcast.NAKACK">
<property name="use_mcast_xmit">false</property>
</protocol>
<protocol type="UNICAST2"/>
<protocol type="pbcast.STABLE"/>
<protocol type="pbcast.GMS"/>
<protocol type="UFC"/>
<protocol type="MFC"/>
<protocol type="FRAG2"/>
<protocol type="RSVP"/>
</stack>

The default TCP stack uses the MPING protocol for discovery, which uses UDP multicast. If you need to use
a different protocol, look at the JGroups Discovery Protocols. The following example stack configures the
TCPPING discovery protocol with two initial hosts:

JBoss Community Documentation

Page 397 of 617

Infinispan 6.0

<stack name="tcp">
<transport type="TCP" socket-binding="jgroups-tcp"/>
<protocol type="TCPPING">
<property name="initial_hosts">HostA[7800],HostB[7800]</property>
</protocol>
<protocol type="MERGE2"/>
<protocol type="FD_SOCK" socket-binding="jgroups-tcp-fd"/>
<protocol type="FD"/>
<protocol type="VERIFY_SUSPECT"/>
<protocol type="pbcast.NAKACK">
<property name="use_mcast_xmit">false</property>
</protocol>
<protocol type="UNICAST2"/>
<protocol type="pbcast.STABLE"/>
<protocol type="pbcast.GMS"/>
<protocol type="UFC"/>
<protocol type="MFC"/>
<protocol type="FRAG2"/>
<protocol type="RSVP"/>
</stack>

Infinispan subsystem configuration


The Infinispan subsystem configures the cache containers and caches. Its schema differs from the default
Infinispan library declarative because it needs to adhere to the application server standards, but the
underlying concepts are the same.
The subsystem declaration is enclosed in the following XML element:

<subsystem xmlns="urn:infinispan:server:core:5.2" default-cache-container="clustered">


...
</subsystem>

JBoss Community Documentation

Page 398 of 617

Infinispan 6.0

Containers
One major difference between the Infinispan library schema and the server schema is that in the latter
multiple containers can be declared. A container is declared as follows:

<cache-container name="clustered" default-cache="default">


...
</cache-container>

Another difference is the lack of an implicit default cache, but the ability to specify a named cache as the
default.
If you need to declare clustered caches (distributed, replicated, invalidation), you also need to specify the
<transport/> element which references an existing JGroups transport. This is not needed if you only
intend to have local caches only.

<transport executor="infinispan-transport" lock-timeout="60000" stack="udp"


cluster="my-cluster-name"/>

Caches
Now you can declare your caches. Please be aware that only the caches declared in the configuration will be
available to the endpoints and that attempting to access an undefined cache is an illegal operation. Contrast
this with the default Infinispan library behaviour where obtaining an undefined cache will implicitly create one
using the default settings. The following are example declarations for all four available types of caches:

<local-cache name="default" start="EAGER">


...
</local-cache>
<replicated-cache name="replcache" mode="SYNC" remote-timeout="30000" start="EAGER">
...
</replicated-cache>
<invalidation-cache name="invcache" mode="SYNC" remote-timeout="30000" start="EAGER">
...
</invalidation-cache>
<distributed-cache name="distcache" mode="SYNC" segments="20" owners="2" remote-timeout="30000"
start="EAGER">
...
</distributed-cache>

JBoss Community Documentation

Page 399 of 617

Infinispan 6.0

Expiration
To define a default expiration for entries in a cache, add the <expiration/> element as follows:

<expiration lifespan="2000" max-idle="1000"/>

The possible attributes for the expiration element are:


lifespan maximum lifespan of a cache entry, after which the entry is expired cluster-wide, in
milliseconds. -1 means the entries never expire.
max-idle maximum idle time a cache entry will be maintained in the cache, in milliseconds. If the idle
time is exceeded, the entry will be expired cluster-wide. -1 means the entries never expire.
interval interval (in milliseconds) between subsequent runs to purge expired entries from memory
and any cache stores. If you wish to disable the periodic eviction process altogether, set interval to -1.

Eviction
To define an eviction strategy for a cache, add the <eviction/> element as follows:

<eviction strategy="LIRS" max-entries="1000"/>

The possible attributes for the eviction element are:


strategy sets the cache eviction strategy. Available options are 'UNORDERED', 'FIFO', 'LRU', 'LIRS'
and 'NONE' (to disable eviction).
max-entries maximum number of entries in a cache instance. If selected value is not a power of two
the actual value will default to the least power of two larger than selected value. -1 means no limit.

JBoss Community Documentation

Page 400 of 617

Infinispan 6.0

Locking
To define the locking configuration for a cache, add the <locking/> element as follows:

<locking isolation="REPEATABLE_READ" acquire-timeout="30000" concurrency-level="1000"


striping="false"/>

The possible attributes for the locking element are:


isolation sets the cache locking isolation level. Can be NONE, READ_UNCOMMITTED,
READ_COMMITTED, REPEATABLE_READ, SERIALIZABLE. Defaults to REPEATABLE_READ
striping if true, a pool of shared locks is maintained for all entries that need to be locked. Otherwise,
a lock is created per entry in the cache. Lock striping helps control memory footprint but may reduce
concurrency in the system.
acquire-timeout maximum time to attempt a particular lock acquisition.
concurrency-level concurrency level for lock containers. Adjust this value according to the number of
concurrent threads interacting with Infinispan.
concurrent-updates for non-transactional caches only: if set to true(default value) the cache keeps
data consistent in the case of concurrent updates. For clustered caches this comes at the cost of an
additional RPC, so if you don't expect your application to write data concurrently, disabling this flag
increases performance.

Transactions
While it is possible to configure server caches to be transactional, none of the available protocols offer
transaction capabilities.

Loaders and Stores


TODO

Endpoint subsystem configuration


The endpoint subsystem exposes a whole container (or in the case of Memcached, a single cache) over a
specific connector protocol. You can define as many connector as you need, provided they bind on different
interfaces/ports.
The subsystem declaration is enclosed in the following XML element:

<subsystem xmlns="urn:infinispan:server:endpoint:5.3">
...
</subsystem>

JBoss Community Documentation

Page 401 of 617

Infinispan 6.0

HotRod
The following connector declaration enables a HotRod server using the hotrod socket binding (declared
within a <socket-binding-group /> element) and exposing the caches declared in the local container, using
defaults for all other settings.

<hotrod-connector socket-binding="hotrod" cache-container="local" />

The connector will create a supporting topology cache with default settings. If you wish to tune these settings
add the <topology-state-transfer /> child element to the connector as follows:

<hotrod-connector socket-binding="hotrod" cache-container="local">


<topology-state-transfer lazy-retrieval="false" lock-timeout="1000"
replication-timeout="5000" />
</hotrod-connector>

The HotRod connector can be further tuned with additional settings such as concurrency and buffering. See
the protocol connector settings paragraph for additional details
Furthermore the HotRod connector can be secured using SSL. First you need to declare an SSL server
identity within a security realm in the management section of the configuration file. The SSL server identity
should specify the path to a keystore and its secret. Refer to the AS7.2 documentation on this. Next add the
<security /> element to the HotRod connector as follows:

<hotrod-connector socket-binding="hotrod" cache-container="local">


<security ssl="true" security-realm="ApplicationRealm" require-ssl-client-auth="false" />
</hotrod-connector>

Memcached
The following connector declaration enables a Memcached server using the memcached socket binding
(declared within a <socket-binding-group /> element) and exposing the memcachedCache cache declared
in the local container, using defaults for all other settings. Because of limitations in the Memcached protocol,
only one cache can be exposed by a connector. If you wish to expose more than one cache, declare
additional memcached-connectors on different socket-bindings.

<memcached-connector socket-binding="memcached" cache-container="local"/>

WebSocket
<websocket-connector socket-binding="websocket" cache-container="local"/>

JBoss Community Documentation

Page 402 of 617

Infinispan 6.0

REST
The REST connector differs from the above connectors because it piggybacks on the web subsystem.
Therefore configurations such as socket binding, worker threads, timeouts, etc must be performed on the
web subsystem.

<rest-connector virtual-server="default-host" cache-container="local" security-domain="other"


auth-method="BASIC"/>

Common Protocol Connector Settings


The HotRod, Memcached and WebSocket protocol connectors support a number of tuning attributes in their
declaration:
worker-threads Sets the number of worker threads. Defaults to twice the number of available cores.
idle-timeout Specifies the maximum time in seconds that connections from client will be kept open
without activity. Defaults to -1 (connections will never timeout)
tcp-nodelay Affects TCP NODELAY on the TCP stack. Defaults to enabled.
send-buffer-size Sets the size of the send buffer. Defaults to
receive-buffer-size Sets the size of the receive buffer. Defaults to

Protocol Interoperability
By default each protocol stores data in the cache in the most efficient format for that protocol, so that no
transformations are required when retrieving entries. If instead you need to access the same data from
multiple protocols, you should enable compatibility mode on the caches that you want to share. This is done
by adding the <compatibility /> element to a cache definition, as follows:

<cache-container name="local" default-cache="default">


<local-cache name="default" start="EAGER">
<transaction mode="NONE"/>
<compatibility enabled="true"/>
</local-cache>
</cache-container>

JBoss Community Documentation

Page 403 of 617

Infinispan 6.0

3.69.6 Hot Rod Server


Introduction
Starting an Infinispan Hot Rod server
Predefining Hot Rod Caches

Introduction
Starting with version 4.1, Infinispan distribution contains a server module that implements Infinispan's
custom binary protocol called Hot Rod. The protocol was designed to enable faster client/server interactions
compared to other existing text based protocols and to allow clients to make more intelligent decisions with
regards to load balancing, failover and even data location operations.

Starting an Infinispan Hot Rod server


See the Infinispan Server page for details.

Predefining Hot Rod Caches


In order to provide a more consistent experience when interacting with Hot Rod servers and avoid issues
related to lazily started cache instances, on startup, Hot Rod server starts all defined caches in the Infinispan
configuration file including the default cache. Any request to an undefined cache will be rejected by the
server.
So, as user, this means that any caches you interact with must be defined in the Infinispan configuration file.
Besides, as explained the 'Cache Name' section of the Hot Rod protocol, you can also interact with the
default cache by passing an empty cache name.

3.69.7 Memcached Server


Introduction
Command Clarifications
Flush All
Unsupported Features
Individual Stats
Statistic Settings
Settings with Arguments Parameter
Delete Hold Time Parameter
Verbosity Command

Introduction
As of Infinispan 5.3, the supported way to start an Infinispan Memcached server is via the Infinispan Server.
This page details differences between the original Memcached server functionality and the Infinispan
implementation

JBoss Community Documentation

Page 404 of 617

Infinispan 6.0

Command Clarifications
Flush All
Even in a clustered environment, flush_all command leads to the clearing of the Infinispan Memcached
server where the call lands. There's no attempt to propagate this flush to other nodes in the cluster. This is
done so that flush_all with delay use case can be reproduced with the Infinispan Memcached server.
The aim of passing a delay to flush_all is so that different Memcached servers in a full can be flushed at
different times, and hence avoid overloading the database with requests as a result of all Memcached
servers being empty. For more info, check the Memcached text protocol section on flush_all.

JBoss Community Documentation

Page 405 of 617

Infinispan 6.0

Unsupported Features
This section explains those parts of the memcached text protocol that for one reason or the other, are not
currently supported by the Infinispan based memcached implementation.

Individual Stats
Due to difference in nature between the original memcached implementation which is C/C++ based and the
Infinispan implementation which is Java based, there're some general purpose stats that are not supported.
For these unsupported stats, Infinispan memcached server always returns 0.
Here's the list of currently unsupported stats:
pid
pointer_size
rusage_user
rusage_system
bytes
curr_connections
total_connections
connection_structures
auth_cmds
auth_errors
limit_maxbytes
threads
conn_yields
reclaimed

Statistic Settings
The settings statistics section of the text protocol has not been implemented due to its volatility.

Settings with Arguments Parameter


Since the arguments that can be send to the Memcached server are not documented, Infinispan
Memcached server does not support passing any arguments to stats command. If any parameters are
passed, the Infinispan Memcached server will respond with a CLIENT_ERROR.

Delete Hold Time Parameter


Memcached does no longer honor the optional hold time parameter to delete command and so the Infinispan
based memcached server does not implement such feature either.

Verbosity Command
Verbosity command is not supported since Infinispan logging cannot be simplified to defining the logging
level alone.

JBoss Community Documentation

Page 406 of 617

Infinispan 6.0

3.69.8 WebSocket Server


The Infinispan WebSocket Server can be used to expose an Infinispan Cache instance over a WebSocket
Interface via a very simple Javascript "Cache" API. The WebSocket Interface was introduced as part of the
HTML 5 specification. It defines a full-duplex communication channel to the browser, operating over a single
socket (unlike Comet or Ajax) and is exposed to the browser via a Javascript interface.
Starting The Server
Javascript API
Creating a Client-Side Cache Object Instance
Cache Operations
Sample code
Browser Support
Screencast
Status
Source

Starting The Server


See the Infinispan Server page for details.

Javascript API
Writing a web page that uses the Infinispan Cache API is trivial. The page simply needs to include a
<script> declaration for the infinispan-ws.js Javascript source file. This script is served up by
WebSocket Server.
So, for loading infinispan-ws.js from a WebSocket Server instance running on www.acme.com:8181
(default port):

<script type="text/javascript" src="<a href="http://www.acme.com:61999/infinispan-ws.js"


target="_blank">http://www.acme.com:8181/infinispan-ws.js</a>" />

JBoss Community Documentation

Page 407 of 617

Infinispan 6.0

Creating a Client-Side Cache Object Instance


The client-side interface to a server-side Infinispan cache is the Cache Javascript object. It can be
constructed as follows:

<script type="text/javascript">
var cache = new Cache();
// etc...
</script>

By default, the Cache instance will interface to the default Infinispan Cache associated with the WebSocket
Server from which the infinispan-ws.js Javascript source file was loaded. So, in the above case, the
Cache object instance will connect to the WebSocket Server running on www.acme.com:8181 (i.e.
ws://www.acme.com:8181).
The Infinispan Cache name and WebSocket Server address can be specified in the {{Cache} object
constructor as follows:

var cache = new Cache("omCache", "ws://ws.acmews.com:8181");


// etc...

JBoss Community Documentation

Page 408 of 617

Infinispan 6.0

Cache Operations
A number of cache operations can be performed via the Cache object instance such as get, put, remove,
notify and unnotify.
The get and notify operations require a callback function to be registered with the Cache object
instance. This callback function receives all add/update/remove notifications on any cache entries for which
the notify function was invoked. It also asynchronously receives the result of a single invocation of the
get function i.e. get can be thought of as "notify once, immediately".
The callback function is registered with the Cache object instance via the registerCallback function.
The function should have 2 parameters - key and value, relating to the cache key and value.

var cache = new Cache();


// Ask to be notified about some cache entries...
cache.notify("orderStatus");
cache.notify("expectedDeliveryTime");
// Register the callback function for receiving notifcations...
cache.registerCallback(cacheCallback);
// Cache callback function...
function cacheCallback(key, value) {
// Handle notification...
}

Getting and updating data in the cache is done by simply calling the get, put and remove functions on the
Cache object instance. These operations could be triggered by user interaction with a web form e.g.

<form onsubmit="return false;">


<!-- Other form components... -->
<!-- Buttons for making cache updates... -->
<input type="button" value="Put"
onclick="cache.put(this.form.key.value, this.form.val.value)" />
<input type="button" value="Get"
onclick="cache.get(this.form.key.value)" />
<input type="button" value="Remove"
onclick="cache.remove(this.form.key.value)" />
</form>

Sample code
Infinispan's source tree contains a sample HTML document that makes use of the WebSocket server.
Browse through the source of this HTML document here.

JBoss Community Documentation

Page 409 of 617

Infinispan 6.0

Browser Support
At the time of writing, Google Chrome was the only browser with native WebSocket support. However, the
jWebSocket project provides a client side Javascript library that adds WebSocket support to any Flash
enabled browser.

Screencast
See the following demo of the Infinispan WebSocket Server in action.

Status
Prototype/Alpha.

Source
Browse Infinispan's Git repository.

3.70 Storing objects (e.g. arrays) with custom


Equivalence functions
The Problem of Caching Arrays
Old workaround: Wrapper Classes
New solution: Plugging Equivalence functions
Configuring Equivalence functions
Using XML
Using Programmatic Configuration
Byte array storage example
Other methods in Equivalence interface

3.70.1 The Problem of Caching Arrays


There are times when users want to store data into Infinispan caches whose default equals() and/or
hashCode() implementations produce undesirable results. One of those data types are arrays. When users
want to store arrays into Infinispan caches, the big majority of users want equals() function to be
calculated based on the contents of the arrays as opposed to comparing the object reference, so if we take
byte arrays are example, users would like to call up the static java.util.Arrays.equals(byte[],
byte[]) method instead of Object.equals(). The same thing happens with hashCode(). The default
implementation of Object.hashCode() for arrays suffers from the same issue, because the result is not
produced based on the contents of the array, but rather based on the object reference to the array.

JBoss Community Documentation

Page 410 of 617

Infinispan 6.0

3.70.2 Old workaround: Wrapper Classes


Until Infinispan 5.2, the way to get around these issues was by wrapping arrays, or any other object whose
equals()/hashCode() implementations are not best suited for being stored in Infinispan caches, around
another object which would override Object.equals() and Object.hashCode() to do the correct
calculations. This is where classes such as ByteArrayKey originate:

public final class ByteArrayKey implements Serializable {


private final byte[] data;
private final int hashCode;
public ByteArrayKey(byte[] data) {
this.data = data;
this.hashCode = 41 + Arrays.hashCode(data);
}
public byte[] getData() {
return data;
}
@Override
public boolean equals(Object obj) {
if (this == obj) return true;
if (obj == null || ByteArrayKey.class != obj.getClass()) return false;
ByteArrayKey key = (ByteArrayKey) obj;
return Arrays.equals(key.data, this.data);
}
@Override
public int hashCode() {
return hashCode;
}
@Override
public String toString() {
return new StringBuilder().append("ByteArrayKey").append("{")
.append("data=").append(Util.printArray(data, true))
.append("}").toString();
}
}

The problem with these classes is that they result in extra memory consumption due to the extra objects
required to support data types such as arrays and really, these classes just a workaround for the lack of
ability to provide a way to pass in a function that specifies how two byte arrays are are compared, or how to
calculate the hash code of a given array.

JBoss Community Documentation

Page 411 of 617

Infinispan 6.0

3.70.3 New solution: Plugging Equivalence functions


Starting with Infinispan 5.3, Infinispan users can provide these functions for both keys and values
implementing the new Equivalence<T> interface:

public interface Equivalence<T> extends Serializable {


/**
* Returns a hash code value for the object passed.
*
* As an example, implementors can provide an alternative implementation
* for the hash code calculation for arrays. So, instead of relying on
* {@link Object#hashCode()}, call {@link java.util.Arrays.hashCode()}.
*
* @param obj instance to calculate hash code for
* @return a hash code value for the object passed as parameter
*/
int hashCode(Object obj);
/**
* Indicates whether the objects passed are "equal to" each other.
*
* As an example, implementors can provide an alternative implementation
* for the equals for arrays. So, instead of relying on
* {@link Object#equals(Object)}}, call {@link java.util.Arrays.equals())}.
*
* @param obj to be compared with second parameter
* @param otherObj to be compared with first parameter
* @return <code>true</code> if both objects are the same;
*
<code>false</code> otherwise
*/
boolean equals(T obj, Object otherObj);
/**
* Returns a string representation of the given object.
*
* @param obj whose string representation is to be returned
* @return a string representation of the passed object
*/
String toString(Object obj);
/**
* Returns whether the given object is comparable. In other words, if
* given an instance of the object, a sensible comparison can be computed
* using {@link #compare(Object, Object)} method.
*
* @param obj instance to check if it's comparable
* @return <code>true</code> if the object is comparable;
*
<code>false</code> otherwise
*/
boolean isComparable(Object obj); // For future support for objects that are not comparable,
i.e. arrays
/**

JBoss Community Documentation

Page 412 of 617

Infinispan 6.0
* Compares the two given objects for order. Returns a negative integer,
* zero, or a positive integer as the first object is less than, equal to,
* or greater than the second object.
*
* @param obj first object to be compared
* @param otherObj second object to be compared
* @return a negative integer, zero, or a positive integer as the
*
first object is less than, equal to, or greater than the
*
second object
*/
int compare(Object obj, Object otherObj); // For future support for objects that are not
comparable, i.e. arrays
}

Implementations of these function can be pretty flexible. On one side, they could focus on a single, particular
type, such as ByteArrayEquivalence below which expects nothing else other than byte arrays, such as
in the case of Hot Rod based Infinispan remote caches:

package com.acme;
public class ByteArrayEquivalence implements Equivalence<byte[]> {
public static final Equivalence<byte[]> INSTANCE = new ByteArrayEquivalence();
@Override
public int hashCode(Object obj) {
return 41 + Arrays.hashCode((byte[]) obj);
}
@Override
public boolean equals(byte[] obj, Object otherObj) {
if (obj == otherObj) return true;
if (obj == null) return false;
if (otherObj == null || byte[].class != otherObj.getClass()) return false;
byte[] otherByteArray = (byte[]) otherObj;
return Arrays.equals(obj, otherByteArray);
}
@Override
public String toString(Object obj) {
return Arrays.toString((byte[]) obj);
}
@Override
public boolean isComparable(Object obj) {
return false;
}
@Override
public int compare(Object obj, Object otherObj) {
return 0; // irrelevant
}
}

JBoss Community Documentation

Page 413 of 617

Infinispan 6.0
Or you could have implementations that support multiple different types, in case you store varied
information, for example AnyServerEquivalence which supports both arrays and normal objects:

public class AnyServerEquivalence implements Equivalence<Object> {


private static boolean isByteArray(Object obj) {
return byte[].class == obj.getClass();
}
@Override
public int hashCode(Object obj) {
if (isByteArray(obj)) {
return 41 + Arrays.hashCode((byte[]) obj);
} else {
return obj.hashCode();
}
}
@Override
public boolean equals(Object obj, Object otherObj) {
if (obj == otherObj)
return true;
if (obj == null || otherObj == null)
return false;
if (isByteArray(obj) && isByteArray(otherObj))
return Arrays.equals((byte[]) obj, (byte[]) otherObj);
return obj.equals(otherObj);
}
@Override
public String toString(Object obj) {
if (isByteArray(obj))
return Arrays.toString((byte[]) obj);
else
return obj.toString();
}
@Override
public boolean isComparable(Object obj) {
return obj instanceof Comparable;
}
@Override
@SuppressWarnings("unchecked")
public int compare(Object obj, Object otherObj) {
return ((Comparable<Object>) obj).compareTo(otherObj);
}
}

JBoss Community Documentation

Page 414 of 617

Infinispan 6.0

Configuring Equivalence functions


Using XML
The way to configure Infinispan with these Equivalence implementations is by adding them to the
<dataContainer> XML element. For example, if we wanted to have byte array based keys, but the values
would be normal objects, we'd define:

<dataContainer keyEquivalence="com.acme.ByteArrayEquivalence" />

If you were trying to store both byte arrays as keys and values, you'd configure valueEquivalence
attribute in <dataContainer> XML element:

<dataContainer keyEquivalence="com.acme.ByteArrayEquivalence"
valueEquivalence="com.acme.ByteArrayEquivalence" />

If no key or value equivalence is configured, they default to org.infinispan.util.AnyEquivalence,


which behaves like any standard java object, delegating the equals/hashCode() calls to the objects
themselves.

Using Programmatic Configuration


Key and/or value equivalence could also have been configured programmatically, for example:

EmbeddedCacheManager cacheManager = ...;


ConfigurationBuilder builder = new ConfigurationBuilder();
builder.dataContainer()
.keyEquivalence(com.acme.ByteArrayEquivalence.INSTANCE)
.valueEquivalence(com.acme.ByteArrayEquivalence.INSTANCE);
cacheManager.defineConfiguration("myCache", builder.build());

Byte array storage example


Assuming you've configured both keyEquivalence (via XML, or programmatically) to be
com.acme.ByteArrayEquivalence, you should now be able to write code like this and get the assertion
to succeed. If keyEquivalence has not been configured correctly, this test will fail:

Cache<byte[], byte[]> cache = ...


byte[] key = {1, 2, 3};
byte[] value = {4, 5, 6};
cache.put(key, value);
byte[] expectedValue = {4, 5, 6};
byte[] lookupKey = {1, 2, 3};
assert Arrays.equals(expectedValue, cache.get(lookupKey));

JBoss Community Documentation

Page 415 of 617

Infinispan 6.0

Other methods in Equivalence interface


Finally, Equivalence defines some extra methods, such as toString(Object obj),
isComparable(Object obj) and compare(Object obj, Object otherObj), which again can be
used to provide different implementations to the ones provided for the JDK. For example, the toString()
method can be used to provide a different String representation of the object, which is again useful for arrays
since the default JDK implementation does not print the array contents. The comparable functions are not
yet used by Infinispan but they've been defined in order to help with potential future support of tree-based
storage in inner data structures.

3.71 Interoperability between Embedded and Remote


Server Endpoints
Enable Compatibility Mode
Optional: Configuring Compatibility Marshaller
Code examples
Infinispan offers the possibility to store and retrieve data in a local, embedded way, and also remotely thanks
to the multiple endpoints offered, but until now if you choose one way to access the data, you were stuck
with it. For example, you could not store data using the embedded interface and retrieve it via REST.
Starting with Infinispan 5.3, it is now possible to configure Infinispan caches to work in a special,
compatibility mode for those users interested in accessing Infinispan in multiple ways. Achieving such
compatibility requires extra work from Infinispan in order to make sure that contents are converted back and
forth between the different formats of each endpoint and this is the reason why compatibility mode is
disabled by default.

3.71.1 Enable Compatibility Mode


For compatibility mode to work as expected, all endpoints need to be configured with the same cache
manager, and need to talk to the same cache. If you're using the brand new Infinispan Server distribution,
this is all done for you. If you're in the mood to experiment with this in a standalone unit test, this class
shows you how you can start multiple endpoints from a single class.
So, to get started using Infinispan's compatibility mode, it needs to be enabled, either via XML:

<namedCache...>
<compatibility enabled="true"/>
</namedCache>

Or programmatically:

JBoss Community Documentation

Page 416 of 617

Infinispan 6.0

ConfigurationBuilder builder = ...


builder.compatibility().enable();

The key thing to remember about Infinispan's compatibility mode is that where possible, it tries to store data
unmarshalling or deserializing it. It does so because the most common use case is for it to store Java
objects and having Java objects stored in deserialized form means that they're very easy to use from an
embedded cache. With this in mind, it makes some assumptions. For example, if something it's stored via
Hot Rod, it's most likely coming from the reference Hot Rod client, which is written in Java, and which uses a
marshaller that keeps binary payloads very compact. So, when the Hot Rod operation reaches the
compatibility layer, it will try to unmarshall it, by default using the same default marshaller used by the Java
Hot Rod client, hence providing good out-of-the-box support for the majority of cases.

Optional: Configuring Compatibility Marshaller


It could happen though the client might be using a Hot Rod client written for another language other than
Java, say Ruby or Python. In this case, some some kind of custom marshaller needs to be configured that
either translates that serialized payload into a Java object to be stored in the cache, or keeps it in serialized
form. Both options are valid, but of course it will have an impact on what kind of objects are retrieved from
Infinispan if using the embedded cache. The marshaller is expected to implement this interface. Configuring
the compatibility marshaller is optional and can be done via XML:

<namedCache...>
<compatibility enabled="true" marshallerClass="com.acme.CustomMarshaller"/>
</namedCache>

Or programmatically:

ConfigurationBuilder builder = ...


builder.compatibility().enable().marshaller(new com.acme.CustomMarshaller());

One concrete example of this marshaller logic can be found in the SpyMemcachedCompatibleMarshaller.
Spy Memcached uses their own transcoders in order to marshall objects, so the compatibility marshaller
created is in charge of marshalling/unmarshalling data stored via Spy Memcached client. If you want to
retrieve data stored via Spy Memcached via say Hot Rod, you can configure the Java Hot Rod client to use
this same marshaller, and this is precisely what the test where the Spy Memcached marshaller is located is
demonstrating.

3.71.2 Code examples


The best code examples available showing compatibility in action can be found in the Infinispan
Compatibility Mode testsuite, but more will be developed in the near future.

JBoss Community Documentation

Page 417 of 617

Infinispan 6.0

3.72 Infinispan for HTTP session clustering and caching


One popular use case for data grids is to cache and cluster HTTP sessions in servlet containers. This
provides servlet containers and Java EE application servers with the following features:
Fast access to HTTP sessions, as they're cached in memory
Distribution of HTTP sessions across a cluster. Allows for failover and high availability between
servlet container or app server nodes.

3.72.1 JBoss AS and WildFly


JBoss AS and WildFly already use Infinispan for HTTP session caching and clustering.

3.72.2 Jetty
Jetty can be set up to use Infinispan for HTTP session management, using this adapter.

3.72.3 Other application servers and servlet containers


Creating plugins for other servlet containers and app servers should be easy enough, following the pattern
used by JBossAS/WildFly/Jetty above. Please see the open tasks below, contributions accepted!
ISPN-462 HTTP and EJB session management for WebSphere
ISPN-463 HTTP and EJB session management for WebLogic
ISPN-464 HTTP and EJB session management for Glassfish
ISPN-465 HTTP session management for Tomcat

JBoss Community Documentation

Page 418 of 617

Infinispan 6.0

3.73 Design of data versioning in Infinispan

JBoss Community Documentation

Page 419 of 617

Infinispan 6.0

3.73.1 Overview
Infinispan will offer three forms of data versioning, including simple, partition aware and external. Each case
is described in detail below.

Simple versioning
The purpose of simple versioning is to provide a reliable mechanism of write skew checks when using
optimistic transactions, REPEATABLE_READ and a clustered cache. Write skew checks are performed at
prepare-time to ensure a concurrent transaction hasn't modified an entry while it was read and potentially
updated based on the value read.
When operating in LOCAL mode, write skew checks rely on Java object references to compare differences
and this is adequate to provide a reliable write-skew check, however this technique is useless in a cluster
and a more reliable form of versioning is necessary to provide reliable write skew checks.
Simple versioning is an implementation of the proposed EntryVersion interface, backed by a long that is
incremented each time the entry is updated.

Partition-aware versioning
This versioning scheme makes use of vector clocks to provide a network partition resilient form of
versioning.
Unlike simple versioning, which is maintained per entry, a vector clock's node counter is maintained
per-node.

External versioning
This scheme is used to encapsulate an external source of data versioning within Infinispan, such as when
using Infinispan with Hibernate which in turn gets it's data version information directly from a database.
In this scheme, a mechanism to pass in the version becomes necessary, and overloaded versions of put()
and putForExternalRead() will be provided in AdvancedCache to take in an external data version. This
is then stored on the InvocationContext and applied to the entry at commit time.
Write skew checks cannot and will not be performed in the case of external data versioning.

Tombstones
To deal with deletions of entries, tombstones will be maintained as null entries that have been deleted, so
that version information of the deleted entry can be maintained and write skews can still be detected.
However this is an expensive thing to do, and as such, is a configuration option, disabled by default. Further,
tombstones will follow a strict lifespan and will be cleared from the system after a specific amount of time.

JBoss Community Documentation

Page 420 of 617

Infinispan 6.0

3.73.2 Configuration
By default versioning will be disabled. This will mean write skew checks when using transactions and
REPEATABLE_READ as an isolation level will be unreliable when used in a cluster. Note that this doesn't
affect single-node, LOCAL mode usage.

Via XML
<versioning enabled="false" type="SIMPLE|PARTITION_AWARE|EXTERNAL" useTombstones="false"
tombstoneLifespan="60000"/>

Via the programmatic API


fluent().versioning().type(SIMPLE).useTombstones(true).tombstoneLifespan(1, TimeUnit.MINUTES);

JBoss Community Documentation

Page 421 of 617

Infinispan 6.0

3.74 Infinispan modules for JBoss AS 7.x


Since Infinispan 5.2, the distribution includes a set of modules for JBoss AS 7.x. By installing these modules,
it is possible to deploy user applications without packaging the Infinispan JARs within the deployments
(WARs, EARs, etc), thus minimizing their size. In order not to conflict with the Infinispan modules which are
already present within an AS installation, the modules provided by the Infinispan distribution are located
within their own slot identified by the major.minor versions (e.g. slot="5.2").
In order to tell the AS deployer that we want to use the Infinispan APIs within our application, we need to add
explicit dependencies to the deployment's MANIFEST:
MANIFEST.MF
Manifest-Version: 1.0
Dependencies: org.infinispan:5.2 services

If you are using Maven to generate your artifacts, mark the Infinispan dependencies as provided and
configure your artifact archiver to generate the appropriate MANIFEST.MF file:
pom.xml
<dependencies>
<dependency>
<groupId>org.infinispan</groupId>
<artifactId>infinispan-core</artifactId>
<version>5.2.0.Final</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.infinispan</groupId>
<artifactId>infinispan-cachestore-jdbc</artifactId>
<version>5.2.0.Final</version>
<scope>provided</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<configuration>
<archive>
<manifestEntries>
<Dependencies>org.infinispan:5.2 services, org.infinispan.cachestore.jdbc:5.2
services</Dependencies>
</manifestEntries>
</archive>
</configuration>
</plugin>
</plugins>
</build>

JBoss Community Documentation

Page 422 of 617

Infinispan 6.0

3.75 Infinispan with Groovy


3.75.1 Introduction
The idea by this tutorial is to give an introduction in the use of the Infinispan API and its configuration file. As
trying to do it in a more interactive fashion, the tutorial makes use of the Groovy dynamic language that will
allow to interact with the API by using a console. So your first task should be to create the necessary
environment to execute this tutorial, you can find the instructions here.
The tutorial will start by showing the basic usage of the Infinispan API and a use of a simple cache
configuration, then it will walk through different configuration scenarios and use cases. By the end of the
tutorial you should have a clear understanding of the use the Infinispan API and some of the various
configuration options.
The scenarios and use cases shown are:
Basic cache configuration
Cache with transaction management configuration
Cache with a cache store configuration
Cache with eviction configuration
Cache with eviction and cache store configuration
Cache with REPL_SYNC & transaction management configuration.
All the sample configurations are in the sample-configurations.xml file attached to this tutorial, check the
environment configuration to know how to make use of this configuration file. Lets get started:
NOTE: This document is part of the Infinispan Interactive Tutorial

Introduction
The Infinispan tutorial makes use of Groovy to get a more interactive experience when starting to learn about
how to use the Infinispan API. So you will need to install a few prerequisites before getting started:
The Groovy Platform, I used Groovy 1.6.3
Java and Infinispan
Download those and extract/install where you feel appropriate, depending on your operating system and
personal preferences you will either have installers or compressed distributions. You can read more about
read installing Java and Infinispan in Installing Infinispan for the tutorials.

JBoss Community Documentation

Page 423 of 617

Infinispan 6.0

Installing Groovy
You can use the installer or compressed file to install the Groovy Platform, I used the compressed file and
decompressed at C:\Program Files\groovy\groovy-1.6.3. Once you have installed the Groovy Platform you
should set some environment variables:

GROOVY_HOME=C:\Program Files\groovy\groovy-1.6.3

and add to the PATH environment variable:

PATH=%PATH%;%GROOVY_HOME%\bin

test that everything is correct by executing in a Command Shell/Terminal the commands shown:

$> groovy -v
Groovy Version: 1.6.3 JVM: 1.6.0_14

If you get a similar result as shown, everything went well.

Installing Infinispan
Now you should add the Infinispan libraries to the Groovy Platform so you will able to access the API from
the Groovy console. Add the infinispan-core.jar and its dependencies to the $USER_HOME/.groovy/lib
directory, the jar is located in $INFINISPAN_HOME/modules/core and the dependencies at
$INIFINISPAN_HOME/modules/core/lib.
For example, on Windows, you need to copy it to:

C:\Documents and Settings\Alejandro Montenegro\.groovy\lib

or on Linux:

/home/amontenegro/.groovy/lib

and $INFINISPAN_HOME is where you decompressed the Infinispan distribution.


To test the installation, download the attached file infinispantest.groovy and in a Command Shell/Terminal
execute

$> groovy infinispantest


4.0.0.ALPHA5

JBoss Community Documentation

Page 424 of 617

Infinispan 6.0

Setting the classpath


The last thing to do is to add to the CLASSPATH environment variable the sample configuration file, this file
contains definitions of cache's that will be used in the tutorial. I created the directory
$USER_HOME/.groovy/cp and added it to the classpath
For example, on Windows:

CLASSPATH=%CLASSPATH%;C:\Documents and Settings\Alejandro Montenegro\.groovy\cp

or, on Linux:

CLASSPATH=$CLASSPATH:/home/amontenegro/.groovy/cp

finally add the sample-configurations.xml and infinispan-config-4.0.xsd files(attached) to the directory.

JBoss Community Documentation

Page 425 of 617

Infinispan 6.0

3.75.2 Loading the configuration file


The cache manager is the responsible to manage all the cache's, so you have to start by indicating where to
get the cache definitions to the cache manager, remember that the cache definitions are in the
sample-configurations.xml file. If no cache definitions are indicated, the cache manager will use a default
cache.
Start by open a groovy console by typing groovy.sh in a command shell or terminal. You should now have
something similar to:

Groovy Shell (1.6.3, JVM: 1.6.0_14)


Type 'help' or '\h' for help.
------------------------------------------------------groovy:000>

It's time to start typing some commands, first start by importing the necessary libraries

groovy:000> import org.infinispan.*


===> [import org.infinispan.*]
groovy:000> import org.infinispan.manager.*
===> [import org.infinispan.*, import org.infinispan.manager.*]

And now, create a cache manager indicating the file with the cache definitions.

groovy:000> manager = new DefaultCacheManager("sample-configurations.xml")


===> org.infinispan.manager.DefaultCacheManager@19cc1b@Address:null

the cache manager has now the knowledge of all the named caches defined in the configuration file and also
has a no named cache that's used by default. You can now access any of the cache's by interacting with the
cache manager as shown.

groovy:000> defaultCache = manager.getCache()


===> Cache 'org.infinispan.manager.DefaultCacheManager.DEFAULT_CACHE_NAME'@7359733
//TO GET A NAMED CACHE
groovy:000> cache = manager.getCache("NameOfCache")

3.75.3 Basic cache configuration


The basic configuration, is the simplest configuration that you can have, its make use of default settings for
the properties of the cache configuration, the only thing you have to set is the name of the cache.

<namedCache name="Local"/>

JBoss Community Documentation

Page 426 of 617

Infinispan 6.0
That's all you have to add to the configuration file to have a simple named cache, now its time to interact
with the cache by using the Infinispan API. Lets start by getting the named cache and put some objects
inside it.

//START BY GETTING A REFERENCE TO THE NAMED CACHE


groovy:000> localCache = manager.getCache("Local")
===> Cache 'Local'@19521418
//THE INITIAL SIZE IS 0
groovy:000> localCache.size()
===> 0
//NOW PUT AN OBJECT INSIDE THE CACHE
groovy:000> localCache.put("aKey", "aValue")
===> null
//NOW THE SIZE IS 1
groovy:000> localCache.size()
===> 1
//CHECK IF IT HAS OUR OBJECT
groovy:000> localCache.containsKey("aKey")
===> true
//BY OBTAINING AN OBJECT DOESN'T MEAN TO REMOVE
groovy:000> localCache.get("aKey")
===> aValue
groovy:000> localCache.size()
===> 1
//TO REMOVE ASK IT EXPLICITLY
groovy:000> localCache.remove("aKey")
===> aValue
groovy:000> localCache.isEmpty()
===> true

So you have seen the basic of the Infinispan API, adding, getting and removing from the cache, there is
more, but don't forget that you are working with a cache that are an extension of java.util.ConcurrentHasMap
and the rest of the API is as simple as the one shown above, many of the cool things in Infinispan are totally
transparent (that's actually the coolest thing about Infinispan) and depends only on the configuration of your
cache.
If you check the Infinispan JavaDoc you will see that the Cache#put() method has been overridden several
times.

JBoss Community Documentation

Page 427 of 617

Infinispan 6.0

//YOU WILL NEED TO IMPORT ANOTHER LIBRARY


groovy:000> import java.util.concurrent.TimeUnit
===> [import org.infinispan.*, import org.infinispan.manager.*, import
java.util.concurrent.TimeUnit]
//NOTHING NEW HERE JUST PUTTING A NEW OBJECT
groovy:000> localCache.put("bKey", "bValue")
===> null
//WOW! WHATS HAPPEN HERE? PUTTED A NEW OBJECT BUT IT WILL TIMEOUT AFTER A SECOND
groovy:000> localCache.put("timedKey", "timedValue", 1000, TimeUnit.MILLISECONDS)
===> null
//LETS CHECK THE SIZE
groovy:000> localCache.size()
===> 2
//NOW TRY TO GET THE OBJECT, OOPS ITS GONE! (IF NOT, IT'S BECAUSE YOU ARE A SUPERTYPER, CALL
GUINNESS!))
groovy:000> localCache.get("timedKey")
===> null
//LETS CHECK THE SIZE AGAIN, AS EXPECTED THE SIZE DECREASED BY 1
groovy:000> localCache.size()
===> 1

The Infinispan API also allows you to manage the life cycle of the cache, you can stop and start a cache but
by default you will loose the content of the cache except if you configure a cache store, more about that later
in the tutorial. lets check what happens when you restart the cache

groovy:000> localCache.size()
===> 1
//RESTARTING CACHE
groovy:000> localCache.stop()
===> null
groovy:000> localCache.start()
===> null
//DAMN! LOST THE CONTENT OF THE CACHE
groovy:000> localCache.size()
===> 0

Thats all related to the use of the Infinispan API, now lets check some different behaviors depending on the
configuration of the cache.

3.75.4 Cache with transaction management


You are able to specify the cache to use a transaction manager, and even explicitly control the transactions.
Start by configuring the cache to use a specific TransactionManagerLookup class. Infinispan implements a
couple TransactionManagerLookup classes.
org.infinispan.transaction.lookup.DummyTransactionManagerLookup
org.infinispan.transaction.lookup.GenericTransactionManagerLookup
org.infinispan.transaction.lookup.JBossStandaloneJTAManagerLookup
org.infinispan.transaction.lookup.JBossTransactionManagerLookup

JBoss Community Documentation

Page 428 of 617

Infinispan 6.0
Each use different methods to lookup the transaction manager, depending on the environment you are
running Infinispan you should figure out which one to use. Check the JavaDoc for more details.
For the tutorial its enough to use:

<namedCache name="LocalTX">
<transaction
transactionManagerLookupClass="org.infinispan.transaction.lookup.DummyTransactionManagerLookup"/></namedCache>

Lets check how to interact with the Transaction Manager and to have the control over a transaction

groovy:000> import javax.transaction.TransactionManager


===> [import org.infinispan.*, import org.infinispan.manager.*, import
java.util.concurrent.TimeUnit, import javax.transaction.TransactionManager]
//GET A REFERENCE TO THE CACHE WITH TRANSACTION MANAGER
groovy:000> localTxCache = manager.getCache("LocalTX")
===> Cache 'LocalTX'@16075230
groovy:000> cr = localTxCache.getComponentRegistry()
===> org.infinispan.factories.ComponentRegistry@87e9bf
//GET A REFERENCE TO THE TRANSACTION MANAGER
groovy:000> tm = cr.getComponent(TransactionManager.class)
===> org.infinispan.transaction.tm.DummyTransactionManager@b5d05b
//STARTING A NEW TRANSACTION
groovy:000> tm.begin()
===> null
//PUTTING SOME OBJECTS INSIDE THE CACHE
groovy:000> localTxCache.put("key1", "value1")
===> null
//MMM SIZE DOESN'T INCREMENT
groovy:000> localTxCache.size()
===> 1
//LETS TRY AGAIN
groovy:000> localTxCache.put("key2", "value2")
===> null
//MMM NOTHING..
groovy:000> localTxCache.size()
===> 2
//OH! HAS TO DO THE COMMIT
groovy:000> tm.commit()
===> null
//AND THE SIZE IS AS EXPECTED.. HAPPY!
groovy:000> localTxCache.size()
===> 2

As shown in the example, the transaction is controlled explicitly and the changes in the cache wont be
reflected until you make the commit.

JBoss Community Documentation

Page 429 of 617

Infinispan 6.0

3.75.5 Cache with a cache store


Infinispan allows you to configure a persistent store that can be used to persist the content of the cache, so if
the cache is restarted the cache will be able to keep the content. It can also be used if you want to limit the
size of the cache, then the cache will start putting the objects in the store to keep the size limit, more on that
when looking at the eviction configuration.
Infinispan provides several cache store implementations:
FileCacheStore
JdbcBinaryCacheStore
JdbcMixedCacheStore
JdbcStringBasedCacheStore
JdbmCacheStore
S3CacheStore
BdbjeCacheStore
The tutorial uses the FileCacheStore, that saves the objects in files in a configured directory, in this case the
/tmp directory. If the directory is not set it defaults to Infinispan-FileCacheStore in the current working
directory.

<namedCache name="CacheStore">
<loaders passivation="false" shared="false" preload="true">
<loader class="org.infinispan.loaders.file.FileCacheStore" fetchPersistentState="true"
ignoreModifications="false" purgeOnStartup="false">
<properties>
<property name="location" value="/tmp"/>
</properties>
</loader>
</loaders>
</namedCache>

Now you have a cache with persistent store, lets try it to see how it works

JBoss Community Documentation

Page 430 of 617

Infinispan 6.0

//GETTING THE NEW CACHE


groovy:000> cacheCS = manager.getCache("CacheStore")
===> Cache 'CacheStore'@23240342
//LETS PUT AN OBJECT INSIDE THE CACHE
groovy:000> cacheCS.put("storedKey", "storedValue")
===> null
//LETS PUT THE SAME OBJECT IN OUR BASIC CACHE
groovy:000> localCache.put("storedKey", "storedValue")
===> storedValue
//RESTART BOTH CACHES
groovy:000> cacheCS.stop()
===> null
groovy:000> localCache.stop()
===> null
groovy:000> cacheCS.start()
===> null
groovy:000> localCache.start()
===> null
//LETS TRY GET THE OBJECT FROM THE RESTARTED BASIC CACHE.. NO LUCK
groovy:000> localCache.get("storedKey")
===> null
//INTERESTING CACHE SIZE IS NOT CERO
groovy:000> cacheCS.size()
===> 1
//WOW! JUST RESTARTED THE CACHE AND THE OBKECT KEEPS STAYING THERE!
groovy:000> cacheCS.get("storedKey")
===> storedValue

JBoss Community Documentation

Page 431 of 617

Infinispan 6.0

3.75.6 Cache with eviction


The eviction allow to define policy for removing objects from the cache when it reach its limit, as the true is
that the caches doesn't has unlimited size because of many reasons. So the fact is that you normally will set
a maximum number of objects in the cache and when that number is reached then the cache has to decide
what to do when a new object is added. That's the whole story about eviction, to define the policy of
removing object when the cache is full and want to keep putting objects. You have three eviction strategies:
NONE
FIFO
LRU
Let check the configuration of the cache:

<namedCache name="Eviction">
<eviction wakeUpInterval="500" maxEntries="2" strategy="FIFO"/>
</namedCache>

The strategy has been set to FIFO, so the oldest objects will be removed first and the maximum number of
objects are only 2, so it will be easy to show how it works

//GETTING THE NEW CACHE


groovy:000> evictionCache = manager.getCache("Eviction")
===> Cache 'Eviction'@5132526
//PUT SOME OBJECTS
groovy:000> evictionCache.put("key1", "value1")
===> null
groovy:000> evictionCache.put("key2", "value2")
===> null
groovy:000> evictionCache.put("key3", "value3")
===> null
//HEY! JUST LOST AN OBJECT IN MY CACHE.. RIGHT, THE SIZE IS ONLY TWO
groovy:000> evictionCache.size()
===> 2
//LETS CHECK WHAT OBJECT WAS REMOVED
groovy:000> evictionCache.get("key3")
===> value3
groovy:000> evictionCache.get("key2")
===> value2
//COOL! THE OLDEST WAS REMOVED
groovy:000> evictionCache.get("key1")
===> null

Now you are sure that your cache wont consume all your memory and hang your system, but its an
expensive price you have to pay for it, you are loosing objects in your cache. The good news is that you can
mix cache store with the eviction policy and avoid loosing objects.

JBoss Community Documentation

Page 432 of 617

Infinispan 6.0

3.75.7 Cache with eviction and cache store


Ok, the cache has a limited size but you don't want to loose your objects in the cache. Infinispan is aware of
these issues, so it makes it very simple for you combing the cache store with the eviction policy. When the
cache is full it will persist an object and remove it from the cache, but if you want to recover an object that
has been persisted the the cache transparently will bring it to you from the cache store.
The configuration is simple, just combine eviction and cache store configuration

<namedCache name="CacheStoreEviction">
<loaders passivation="false" shared="false" preload="true">
<loader class="org.infinispan.loaders.file.FileCacheStore" fetchPersistentState="true"
ignoreModifications="false" purgeOnStartup="false">
<properties>
<property name="location" value="/tmp"/>
</properties>
</loader>
</loaders>
<eviction wakeUpInterval="500" maxEntries="2" strategy="FIFO"/>
</namedCache>

Nothing new in the configuration, lets check how it works

//GETTING THE CACHE


groovy:000> cacheStoreEvictionCache = manager.getCache("CacheStoreEviction")
===> Cache 'CacheStoreEviction'@6208201
//PUTTING SOME OBJECTS
groovy:000> cacheStoreEvictionCache.put("cs1", "value1")
===> value1
groovy:000> cacheStoreEvictionCache.put("cs2", "value2")
===> value2
groovy:000> cacheStoreEvictionCache.put("cs3", "value3")
===> value3
///MMM SIZE IS ONLY TWO, LETS CHECK WHAT HAPPENED
groovy:000> cacheStoreEvictionCache.size()
===> 2
groovy:000> cacheStoreEvictionCache.get("cs3")
===> value3
groovy:000> cacheStoreEvictionCache.get("cs2")
===> value2
//WOW! EVEN IF THE CACHE SIZE IS 2, I RECOVERED THE THREE OBJECTS.. COOL!!
groovy:000> cacheStoreEvictionCache.get("cs1")
===> value1

Cache with REPL_SYNC & transaction management


TODO

JBoss Community Documentation

Page 433 of 617

Infinispan 6.0

3.76 Using Infinispan with Scala


3.76.1 Introduction
This article shows how to use Infinispan with Scala language. It uses the same commands and
configurations used in the Groovy edition of interactive tutorial. For more details about the scenarios and
steps please visit about page since here will will only focus on Scala compatibility.

3.76.2 Environment
Preparing the environment is almost similar to one described here, but with a minor difference that unlike
Groovy which uses ~/.groovy/lib folder to extend initial classpath, we will use classic CLASSPATH
environment variable with Scala. Another issue is that with the recent edition of Infinispan core jar file is in
the root folder of $INIFINISPAN_HOME, hence here a sample bash script to prepare CLASSPATH for our
demo:

export INFINISPAN_HOME=~/build/infinispan/infinispan-4.2.1.CR1
for j in $INFINISPAN_HOME/lib/*.jar; do CLASSPATH=$CLASSPATH:$j; done
export CLASSPATH=$CLASSPATH:$INFINISPAN_HOME/infinispan-core.jar
export CLASSPATH=$CLASSPATH:[Path to folder containing sample-configurations.xml file]

Download*sample-configurations.xml* file from here.

3.76.3 Testing Setup


The following code shows how to start an Scala console that will allow commands to be entered
interactively. To verify that the Infinispan classes have been imported correctly, an import for all Infinispan
classes will be attempted and then a request will be made to print the version of Infinispan:

[z@dnb:~/Go/demos/interactive-infinispan-scala]% ./scala
Welcome to Scala version 2.8.1.final (Java HotSpot(TM) 64-Bit Server VM, Java 1.6.0_22).
Type in expressions to have them evaluated.
Type :help for more information.
scala> import org.infinispan._
import org.infinispan._
scala> println(Version.version)
4.2.1.CR1

JBoss Community Documentation

Page 434 of 617

Infinispan 6.0

3.76.4 Loading the Configuration file


In this next example, a new cache manager will be created using the configuration file downloaded earlier:

scala> import org.infinispan.manager._


import org.infinispan.manager._
scala> val manager = new DefaultCacheManager("sample-configurations.xml")
manager: org.infinispan.manager.DefaultCacheManager =
org.infinispan.manager.DefaultCacheManager@38b58e73@Address:null

Retrieving cache instances from cache manager


In this example, the default cache is retrieved expecting keys and values to be of String type:

scala> val defaultCache = manager.getCache[String, String]()


defaultCache: org.infinispan.Cache[String,String] = Cache '___defaultcache'@1326840752

In this next example, a named cache is retrieved, again with keys and values expected to be String:

scala> val namedCache = manager.getCache[String, String]("NameOfCache")


namedCache: org.infinispan.Cache[String,String] = Cache 'NameOfCache'@394890130

JBoss Community Documentation

Page 435 of 617

Infinispan 6.0

3.76.5 Basic cache operations


In this section, several basic operations will be executed against the cache that show how it can be
populated with data, how data can be retrieved and size can be checked, and finally how after removing the
data entered, the cache is empty:

scala> val localCache = manager.getCache[String, String]("Local")


localCache: org.infinispan.Cache[String,String] = Cache 'Local'@420875876
scala> localCache.size()
res0: Int = 0
scala> localCache.put("aKey", "aValue")
res1: String = null
// This null was returned by put() indicating that
// the key was not associated with any previous value.
scala> localCache.size()
res2: Int = 1
scala> localCache.containsKey("aKey")
res3: Boolean = true
scala> localCache.get("aKey")
res4: String = aValue
scala> localCache.size()
res5: Int = 1
scala> localCache.remove("aKey")
res6: String = aValue
scala> localCache.isEmpty()
res7: Boolean = true

JBoss Community Documentation

Page 436 of 617

Infinispan 6.0

3.76.6 Basic cache operations with TTL


When a cache entry is stored, a maximum lifespan for the entry can be provided. So, when that time is
exceeded, the entry will dissapear from the cache:

scala> localCache.put("bKey", "bValue")


res8: String = null
scala> import java.util.concurrent.TimeUnit
import java.util.concurrent.TimeUnit
scala> localCache.put("timedKey", "timedValue", 1000, TimeUnit.MILLISECONDS)
res9: String = null
scala> localCache.size()
res10: Int = 2
scala> localCache.get("timedKey")
res11: String = null
scala> localCache.size()
res12: Int = 1

3.76.7 Cache restarts


When caches are local and not configured with a persistent store, restarting them means that the data is
gone. To avoid this issue you can either configure caches to be clustered so that if one cache dissapears,
the data is not completely gone, or configure the cache with a persistent cache store. The latter option will be
explained later on.

scala> localCache.size()
res13: Int = 1
scala> localCache.stop()
scala> localCache.start()
scala> localCache.size()
res16: Int = 0

JBoss Community Documentation

Page 437 of 617

Infinispan 6.0

3.76.8 Transactional cache operations


Infinispan caches can be operated within a transaction, in such way that operations can be grouped in order
to be executed atomically. The key thing to understand about transactions is that within the transactions
changes are visible, but to other non-transactional operations, or other transactions, these are not visible
until the transaction is committed. The following example shows how within a transaction an entry can be
stored but outside the transaction, this modification is not yet visible, and that once the transaction is
committed, the modification is visible to all:

scala> import javax.transaction.TransactionManager


import javax.transaction.TransactionManager
scala> val localTxCache = manager.getCache[String, String]("LocalTX")
localTxCache: org.infinispan.Cache[String,String] = Cache 'LocalTX'@955386212
scala> val tm = localTxCache.getAdvancedCache().getTransactionManager()
tm: javax.transaction.TransactionManager =
org.infinispan.transaction.tm.DummyTransactionManager@81ee8c1
scala> tm.begin()
scala> localTxCache.put("key1", "value1")
res1: String = null
scala> localTxCache.size()
res2: Int = 1
scala> tm.suspend()
res3: javax.transaction.Transaction = DummyTransaction{xid=DummyXid{id=1}, status=0}
scala> localTxCache.size()
res4: Int = 0
scala> localTxCache.get("key1")
res5: String = null
scala> tm.resume(res3)
scala> localTxCache.size()
res7: Int = 1
scala> localTxCache.get("key1")
res8: String = value1
scala> tm.commit()
scala> localTxCache.size()
res10: Int = 1
scala> localTxCache.get("key1")
res11: String = value1

JBoss Community Documentation

Page 438 of 617

Infinispan 6.0
Note how this example shows a very interesting characteristic of the Scala console. Every operation's return
value is stored in a temporary variable which can be referenced at a later stage, even if the user forgets to
assign the result of a operation when the code was executed.

3.76.9 Persistent stored backed Cache operations


When a cache is backed by a persistent store, restarting the cache does not lead to data being lost. Upon
restart, the cache can retrieve in lazy or prefetched fashion cache entries stored in the backend persistent
store:

scala> val cacheWithStore = manager.getCache[String, String]("CacheStore")


cacheWithStore: org.infinispan.Cache[String,String] = Cache 'CacheStore'@2054925789
scala> cacheWithStore.put("storedKey", "storedValue")
res21: String = null
scala> localCache.put("storedKey", "storedValue")
res22: String = null
scala> cacheWithStore.stop()
scala> localCache.stop()
scala> cacheWithStore.start()
scala> localCache.start()
scala> localCache.get("storedKey")
res27: String = null
scala> cacheWithStore.size()
res28: Int = 1
scala> cacheWithStore.get("storedKey")
res29: String = storedValue

JBoss Community Documentation

Page 439 of 617

Infinispan 6.0

3.76.10 Operating against a size bounded cache


Infinispan caches can be configured with a max number of entries, so if this is exceeded certain cache
entries are evicted from in-memory cache. Which cache entries get evicted is dependant on the eviction
algorithm chosen. In this particular example, FIFO algorithm has been configured, so when a cache entry
needs to be evicted, those stored first will go first:

scala> val evictionCache = manager.getCache[String, String]("Eviction")


evictionCache: org.infinispan.Cache[String,String] = Cache 'Eviction'@882725548
scala> evictionCache.put("key1", "value1")
res30: String = null
scala> evictionCache.put("key2", "value2")
res31: String = null
scala> evictionCache.put("key3", "value3")
res32: String = null
scala> evictionCache.size()
res33: Int = 2
scala> evictionCache.get("key3")
res34: String = value3
scala> evictionCache.get("key2")
res35: String = value2
scala> evictionCache.get("key1")
res36: String = null

JBoss Community Documentation

Page 440 of 617

Infinispan 6.0

3.76.11 Size bounded caches with persistent store


When caches configured with eviction are configured with a persistent store as well, when the cache
exceeds certain size, apart from removing the corresponding cache entries from memory, these entries are
stored in the persistent store. So, if they're requested by cache operations, these are retrieved from the
cache store:

scala> val cacheStoreEvictionCache = manager.getCache[String, String]("CacheStoreEviction")


cacheStoreEvictionCache: org.infinispan.Cache[String,String] = Cache
'CacheStoreEviction'@367917752
scala> cacheStoreEvictionCache.put("cs1", "value1")
res37: String = null
scala> cacheStoreEvictionCache.put("cs2", "value2")
res38: String = null
scala> cacheStoreEvictionCache.put("cs3", "value3")
res39: String = null
scala> cacheStoreEvictionCache.size()
res40: Int = 2
scala> cacheStoreEvictionCache.get("cs3")
res41: String = value3
scala> cacheStoreEvictionCache.get("cs2")
res42: String = value2
scala> cacheStoreEvictionCache.get("cs1")
res43: String = value1

JBoss Community Documentation

Page 441 of 617

Infinispan 6.0

4 Upgrade Guide
4.1 Upgrading from 5.0 to 5.1
Please find below tips and recommendations when upgrading from Infinispan 5.0 to 5.1:
API
Eviction and Expiration
Transactions
State transfer
Configuration
Flags and ClassLoaders
JGroups Bind Address

JBoss Community Documentation

Page 442 of 617

Infinispan 6.0

4.1.1 API
1. The cache and cache manager hierarchies have changed slightly in 5.1 with the introduction of
BasicCache and BasicCacheContainer, which are parent classes of existing Cache and
CacheContainer classes respectively. What's important is that Hot Rod clients must now code
against BasicCache and BasicCacheContainer rather than Cache and CacheContainer. So
previous code that was written like this will no longer compile.

import org.infinispan.Cache;
import org.infinispan.manager.CacheContainer;
import org.infinispan.client.hotrod.RemoteCacheManager;
...
CacheContainer cacheContainer = new RemoteCacheManager();
Cache cache = cacheContainer.getCache();

Instead, if Hot Rod clients want to continue using interfaces higher up the hierarchy from the remote
cache/container classes, they'll have to write:

import org.infinispan.BasicCache;
import org.infinispan.manager.BasicCacheContainer;
import org.infinispan.client.hotrod.RemoteCacheManager;
...
BasicCacheContainer cacheContainer = new RemoteCacheManager();
BasicCache cache = cacheContainer.getCache();

Previous code that interacted against the RemoteCache and RemoteCacheManager should work as it used
to:

import org.infinispan.client.hotrod.RemoteCache;
import org.infinispan.client.hotrod.RemoteCacheManager;
...
RemoteCacheManager cacheContainer = new RemoteCacheManager();
RemoteCache cache = cacheContainer.getCache();

JBoss Community Documentation

Page 443 of 617

Infinispan 6.0

4.1.2 Eviction and Expiration


1. The eviction XML element no longer defines the wakeUpInterval attribute. This is now
configured via the expiration element:

<expiration wakeUpInterval="60000"... />

2. Eviction's maxEntries is used as guide for the entire cache, but eviction happens on a per cache
segment, so when the segment is full, the segment is evicted. That's why maxEntries is a
theoretical limit but in practical terms, it'll be a bit less than that. This is done for performance reasons.

4.1.3 Transactions
1. A cache marked as TRANSACTIONAL cannot be accessed outside of a transaction, and a
NON_TRANSACTIONAL cache cannot be accessed within a transaction. In 5.0, a transactional cache
would support non-transactional calls as well. This change was done to be in-line with expectations
set out in JSR-107 as well as to provide more consistent behavior.
2. In 5.0, commit and rollback phases were asynchronous by default. Starting with 5.1, these are now
synchronous by default, to provide the guarantees required by a single lock-owner model.

4.1.4 State transfer


One of the big changes we made in 5.1 was to use the same push-based state transfer we introduced in 5.0
both for rehashing in distributed mode and for state retrieval in replicated mode. We even borrow the
consistent hash concept in replicated mode to transfer state from all previous cache members at once in
order to speed up transfer.
As a consequence we've unified the state transfer configuration as well, there is now a stateTransfer
element holding a simplified state transfer configuration. The corresponding attributes in the
stateRetrieval and hash elements have been deprecated, as have been some attributes that are no
longer used.

4.1.5 Configuration
If you use XML to configure Infinispan, you shouldn't notice any change, except a much faster startup,
courtesy of the Stax based parser. However, if you use programmatic configuration, read on for the
important differences.
Configuration is now packaged in org.infinispan.configuration, and you must use a builder style:

JBoss Community Documentation

Page 444 of 617

Infinispan 6.0

Configuration c1 = new ConfigurationBuilder()


// Adjust any configuration defaults you want
.clustering()
.l1()
.disable()
.mode(DIST_SYNC)
.hash()
.numOwners(5)
.build();

The old bean style configuration is now deprecated and will be removed in a later version.
Configuration properties which can be safely changed at runtime are mutable, and all others are immutable.
To copy a configuration, use the read() method on the builder, for example:

Configuration c2 = new ConfigurationBuilder()


// Read in C1 to provide defaults
.read(c1)
.clustering()
.l1()
.enable()
// This cache is DIST_SYNC, will have 5 owners, with L1 cache enabled
.build();

This completely replaces the old system of defining a set of overrides on bean properties. Note that this
means the behaviour of Infinispan configuration is somewhat different when used programmatically. Whilst
before, you could define a default configuration, and any overrides would be applied on top of your defaults
when defined, now you must explicitly read in your defaults to the builder. This allows for much greater
flexibility in your code (you can have a as many "default" configurations as you want), and makes your code
more explicit and type safe (finding references works).
The schema is unchanged from before. Infinispan 4.0 configurations are currently not being parsed. To
upgrade, just change the schema definition from:

<infinispan
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="urn:infinispan:config:4.1
http://www.infinispan.org/schemas/infinispan-config-4.1.xsd"
xmlns="urn:infinispan:config:4.1">

to

<infinispan
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="urn:infinispan:config:5.1
http://www.infinispan.org/schemas/infinispan-config-5.1.xsd"
xmlns="urn:infinispan:config:5.1">

JBoss Community Documentation

Page 445 of 617

Infinispan 6.0
The schema documentation has changed format, as it is now produced using the standard tool xsddoc. This
should be a significant improvement, as better navigation is offered. Some elements and attributes are
missing docs right now, we are working on adding this. As an added benefit, your IDE should now show
documentation when an xsd referenced (as above)
We are in the process of adding in support for this configuration style for modules (such as cache stores). In
the meantime, please use the old configuration or XML if you require support for cache store module
configuration.

4.1.6 Flags and ClassLoaders


The Flags and ClassLoaders API has changed. In the past, the following would work:
cache.withFlags(f1, f2);
cache.withClassLoader(cl);
cache.put(k, v);
In 5.1.0, these withX() methods return a new instance and not the cache itself, so thread locals are avoided
and the code above will not work. If used in a fluent manner however, things still work:

cache.withFlags(f1, f2).withClassLoader(cl).put(k, v);

The above pattern has always been the intention of this API anyway.

4.1.7 JGroups Bind Address


Since upgrading to JGroups 3.x, -Dbind.address is ignored. This should be replaced with
-Djgroups.bind_addr.

4.1.8 Configuration changes from 5.0 to 5.1


If you use XML to configure Infinispan, you shouldn't notice any change, except a much faster startup,
courtesy of the Stax based parser. However, if you use programmatic configuration, read on for the
important differences.
Configuration is now packaged in org.infinispan.configuration, and you must use a builder style:

JBoss Community Documentation

Page 446 of 617

Infinispan 6.0

Configuration c1 = new ConfigurationBuilder()


// Adjust any configuration defaults you want
.clustering()
.l1()
.disable()
.mode(DIST_SYNC)
.hash()
.numOwners(5)
.build();

The old bean style configuration is now deprecated and will be removed in a later version.
Configuration properties which can be safely changed at runtime are mutable, and all others are immutable.
To copy a configuration, use the read() method on the builder, for example:

Configuration c2 = new ConfigurationBuilder()


// Read in C1 to provide defaults
.read(c1)
.clustering()
.l1()
.enable()
// This cache is DIST_SYNC, will have 5 owners, with L1 cache enabled
.build();

This completely replaces the old system of defining a set of overrides on bean properties. Note that this
means the behaviour of Infinispan configuration is somewhat different when used programmatically. Whilst
before, you could define a default configuration, and any overrides would be applied on top of your defaults
when defined, now you must explicitly read in your defaults to the builder. This allows for much greater
flexibility in your code (you can have a as many "default" configurations as you want), and makes your code
more explicit and type safe (finding references works).
The schema is unchanged from before. Infinispan 4.0 configurations are currently not being parsed. To
upgrade, just change the schema definition from:

<infinispan
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="urn:infinispan:config:4.1
http://www.infinispan.org/schemas/infinispan-config-4.1.xsd"
xmlns="urn:infinispan:config:4.1">

to

<infinispan
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="urn:infinispan:config:5.1
http://www.infinispan.org/schemas/infinispan-config-5.1.xsd"
xmlns="urn:infinispan:config:5.1">

JBoss Community Documentation

Page 447 of 617

Infinispan 6.0
The schema documentation has changed format, as it is now produced using the standard tool xsddoc. This
should be a significant improvement, as better navigation is offered. Some elements and attributes are
missing docs right now, we are working on adding this. As an added benefit, your IDE should now show
documentation when an xsd referenced (as above)
We are in the process of adding in support for this configuration style for modules (such as cache stores). In
the meantime, please use the old configuration or XML if you require support for cache store module
configuration.

JBoss Community Documentation

Page 448 of 617

Infinispan 6.0

4.2 Upgrading from 5.1 to 5.2


4.2.1 Declarative configuration
In order to use all of the latest features, make sure you change the namespace declaration at the top of your
XML configuration files as follows:

<infinispan xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="urn:infinispan:config:5.2
http://www.infinispan.org/schemas/infinispan-config-5.2.xsd" xmlns="urn:infinispan:config:5.2">
...
</infinispan>

4.2.2 Transaction
The default transaction enlistment model has changed (ISPN-1284) from XAResounce to Synchronization
. Also now, if the XAResounce enlistment is used, then recovery is enabled by default.
In practical terms, if you were using the default values, this should not cause any backward compatibility
issues but an increase in performance of about 5-7%. However in order to use the old configuration defaults,
you need to configure the following:

<transaction useSynchronization="false">
<recovery enabled="false"/>
</transaction>

or the programmatic configuration equivalent:

ConfigurationBuilder builder = new ConfigurationBuilder();


builder.transaction().useSynchronization(false).recovery().enabled(false)

4.2.3 Cache Loader and Store configuration


Cache Loader and Store configuration has changed greatly in Infinispan 5.2. Please refer to the Cache
Loaders and Stores documentation.

4.2.4 Virtual Nodes > Segments


The concept of Virtual Nodes doesn't exist anymore in Infinispan 5.2 and has been replaced by Segments.
Please refer to the Clustering modes documentation

JBoss Community Documentation

Page 449 of 617

Infinispan 6.0

4.3 Upgrading from 5.2 to 5.3


This page documents the code / configuration changes required when upgrading from Infinispan 5.2 to 5.3

JBoss Community Documentation

Page 450 of 617

Infinispan 6.0

5 Glossary
5.1 Glossary
2-phase commit
Atomicity, Consistency, Isolation, Durability (ACID)
Basically Available, Soft-state, Eventually-consistent (BASE)
Cache Aside
Consistency, Availability and Partition-tolerance (CAP) Theorem
Consistent Hash
Data grid
Deadlock
Distributed Hash Table (DHT)
Externalizer
Hot Rod
In-memory data grid
Isolation level
JTA synchronization
Livelock
Memcached
Multiversion Concurrency Control (MVCC)
Near Cache
Network partition
NoSQL
Optimistic locking
Pessimistic locking
Read Ahead
READ COMMITTED
Relational Database Management System (RDBMS)
REPEATABLE READ
Representational State Transfer (REST)
Split brain
Structured Query Language (SQL)
Write-behind
Write skew
Write-through
XA resource

JBoss Community Documentation

Page 451 of 617

Infinispan 6.0

5.2 2-phase commit


2-phase commit protocol (2PC) is a consensus protocol used for atomically commit or rollback distributed
transactions.

5.2.1 More resources


wikipedia article

5.3 Atomicity, Consistency, Isolation, Durability (ACID)


TODO

5.4 Basically Available, Soft-state,


Eventually-consistent (BASE)
BASE, also known as Eventual Consistency, is seen as the polar opposite of Atomicity, Consistency,
Isolation, Durability (ACID), properties seen as desirable in traditional database systems such as a
Relational Database Management System (RDBMS).
BASE essentially embraces the fact that true consistency cannot be achieved in the real world, and as such
cannot be modelled in highly scalable distributed systems. BASE has roots in Eric Brewer's Consistency,
Availability and Partition-tolerance (CAP) Theorem, and eventual consistency is the underpinning of any
distributed system that aims to provide high availability and partition tolerance.
Infinispan has traditionally followed ACID principles as far as possible, however an eventually consistent
mode embracing BASE is on the roadmap.

5.4.1 More resources


A good article on ACM compares BASE versus ACID.
An excellent talk on eventual consistency and BASE in Riak is also available on InfoQ.

5.5 Cache Aside


TODO

JBoss Community Documentation

Page 452 of 617

Infinispan 6.0

5.6 Consistency, Availability and Partition-tolerance


(CAP) Theorem
Made famous by Eric Brewer at UC Berkeley, this is a theorem of distributed computing that can be
simplified to state that one can only practically build a distributed system exhibiting any two of the three
desirable characteristics of distributed systems, which are: Consistency, Availability and Partition-tolerance
(abbreviated to CAP). The theorem effectively stresses on the unreliability of networks and the effect this
unreliability has on predictable behavior and high availability of dependent systems.
Infinispan has traditionally been biased towards Consistency and Availability, sacrificing Partition-tolerance.
However, Infinispan does have a Partition-tolerant, eventually-consistent mode in the pipeline. This optional
mode of operation will allow users to tune the degree of consistency they expect from their data, sacrificing
partition-tolerance for this added consistency.

5.6.1 More resources


The theorem is well-discussed online, with many good resources to follow up on, including:
http://www.julianbrowne.com/article/viewer/brewers-cap-theorem
A more recent article by Eric Brewer himself appears on InfoQ, a modern analysis of the theorem.

5.7 Consistent Hash


TODO

JBoss Community Documentation

Page 453 of 617

Infinispan 6.0

5.8 Data grid


A data grid is a cluster of (typically commodity) servers, normally residing on a single local-area network,
connected to each other using IP based networking. Data grids behave as a single resource, exposing the
aggregate storage capacity of all servers in the cluster. Data stored in the grid is usually partitioned, using a
variety of techniques, to balance load across all servers in the cluster as evenly as possible. Data is often
redundantly stored in the grid to provide resilience to individual servers in the grid failing i.e. more than one
copy is stored in the grid, transparently to the application.
Data grids typically behave in a peer-to-peer fashion. Infinispan, for example, makes use of JGroups as a
group communication library and is hence biased towards a peer-to-peer design. Such design allows
Infinispan to exhibit self-healing characteristics, providing service even when individual servers fail and new
nodes are dynamically added to the grid.
Infinispan also makes use of TCP and optionally UDP network protocols, and can be configured to make use
of IP multicast for efficiency if supported by the network.

5.8.1 More resources


In-memory data grid

5.9 Deadlock
TODO

5.10 Distributed Hash Table (DHT)


TODO

5.11 Externalizer
An Externalizer is a class that knows how to marshall a given object type to a byte array, and how to
unmarshall the contents of a byte array into an instance of the object type. Externalizers are effectively an
Infinispan extension that allows users to specify how their types are serialized. The underlying Infinispan
marshalling infrastructure builds on JBoss Marshalling, and offers efficient payloads and stream caching.
This provides much better performance than standard Java serialization.

5.11.1 More resources


Plug your own Externalizer implementation into Infinispan

JBoss Community Documentation

Page 454 of 617

Infinispan 6.0

5.12 Hot Rod


Hot Rod is the name of Infinispan's custom TCP client/server protocol which was created in order to
overcome the deficiencies of other client/server protocols such as Memcached. HotRod, as opposed to other
protocols, has the ability of handling failover on an Infinispan server cluster that undergoes a topology
change. To achieve this, the Hot Rod regularly informs the clients of the cluster topology.
Hot Rod enables clients to do smart routing of requests in partitioned, or distributed, Infinispan server
clusters. This means that Hot Rod clients can determine the partition in which a key is located and
communicate directly with the server that contains the key. This is made possible by Infinispan servers
sending the cluster topology to clients, and the clients using the same consistent hash as the servers.

5.12.1 More resources


Information about the first version of the protocol
Starting a Hot Rod server
Hot Rod client libraries

5.13 memory data grid


An in-memory data grid (IMDG) is a special type of Data grid. In an IMDG, each server uses its main system
memory (RAM) as primary storage for data (as opposed to disk-based storage). This allows for much greater
concurrency, as lock-free STM techniques such as compare-and-swap can be used to allow hardware
threads accessing concurrent datasets. As such, IMDGs are often considered far better optimized for a
multi-core and multi-CPU world when compared to disk-based solutions. In addition to greater concurrency,
IMDGs offer far lower latency access to data (even when compared to disk-based data grids using solid
state drives).
The tradeoff is capacity. Disk-based grids, due to the far greater capacity of hard disks, exhibit two (or even
three) orders of magnitude greater capacity for the same hardware cost.

5.14 Isolation level


TODO

5.15 JTA synchronization


A Synchronization is a listener which receives events relating to the transaction lifecycle. A Synchronization
implementor receives two events, before completion and after completion. Synchronizations are useful when
certain activities are required in the case of a transaction completion; a common usage for a Synchronization
is to flush an application's caches.

JBoss Community Documentation

Page 455 of 617

Infinispan 6.0

5.16 Livelock
TODO

5.17 Memcached
Memcached is an in-memory caching system, often used to speed-up database-driven websites.
Memcached also defines a text based, client/server, caching protocol, known as the Memcached protocol.
Infinispan offers a server which speaks the Memcached protocol, allowing Memcached itself to be replaced
by Infinispan. Thanks to Infinispan's clustering capabilities, it can offer data failover capabilities not present in
original Memcached systems.

5.17.1 More resource


Memcached Server

5.18 Multiversion Concurrency Control (MVCC)


TODO

5.19 Near Cache


TODO

5.20 Network partition


Network partitions happens when multiple parts of a cluster become separated due to some type of network
failure, whether permanent or temporary. Often temporary failures heal spontaneously, within a few seconds
or at most minutes, but the damage that can occur during a network partition can lead to inconsistent data.
Closely tied to Brewer's CAP theorem, distributed systems choose to deal with a network partition by either
sacrificing availability (either by shutting down or going into read-only mode) or consistency by allowing
concurrent and divergent updates to the same data.
Network partitions are also commonly known as a Split brain, after the biological condition of the same
name.
For more detailed discussion, see this blog post.

5.21 NoSQL
TODO

JBoss Community Documentation

Page 456 of 617

Infinispan 6.0

5.22 Optimistic locking


TODO

5.23 Pessimistic locking


TODO

5.24 Read Ahead


TODO

5.25 READ COMMITTED


READ_COMMITTED is one of two isolation levels the Infinispan's locking infrastructure provides (the other is
REPEATABLE READ). Isolation levels have their origins in relational databases.
In Infinispan, READ_COMMITTED works slightly differently to databases. READ_COMMITTED says that
"data can be read as long as there is no write", however in Infinispan, reads can happen anytime thanks to
Multiversion Concurrency Control (MVCC). MVCC allows writes to happen on copies of data, rather than on
the data itself. Thus, even in the presence of a write, reads can still occur, and all read operations in
Infinispan are non-blocking (resulting in increased performance for the end user). On the other hand, write
operations are exclusive in Infinispan, (and so work the same way as READ_COMMITTED does in a
database).
With READ_COMMITTED, multiple reads of the same key within a transaction can return different results,
and this phenomenon is known as non-repeatable reads. This issue is avoided with REPETEABLE_READ
isolation level.
By default, Infinispan uses READ_COMMITTED as isolation level.

5.26 Relational Database Management System (RDBMS)

JBoss Community Documentation

Page 457 of 617

Infinispan 6.0

5.27 REPEATABLE READ


REPEATABLE_READ is one of two isolation levels the Infinispan's locking infrastructure provides (the other
is READ_COMMITTED). Isolation levels have their origins in database.
In Infinispan, REPEATABLE_READ works slightly differently to databases. REPETEABLE_READ says that
"data can be read as long as there are no writes, and viceversa". This avoids the non-repeatable reads
phenomenon, because once data has been written, no other transaction can read it, so there's no chance of
re-reading the data and finding different data.
However, as indicated in READ_COMMITTED article, Infinispan has an MVCC model that allows it to have
non-blocking reads. Infinispan provides REPETEABLE_READ semantics by keeping the previous value
whenever an entry is modified. This allows Infinispan to retrieve the previous value if a second read happens
within the same transaction.

5.28 Representational State Transfer (REST)


REST is a software architectural style that promotes accessing resources via a uniform generic interface.
HTTP is an implementation of this architecture, and generally when REST is mentioned, it refers to REST
over HTTP protocol. When HTTP is used, the uniform generic interface for accessing resources is formed of
GET, PUT, POST, DELETE and HEAD operations.
Infinispan's REST server offers a RESTful API based on these HTTP methods, and allow data to be stored,
retrieved and deleted.

5.28.1 More resources


Starting an Infinispan REST server
The RESTful API
Differences between the REST server and other servers

5.29 Split brain


A colloquial term for a Network partition. See Network partition for more details.

5.30 Structured Query Language (SQL)


TODO

JBoss Community Documentation

Page 458 of 617

Infinispan 6.0

5.31 Write-behind
Write-behind is a cache store update mode. When this mode is used, updates to the cache are
asynchronously written to the cache store. Normally this means that updates to the cache store are not
performed in the client thread.
An alternative cache store update mode is Write-through.

5.31.1 More resources


Infinispan User guide

5.32 Write skew


TODO

5.33 Write-through
Write-through is a cache store update mode. When this mode is used, clients update a cache entry, e.g. via
a Cache.put() invocation, the call will not return until Infinispan has updated the underlying cache store.
Normally this means that updates to the cache store are done in the client thread.
An alternative mode in which cache stores can be updated is Write-behind.

5.33.1 More resources


Infinispan User guide

5.34 XA resource
An XA resource is a participant in an XA transaction (also known as a distributed transaction). For example,
given a distributed transaction that operates over a database and Infinispan, XA defines both Infinispan and
the database as XA resources.
Java's API for XA transactions is JTA and XAResource is the java interface that describes an XA resource.

JBoss Community Documentation

Page 459 of 617

Infinispan 6.0

6 Extending Infinispan
Infinispan has a highly extensible architecture, making it easy to add extensions wherever needed. This
guide walks you through how to create extensions.

Target Audience
This guide is only for those who are looking to extend Infinispan beyond it's core use cases.

JBoss Community Documentation

Page 460 of 617

Infinispan 6.0

6.1 Custom Commands


Infinispan makes use of a command/visitor pattern to implement the various top-level methods you see on
the public-facing API. This is explained in further detail in the Architectural Overview on the Infinispan public
wiki. However, these commands - and their corresponding visitors - are hard-coded as a part of Infinispan's
core module, making it impossible for module authors to extend and enhance Infinispan to create new
arbitrary commands and visitors.
However, since Infinispan 5.0, this capability has now been added. As a module author (such as
infinispan-tree, infinispan-query, etc.) you can now define your own commands. From Infinispan 5.1
onwards, you do so by:
1. Create a
META-INF/services/org.infinispan.commands.module.ModuleCommandExtensions file
and ensure this is packaged in your jar.
2. Implementing ModuleCommandFactory and ModuleCommandInitializer from
infinispan-core.
3. Implementing ModuleCommandExtensions from infinispan-core.
4. Specifing the fully-qualified class name of the ModuleCommandExtensions implementation in
META-INF/services/org.infinispan.commands.module.ModuleCommandExtensions.
5. Implement your custom commands and visitors for these commands
Here is an example of an
META-INF/services/org.infinispan.commands.module.ModuleCommandExtensions file,
configured accordingly:Code Snippet error: Unable to retrieve the URL:

https://github.com/infinispan/infinispan/raw/master/query/src/main/resources/META-INF/services/org.infinispan.commands
status code: 404.
For a full, working example of a sample module that makes use of custom commands and visitors, check out
Infinispan Sample Module.

6.1.1 Preassigned Custom Command Id Ranges


This is the list of Command identifiers that are used by Infinispan based modules or frameworks. Infinispan
users should avoid using ids within these ranges. (RANGES to be finalised yet!)
Being this a single byte, ranges can't be too large.
Infinispan Query:

100 - 119

Hibernate Search: 120 - 139

JBoss Community Documentation

Page 461 of 617

Infinispan 6.0

6.2 Writing custom commands in Infinispan


Infinispan makes use of a command/visitor pattern to implement the various top-level methods you see on
the public-facing API. This is explained in further detail in the Architectural Overview on the Infinispan public
wiki. However, these commands - and their corresponding visitors - are hard-coded as a part of Infinispan's
core module, making it impossible for module authors to extend and enhance Infinispan to create new
arbitrary commands and visitors.
However, since Infinispan 5.0, this capability has now been added. As a module author (such as
infinispan-tree, infinispan-query, etc.) you can now define your own commands. From Infinispan 5.1
onwards, you do so by:
1. Create a
META-INF/services/org.infinispan.commands.module.ModuleCommandExtensions file
and ensure this is packaged in your jar.
2. Implementing ModuleCommandFactory and ModuleCommandInitializer from
infinispan-core.
3. Implementing ModuleCommandExtensions from infinispan-core.
4. Specifing the fully-qualified class name of the ModuleCommandExtensions implementation in
META-INF/services/org.infinispan.commands.module.ModuleCommandExtensions.
5. Implement your custom commands and visitors for these commands
Here is an example of an
META-INF/services/org.infinispan.commands.module.ModuleCommandExtensions file,
configured accordingly:Code Snippet error: Unable to retrieve the URL:

https://github.com/infinispan/infinispan/raw/master/query/src/main/resources/META-INF/services/org.infinispan.commands
status code: 404.
For a full, working example of a sample module that makes use of custom commands and visitors, check out
Infinispan Sample Module.

6.2.1 Preassigned Custom Command Id Ranges


This is the list of Command identifiers that are used by Infinispan based modules or frameworks. Infinispan
users should avoid using ids within these ranges. (RANGES to be finalised yet!)
Being this a single byte, ranges can't be too large.
Infinispan Query:

100 - 119

Hibernate Search: 120 - 139

JBoss Community Documentation

Page 462 of 617

Infinispan 6.0

7 Contributing to Infinispan
AuthorsAnna Manukyan , Galder Zamarreo , Guillaume Scheibel , Kevin Pollet , Manik Surtani , Mircea
Markus , Navin Surtani , Pete Muir , Prabhat Jha , Radoslav Husar , Ray Tsang , Sanne Grinovero , Tristan
Tarrant

Target Audience
This guide shows you how to contribute to the Infinispan project. It contains useful information for
anyone from a casual contributors, wishing to submit a bug report, to full time developers.

The Basics
Pre-requisites
Issue Management - JIRA
Versioning Guidelines
Source control - Git
Setting up your IDE
Eclipse
Build - Maven
Continuous Integration - TeamCity
Testing - TestNG
Communicating with other Infinispan contributors
Style Requirements
Spelling
License header
Check-in comments
Configuration
Logging

JBoss Community Documentation

Page 463 of 617

Infinispan 6.0
Source Control
Pre-requisites
Repositories
Roles
Occasional Contributor
Frequent Contributor
Project Admin
Contributor License Agreement (CLA)
Committing your work
Release branches
Topic branches
Comments
Commits
Keeping your repo in sync with upstream
If you have cloned upstream
If you have forked upstream
Tips on enhancing git
Auto-completions
Terminal colours
Aliases
Visual History
Visual diff and merge tools
Choosing an Editor
Shell prompt
Building Infinispan
Requirements
Quick command reference
Publishing releases to Maven
Publishing snapshots
Publishing releases
The Maven Archetypes
Starting a new project
Writing a test case for Infinispan
Versions
Source Code
API, Commons and Core
API
Commons
Core

JBoss Community Documentation

Page 464 of 617

Infinispan 6.0
Running and Writing Tests
Running the tests
Specifying which tests to run
Skipping the test run
Running tests using @Parameters
Enabling TRACE in test logs
Enabling code coverage generation
Test groups
Which group should I use?
Test permutations
Running permutations manually or in an IDE
The Parallel Test Suite
Tips for writing and debugging parallel tests
Helping Others Out
Adding Configuration
Adding a property
Adding a group
Don't forget to update the XSD and XSD test
Bridging to the old configuration
Writing Documentation and FAQs
Introduction
What goes where?
Wiki markup or rich text
Markup guide
Headers, Page Structure and the Table of Contents
Marking up text
Lists and tables
Links
Admonitions
Images and other media
Code samples
Voice and grammar guide
Glossary
Screencasts
Managing this confluence instance.

Infinispan's Architecture
Interested in reading more about Infinispan's architecture? Check out the Architectural Overview.

JBoss Community Documentation

Page 465 of 617

Infinispan 6.0

7.1 The Basics


In this chapter we quickly walk through the basics on contributing; future chapters go into more
depth.

7.1.1 requisites
Java 1.6

Infinispan is baselined on Java 6.0, and is built and tested using Sun Java 6.0.

Maven 3

The Infinispan build uses Maven, and we recommend using Maven 3.

Git

The Infinispan sources are stored in Git. If you don't wish to install Git, you can download

(optional)

source bundles

7.1.2 Issue Management - JIRA


Infinispan uses JIRA for issue management, hosted on issues.jboss.org. You can log in using your normal
jboss.org username and password.
If you need to create a new issue then follow these steps.
1. Choose between
Feature Request if you want to request an enhancement or new feature for Infinispan
Bug if you have discovered an issue
Task if you wish to request a documentation, sample or process (e.g. build system)
enhancement or issue
2. Then enter a Summary, describing briefly the problem - please try to be descriptive!
3. You should not set Priority.
4. Now, enter the version you are reporting an issue against in the Affects Version field, and leave the
Fix Version field blank.
5. In the Environment text area, describe in as much detail as possible your environment (e.g. Java
runtime and version, operating system, any network topology which is relevant).
6. In the Description field enter a detailed description of your problem or request.
7. If the issue has been discussed on the forums or the mailing list, enter a reference in the Forum
Reference field
8. Finally, hit Create

JBoss Community Documentation

Page 466 of 617

Infinispan 6.0

Versioning Guidelines
Only Infinispan contributors should set the Fix Version field.

When setting the Fix Version field for bugs and issues in JIRA, the following guidelines apply:
Version numbers are defined as MAJOR.MINOR.MICRO.MODIFIER. For example, 4.1.0.BETA1 would be:
MAJOR

MINOR

MICRO

MODIFIER BETA1
If the issue relates to a Task or Feature Request, please ensure that the .FINAL version is included in the
Fixed In field. For example, a new feature should contain 4.1.0.BETA1, 4.1.0.FINAL if it is new for 4.1.0 and
was first made public in BETA1. For example, see ISPN-299.
If the issue relates to a bug which affected a previous FINAL version, then the Fixed In field should also
contain the .FINAL version which contains the fix, in addition to any ALPHA, BETA or CR release. For
example, see ISPN-546.
If the issue pertains to a bug in the current release, then the .FINAL version should not be in the Fixed In
field. For example, a bug found in 4.1.0.ALPHA2 (but not in 4.1.0.ALPHA1) should be marked as fixed in
4.1.0.ALPHA3, but not in 4.1.0.FINAL. For example, see ISPN-416.

7.1.3 Source control - Git


Infinispan uses git, hosted on GitHub, for version control. You can find the upstream git repository at
https://github.com/infinispan. To clone the repository:

$ git clone git@github.com:infinispan/infinispan.git

or to clone your fork:

$ git clone git@github.com:YOUR_GITHB_USERNAME/infinispan.git

For more information, read the Git chapter.

JBoss Community Documentation

Page 467 of 617

Infinispan 6.0

Setting up your IDE


Maven supports generating IDE configuration files for easy setup of a project. Tested are Eclipse, IntelliJ
IDEA and Netbeans.
Before we import the project, we need to clone the project as described above.

Eclipse
1. Install the m2eclipse plugin if you have not already installed it. Eclipse is including it since version
"Indigo" 3.7, for older versions follow instructions at http://eclipse.org/m2e/.
2. Import the Infinispan maven project. Select File -> Import in your eclipse workbench. Select the
Existing Maven Project importer.

3. Select the root directory of your Infinispan checkout.

JBoss Community Documentation

Page 468 of 617

Infinispan 6.0
4. Select Infinispan modules that you want to import.
5. Finally, from Infinispan 5.0 onwards, annotation processing is used to allow log messages to be
internationalized. This processing can be done directly from Eclipse as part of compilation but it
requires some set up:
1. Open the properties for infinispan-core and locate Annotation Processing
2. Tick Enable project specific settings
3. Enter target/generated-sources/annotations as the Generated source
directory

Code Formatting. From the menu Window->Preferences-> select Java -> Code Style -> Formatter. Import
formatter.xml
Code template. From the menu Window->Preferences-> select Java -> Code Style -> Code Templates.
Import codetemplates.xml
Some modules use Scala, if you plan contributing to one of these modules it's worth installing the Scala tools
.

JBoss Community Documentation

Page 469 of 617

Infinispan 6.0

IntelliJ IDEA
Importing
When you start IntelliJ, you will be greeted by a screen as shown below:

JBoss Community Documentation

Page 470 of 617

Infinispan 6.0

If you have already obtained a copy of the Infinispan sources via Github (see 'Source Control'), then
simply follow: Import Project -> /directory/to/downloaded/sources. IntelliJ will automatically make
use of maven to import the project since it will detect a pom.xml file in the base directory.
If you have not obtained the sources already, you can simply use the Git integration provided within
IntelliJ 12. Click on Check out from Version Control -> Github. After entering your Github
credentials, you will then be prompted to enter the git repository URL along with the location that you
want to check out the source code to.

JBoss Community Documentation

Page 471 of 617

Infinispan 6.0

Compiler settings
From Infinispan 5.0 onwards, annotation processing is used to allow log messages to be
internationalized. This processing can be done directly from IntelliJ as part of compilation but it
requires some set up:
Go to "Preferences/Compiler/Annotation Processor" and click on Enable annotation processing
Add an annotation processor with "Processor FQN Name" as
org.jboss.logging.LoggingToolsProcessor
In "Processed Modules", add all modules except the root and the parent modules.

There can sometimes be issues with the generated logging classes on rebuild (particularly when you
switch Git branches). If these issues do crop up then simply run mvn clean install -DskipTests=true
on the command line to clear them out.
EXTRA: If you are running a multi-core environment (e.g. quad-core or above) then you can follow the
instructions on making use of parallelized compilation in IntelliJ 12. Information on how to do this can
be found here.

JBoss Community Documentation

Page 472 of 617

Infinispan 6.0

Scala Plugin
You will need to download the Scala plugin for IntelliJ as well. This can be done by: Project Settings
-> Plugins -> Browse Repositories. Then run a search for 'Scala'. JetBrains themselves are the
vendor for this plugin and more information on it can be found here.

You also have to configure the Scala plugin to use the Scala compiler for Scala files and the Java
compiler for Java files. You can do this by going into Settings -> Compiler -> Scala Compiler. Be
sure to add the scala compiler bundle as shown in the screenshot below.

Code Style
You can find the code style .jar file for IntelliJ in the Infinispan source download. It is located in
/path/to/infinispan/home/ide-settings/intellij.

JBoss Community Documentation

Page 473 of 617

Infinispan 6.0

7.1.4 Build - Maven


Infinispan uses Maven for builds. Make sure you have Maven 3 installed, and properly configured. For more
information, read the Maven chapter.

Continuous Integration - TeamCity


Infinispan TeamCity for continuous integration. TeamCity polls GitHub for updates and runs whenever
updates are available. You can check the status of the latest builds here.

7.1.5 Testing - TestNG


Infinispan uses TestNG for unit and functional tests, and all Infinispan tests are run in parallel. For more
information see the Test Suite chapter; this chapter gives advice on writing tests which can safely execute in
parallel.

7.1.6 Communicating with other Infinispan contributors


Infinispan contributors use a mix of mailings lists and IRC to communicate ideas and designs, with more
detailed designs often making their way into wiki pages.

JBoss Community Documentation

Page 474 of 617

Infinispan 6.0

7.1.7 Style Requirements


Infinispan uses the K&R code style for all Java source files, with two exceptions:
use 3 spaces instead of a tab character for indentations.
braces start on the same line for class, interface and method declarations as well as code blocks.
In addition, sure all new line characters used must be LF (UNIX style line feeds). Most good IDEs allow you
to set this, regardless of operating system used.
All patches or code committed must adhere to this style. Code style settings which can be imported into
IntelliJ IDEA and Eclipse are committed in the project sources, in ide-settings.

Spelling
Ensure correct spelling in code, comments, Javadocs, etc. (use American English spelling). It is
recommended that you use a spellchecker plugin for your IDE.

License header
All source files must have up-to-date license headers as described in Copyright Ownership and Licenses.
Never remove existing headers or copyrights.

Check-in comments
Please ensure any commit comments use this format if related to a task or issue in JIRA. This helps JIRA
pick out these checkins and display them on the issue, making it very useful for back/forward porting fixes. If
your comment does not follow this format, your commit may not be merged into upstream.

7.1.8 Configuration
Infinispan offers both programmatic configuration and XML configuration. For more information read the
Configuration chapter.

7.1.9 Logging
Infinispan follows the JBoss logging standards, which can be found here.
From Infinispan 5.0 onwards, Infinispan uses JBoss Logging to abstract over the logging backend. Infinispan
supports localization of log message for categories of INFO or above as explained in the JBoss Logging
guidelines. As a developer, this means that for each INFO, WARN, ERROR, FATAL message your code emits,
you need to modify the Log class in your module and add an explicit method for it with the right annotations.
For example:

JBoss Community Documentation

Page 475 of 617

Infinispan 6.0

@LogMessage(level = INFO)
@Message(value = "An informative message: %s - %s", id = 600)
void anInformativeMessage(String param1, String param2);

And then, instead of calling log.info(...), you call the method, for example
log.anInformativeMessage(param1, param2). If what you're trying to log is an error or similar
message and you want an exception to be logged as cause, simply use @Cause annotation, example:

@LogMessage(level = ERROR)
@Message(value = "An error message: %s", id = 600)
void anErrorMessage(String param1, @Cause IllegalStateException e);

The last thing to figure out is which id to give to the message. Each module that logs something in
production code that could be internationalized has been given an id range, and so the messages should
use an available id in the range for the module where the log call resides. Here are the id range assignments
per module:

JBoss Community Documentation

Page 476 of 617

Infinispan 6.0

Module name

Id range

core

1 - 1000

tree

2001 - 3000

bdbje cache store

2001 - 3000

cassandra cache store

3001 - 4000

hotrod client

4001 - 5000

server core

5001 - 6000

server hotrod

6001 - 7000

cloud cache store

7001 - 8000

jdbc cache store

8001 - 9000

jdbm cache store

9001 - 10000

remote cache store

10001 - 11000

server memcached

11001 - 12000

server rest

12001 - 13000

server websocket

13001 - 14000

query

14001 - 15000

lucene directory

15001 - 16000

rhq plugin

16001 - 17000

cdi integration

17001 - 18000

hbase cache store

18001 - 19000

cli interpreter

19001 - 20000

cli client

20001 - 21000

mongodb cache store

21001 - 22000

jpa cache store

22001 - 23000

leveldb cache store

23001 - 24000

couchbase cache store 24001 - 25000

When editing the above table, remember to update the README-i18n.txt file in the project sources!

JBoss Community Documentation

Page 477 of 617

Infinispan 6.0

You will need to enable annotation processing in order to be able to compile Infinispan and have
the logger implementation generated.

7.2 Source Control


As a convention, upstream is used as the name of the http://github.com/infinispan/infinispan
repository. This repository is the canonical repository for Infinispan. We usually name origin the fork
on github of each contributor. So the exact meaning of origin is relative to the developer: you could
think of origin as your own fork.

7.2.1 requisites
This document assumes some working knowledge of git. We recommend Scott Chacon's excellent Pro Git
as a valuable piece of background reading. The book is released under the Creative Commons license and
can be downloaded in electronic form for free. At very least, we recommend that Chapter 2, Chapter 3 and
Chapter 5 of Pro Git are read before proceeding.

7.2.2 Repositories
Infinispan uses http://github.com/infinispan/infinispan as its canonical repository, and this repository contains
the stable code on master (currently Infinispan 5.x) as well as the maintenance branches for 4.2.x, 4.1.x and
4.0.x.
Typically, only Project Admins would be able to push to this repo while all else may clone or fork this repo.

7.2.3 Roles
The project assumes one of 3 roles an individual may assume when interacting with the Infinispan
codebase. The three roles here are:
Project Admin (typically, no more than 3 or 4 people)
Frequent Contributor
Occasional Contributor

JBoss Community Documentation

Page 478 of 617

Infinispan 6.0

None of the roles assume that you are a Red Hat employee. All it assumes is how much
responsibility over the project has been granted to you. Typically, someone may be in more than
one role at any given time, and puts on a different "hats" based on the task at hand.

Occasional Contributor
This role defines a user who browses through the source code of the project and occasionally submits
patches. Patches may be submitted in one of two ways:
Attach a patch file to the JIRA issue
Creating a pull request on GitHub
The approach a contributor chooses to use depends entirely his/her personal preference, but usually is tied
to how the contributor accesses Infinispan's source code. If the contributor directly clones the upstream
repository, they should submit patch files. If the contributor instead uses their personal GitHub account to
fork the upstream repository, then they are should issue a pull request.

A GitHub pull request is the preferred method to submit a patch!

JBoss Community Documentation

Page 479 of 617

Infinispan 6.0

Attach a patch file to the JIRA issue

In this workflow, the contributor directly clones the upstream repository, makes changes to his local clone,
adequately tests and commits his work with proper comments (more on commit comments later), and
generates a patch. The patch should then be attached to the JIRA issue.
More information on generating patches suitable for attaching to a JIRA can be found in Chapter 5, Section 2
of Pro Git, under the section titled Public Large Project .

Rather than emailing the patches to a developer mail list, please attach your patch to the JIRA
issue.

Creating a pull request on GitHub

JBoss Community Documentation

Page 480 of 617

Infinispan 6.0
In this workflow, the contributor forks the Infinispan upstream repository on GitHub, clones their fork, and
makes changes to this private fork. When changes have been tested and are ready to be contributed back to
the project, a pull request is issued via GitHub so that one of the Project Administrators can pull in the
change.

Topic Branches
It is desirable to work off a topic branch, even when using your own, forked repository. A topic
branch is created for every feature or bug fix you do. Typically you would create one topic branch
per issue, but if several patches are related it's acceptable to have several commits in the same
branch; however different changes should always be identified by different commits.

Before you push your work onto your fork of the repository, it is often a good idea to review your commits.
Consolidating them (squashing) or breaking them up as necessary and cleaning up commit messages
should all be done while still working off your local clone. Also, prior to issuing a pull request, you should
make sure you rebase your branch against the upstream branch you expect it to be merged into. Also, only
submit pull requests for your branch - not for your master!
The section on Public Small Project in Chapter 5, Section 2 of Pro Git has more information on this style of
workflow.

A worked example
1. Make sure your master is synced up with upstream. See this section for how to do this
2. Create new branch for your topic and switch to it. For the example issue, ISPN-1234:

git checkout -b ISPN-12345 master

3. Do your work. Test. Repeat


4. Commit your work on your topic branch
5. Push your topic branch to GitHub. For example:

git push origin ISPN-12345

6. Issue a pull request using the GitHub pull request system


7. Once your pull request has been applied upstream, delete the topic branch both locally and on your
fork. For example:

git branch -d ISPN-12345 && git push origin :ISPN-12345

8. Sync with upstream again so that your changes now appear in your master branch
If your topic branch has been open for a while and you are afraid changes upstream may clash with your
changes, it makes sense to rebase your topic branch before you issue a pull request. To do this:

JBoss Community Documentation

Page 481 of 617

Infinispan 6.0

1. Sync your master branch with upstream

git checkout master


git pull upstream master

2. Switch to your topic branch. For example:

git checkout ISPN-12345

3. Rebase your topic branch against master:

git rebase master

4. During the rebase process you might need to fix conflicts;


5. when you're done test your code again.
6. Push your rebased topic branch to your repo on GitHub (you will likely need to force this with the -f
option).

git push -f origin ISPN-12345

7. Continue your work on your topic branch.

If you are sharing your forked Infinispan repo with others, then do not rebase! Use a merge instead.

JBoss Community Documentation

Page 482 of 617

Infinispan 6.0

Multi-step coordination between developers using forked repositories


Sometimes a feature/task is rather complex to implement and requires competence from multiple areas of
the projects. In such occasions it is not uncommon for developers to coordinate feature implementation
using personal forks of Infinispan prior to finally issuing request to integrate into Infinispan main repository on
GitHub.
For example, developer A using his personal Infinispan fork creates a topic branch T and completes as
much work as he/she can before requesting for assistance from developer B. Developer A pushes topic T to
his personal Infinispan fork where developer B picks it up and brings it down to his local repo. Developer B
then in turn completes necessary work, commits his/her changes on branch T, and finally pushes back T to
his own personal fork. After issuing request for pull to developer A, developer B waits for notification that
developer A integrated his changes. This exchange can be repeated as much as it is necessary and can
involve multiple developers.

A worked example
This example assumes that developer A and B have added each others Infinispan forked repositories with
the git add remote command. For example, developer B would add developer A's personal Infinispan
fork repository with the command

git remote add devA https://github.com/developerA/infinispan.git

1. Developer A starts implementing feature ISPN-244 and works on a local topic branch ispn244
Developer A pushes ispn244 to personal Infinispan fork. For example:

git push origin ispn244

2. Developer B fetches branch ispn244 to local repository. For example:

git fetch devA ispn244:my_ispn244

3. Developer B works on local branch my_ispn244


4. Developer B commits changes, pushes my_ispn244 to own fork.

git push origin my_ispn244

5. Developer B sends pull request to developer A to integrate changes from my_ispn244 to ispn244

JBoss Community Documentation

Page 483 of 617

Infinispan 6.0

Frequent Contributor
A frequent contributor will only ever submit patches via a pull requests. The pull request will be submitted via
GitHub.
Frequent contributors should always fork the upstream project on GitHub and work off a clone of this fork.
This is very similar to Creating a pull request on GitHub workflow used by a Occasional Contributor.

All Infinispan core developers are considered frequent contributors and work off personal forks of
the upstream repository. This allows for complex features to be developed in parallel without
tripping up over one another. This process is certainly not restricted to just Infinispan core
developers; any contributor is welcome to also participate in this manner.

Project Admin
Project Admins have a very limited role. Only Project Admins are allowed to push to upstream, and Project
Admins never write any code directly on the upstream repository. All Project Admins do is pull in and merge
changes from contributors (even if the "contributor" happens to be themselves) into upstream, perform code
reviews and either commit or reject such changes.

All Contributors who are also Project Admins are encouraged to not merge their own changes, to
ensure that all changes are reviewed.

This approach ensures Infinispan maintains quality on the main code source tree, and allows for important
code reviews to take place again ensuring quality. Further, it ensures clean and easily traceable code history
and makes sure that more than one person knows about the changes being performed.

JBoss Community Documentation

Page 484 of 617

Infinispan 6.0

Merging in patches

Patches submitted via JIRA are audited and promoted to the upstream repository as detailed above. A
Project Admin would typically create a working branch to which the patch is applied and tested. The patch
can be further modified, cleaned up, and commit messages made clearer if necessary. The branch should
then be merged to the master or one of the maintenance branches before being pushed.
More information on applying patches can be found in Chapter 5, Section 3 of Pro Git, under Applying
Patches From Email.

Handling pull requests

Project Admins are also responsible for responding to pull requests. The process is similar to applying a
patch directly, except that when pulling in changes from a forked repository, more than a single commit may
be pulled in. Again, this should be done on a newly created working branch, code reviewed, tested and
cleaned up as necessary.

JBoss Community Documentation

Page 485 of 617

Infinispan 6.0
If commits need to be altered - e.g., rebasing to squash or split commits, or to alter commit messages - it is
often better to contact the Contributor and ask the Contributor to do so and re-issue the pull request, since
doing so on the upstream repo could cause update issues for contributors later on. If commits were altered
or three-way merge was performed during a merge instead of fast-forward, it's also a good idea to check the
log to make sure that the resulting repository history looks OK:

$ git log --pretty=oneline --graph --abbrev-commit # History messed up due to a bad merge
*
3005020 Merge branch 'ISPN-786' of git://github.com/Sanne/infinispan
|\
| * e757265 ISPN-786 Make dependency to log4j optional <-- Same with cb4e5d6 - unnecessary
* | cb4e5d6 ISPN-786 Make dependency to log4j optional <-- Cherry-picked commit by other admin
|/
* ...
$ git reset cb4e5d6

# revert the bad merge

It is therefore strongly recommended that you use the handle_pull_request script that ensures a clean
merge. If you still wish to do this manually, please consider reading through the script first to get an idea of
what needs to happen.
More information on pulling changes from remote, forked repos can be found in Chapter 5, Section 3 of Pro
Git, under Checking Out Remote Branches .

Possible trouble handling pull requests


1. If you have warnings about "Merge made by recursive" you have to fix it rebasing.
2. If you have warnings about "non-fast-forward" you have to rebase.
3. If you see "non-fast-forward updates were rejected" you shall never use "force" on upstream! It means
that another patch was merged before you and you have to update your master again, and rebase
again.
4. "force" is allowed only in special maintenance circumstances. If you find you're needing it to handle a
pull request, then you're doing it wrong, and the mistake might be a dangerous one! It's like the good
rule of never commit when you're drunk (coding is allowed).

Never use force on git push


Using -f while pushing on a shared repository such as upstream you could effectively erase other
committed patches. Noone shall ever use this option unless unanimously approved on the public
mailing list: the most dangerous aspect of it is that nobody gets any notification if this happens, and
we might think issues are solved but you silently removed the fix and it's history from the repository.

Cutting releases
Releases can only me cut by Project Admins, and must be done off a recently updated (git fetch and git pull
origin) clone of the upstream repo. Infinispan's release.py script takes care of the rest.

JBoss Community Documentation

Page 486 of 617

Infinispan 6.0

7.2.4 Contributor License Agreement (CLA)


Contributors that submit patches to Infinispan, if they're not employed by Red Hat, are required to sign the
Contributor License Agreement (CLA) following the instructions in our dedicated site.

7.2.5 Committing your work


Release branches
Infinispan has 4 main release branches. These are master (ongoing work on the 5.0.x series), 4.2.x (ongoing
work on the 4.2.x series), 4.1.x and 4.0.x (respective maintenance branches). Work should never be
committed directly to any of these release branches; topic branches should always be used for work, and
these topic branches should be merged in.

JBoss Community Documentation

Page 487 of 617

Infinispan 6.0

Topic branches
Some of the biggest features of git are speed and efficiency of branching, and accuracy of merging. As a
result, best practices involve making frequent use of branches. Creating several topic branches a day, even,
should not be considered excessive, and working on several topic branches simultaneously again should be
commonplace.
Chapter 3, Section 4 of Pro Git has a detailed discussion of topic branches. For Infinispan, it makes sense to
create a topic branch and name it after the JIRA it corresponds to. (if it doesn't correspond to a JIRA, a
simple but descriptive name should be used).

Topic Branches Affecting More Than One Release Branch


Most topic branches will only affect a single release branch, e.g. Infinispan 5.0 features only affect the
master release branch, so a topic branch should be created based off master. However, occasionally, fixes
may apply to both release branches 4.2.x as well as master. In this case, the following workflow should
apply:
Create topic branch off 4.2.x. For example:

git checkout -b <topic>_4.2.x 4.2.x

Create topic branch off master. For example:

git checkout -b <topic>_master master

Do your work on <topic>_master, test and commit your fixes


Switch to <topic>_4.2.x. For example:

git checkout <topic>_4.2.x

Cherry-pick your commit on <topic>_master onto <topic>_4.2.x. For example:

git cherry-pick <commit_id>

Test <topic>_4.2.x for correctness, modify as necessary


Issue pull requests for both topic branches

JBoss Community Documentation

Page 488 of 617

Infinispan 6.0

Comments
It is extremely important that comments for each commit are clear and follow certain conventions. This
allows for proper parsing of logs by git tools. Read this article on how to format comments for git and adhere
to them. Further to the recommendations in the article, the short summary of the commit message should be
in the following format:

ISPN-XXX Subject line of the JIRA in question

This can optionally be followed by a detailed explanation of the commit. Why it was done, how much of it
was completed, etc. You may wish to express this as a list, for example:

*
*
*
*

Add a unit test


Add more unit tests
Fix regressions
Solve major NP-Complete problems

Make sure however to split separate concerns - especially if they are unrelated - in separate commits.
It might happen that a single commit fixes multiple JIRAs. This shouldn't be the norm, but if it happens, it's
recommended that all JIRA ids are specified in the title of commit, followed by a more detailed explanation
following the example above e.g.

ISPN-XXX ISPN-YYYY Summary of JIRA issues


* Fix ISPN-XXXX by doing...
* Fix ISPN-YYYY by doing...

Commits
Sometimes work on your topic branch may include several commits. For example, committing a test. Then
committing another test. Then perhaps committing a fix. And perhaps fixing your own fix in the next commit...
Before issuing a pull request for this topic branch, consider cleaning up these commits. Interactive rebasing
helps you squash several commits into a single commit, which is often more coherent to deal with for others
merging in your work. Chapter 6, Section 4 of Pro Git has details on how to squash commits and generally,
clean up a series of commits before sharing this work with others. Note that you can also easily reorder
them, just change the order of lines during the interactive rebase process.
Also, it is important to make sure you don't accidentally commit files for which no real changes have
happened, but rather, whitespace has been modified. This often happens with some IDEs. git diff
--check should be run before you issue such a pull request, which will check for such "noise" commits and
warn you accordingly. Such files should be reverted and not be committed to the branch.
Adhering to Infinispan's code style guidelines will help minimise "noise" commits. Project Admins are going
to ask contributors to reformat their code if necessary.

JBoss Community Documentation

Page 489 of 617

Infinispan 6.0

7.2.6 Keeping your repo in sync with upstream


If you have cloned upstream
If you have a clone of the upstream, you may want to update it from time to time. Running:

$ git fetch origin


$ git fetch origin --tags

will often do the trick. You could then pull the specific branches you would need to update:

$
$
$
$

git
git
git
git

checkout master
pull origin master
checkout 4.2.x
pull origin 4.2.x

Updating topic branches


You should rebase your topic branches at this point so that they are up-to-date and when pulled by
upstream, upstream can fast-forward the release branches:

$ git checkout <topic>_master


$ git rebase master

and/or

$ git checkout topic_4.2.x


$ git rebase 4.2.x

JBoss Community Documentation

Page 490 of 617

Infinispan 6.0

If you have forked upstream


If you have a fork of upstream, you should probably define upstream as one of your remotes:

$ git remote add upstream git://github.com/infinispan/infinispan.git

You should now be able to fetch and pull changes from upstream into your local repository, though you
should make sure you have no uncommitted changes. (You do use topic branches, right?)

$
$
$
$
$
$
$
$

git
git
git
git
git
git
git
git

fetch upstream
fetch upstream --tags
checkout master
pull upstream master
push origin master
checkout 4.2.x
pull upstream 4.2.x
push origin 4.2.x

A script can do this for you - have a look at sync_with_upstream.

Updating topic branches


Again, you should rebase your topic branches at this point so that they are up-to-date and when pulled by
upstream, upstream can fast-forward the release branches:

$ git checkout topic_master


$ git rebase master

and/or

$ git checkout topic_4.2.x


$ git rebase 4.2.x

The sync_with_upstream script can do this for you if your topic branch naming conventions match the script.

JBoss Community Documentation

Page 491 of 617

Infinispan 6.0

7.2.7 Tips on enhancing git


Auto-completions
Save this script as /.git-completion.bash and in /.bash_profile, add the following on one line:
source ~/.git-completion.bash

After logging out and back in again, typing git <TAB> will give you a list of git commands, as would git
c<TAB>, etc. This even works for options, e.g. git commit --<TAB>. The completions are even aware of
your refs, so even git checkout my_br<TAB> will complete to git checkout my_branch!
Note that you get git autocompletion for free if you use zsh instead of bash.

Terminal colours
Add the following to your ~/.gitconfig

[color]
ui = yes
[color "branch"]
current = yellow reverse
local = yellow
remote = green
[color "diff"]
meta = yellow bold
frag = magenta bold
old = red bold
new = green bold
[color "status"]
added = yellow
changed = green
untracked = cyan

JBoss Community Documentation

Page 492 of 617

Infinispan 6.0

Aliases
Some git commands are pretty long to type, especially with various switches. Aliases help you to map
shortcuts to more complex commands.; Again, For example, add the following to ~/.gitconfig:

[alias]
co = checkout
undo = reset --hard
cb = checkout -b
br = branch
cp = cherry-pick
st = status
l = log --pretty=oneline --decorate --abbrev-commit
lg = log --decorate --abbrev-commit
last = log --decorate -1 -p --abbrev-commit
ci = commit -a
pom = push origin master
graph = log --pretty=oneline --graph --abbrev-commit
dt = difftool

Visual History
Git ships with gitk, a GUI that visually represents a log. If you use Mac OS X, GitX is a good alternative. Try
typing gitk or gitx in a git project directory.
For Linux users, there are lots of alternatives: gitk, gitg, giggle, ... up to egit for Eclipse.

Visual diff and merge tools


There are several options available, including KDiff3, meld and Perforce's P4Merge which are all either open
source or available for free. See this link on setting these up (section under External Merge and Diff Tools)

Choosing an Editor
You can customise the editor used by git editing ~/.gitconfig. The following fires up MacVIM instead of
the default vi editor:

[core]
editor = mvim -f

Alternatively, you could fire up TextMate or another editors of your choice.

JBoss Community Documentation

Page 493 of 617

Infinispan 6.0

Shell prompt
You can change your Bash shell prompt to print the current repository's branch name. Add the following to
your ~/.bashrc:

function git_current_branch {
git branch --no-color 2> /dev/null | sed -e '/^[^*]/d' -e 's/* \(.*\)/[\1]/'
}
if [ "$PS1" ]; then
PS1='[\u@\h:\W]$(git_current_branch)\$ '
fi

The resulting shell prompt will look like:

trustin@matrix:infinispan-4.2][4.2.x]$

If you're a ZSH user, you can get even more interesting branch information thanks to this blog post, such as:
whether your branch is dirty ()
whether it's ahead of the remote()
whether it diverges with the remote ()
whether it's behind ()
For example, the following prompt indicates that the current branch is 't_ispn775_master' and that the
branch is dirty:

[~/Go/code/infinispan.git]% (t_ispn775_master)

7.3 Building Infinispan


Infinispan uses Maven as a build system.

7.3.1 Requirements
Java 6.0 or above
Maven 3 or above

JBoss Community Documentation

Page 494 of 617

Infinispan 6.0

Make sure you follow the steps outlined in Maven Getting Started - Users to set up your JBoss
repository correctly. This step is crucial to ensure your Maven setup can locate JBoss artifacts! If
you also want to test the EAP integration modules you should also add the appropriate Enterprise
Red Hat Maven Repository.

The following is an example settings.xml to get you started:

<settings xmlns="http://maven.apache.org/SETTINGS/1.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/SETTINGS/1.0.0
http://maven.apache.org/xsd/settings-1.0.0.xsd" >
<localRepository/>
<interactiveMode/>
<usePluginRegistry/>
<offline/>
<proxies/>
<profiles>
<profile>
<id>jboss-public-repository</id>
<repositories>
<repository>
<id>jboss-public-repository-group</id>
<name>JBoss Public Maven Repository Group</name>
<url> https://repository.jboss.org/nexus/content/groups/public-jboss/ </url>
<layout>default</layout>
<releases>
<enabled>true</enabled>
<updatePolicy>never</updatePolicy>
</releases>
<snapshots>
<enabled>true</enabled>
<updatePolicy>never</updatePolicy>
</snapshots>
</repository>
</repositories>
<pluginRepositories>
<pluginRepository>
<id>jboss-public-repository-group</id>
<name>JBoss Public Maven Repository Group</name>
<url> https://repository.jboss.org/nexus/content/groups/public-jboss/ </url>
<layout>default</layout>
<releases>
<enabled>true</enabled>
<updatePolicy>never</updatePolicy>
</releases>
<snapshots>
<enabled>true</enabled>
<updatePolicy>never</updatePolicy>
</snapshots>
</pluginRepository>
</pluginRepositories>
</profile>

JBoss Community Documentation

Page 495 of 617

Infinispan 6.0

<!-- Include early access of application server and other products -->
<profile>
<id>redhat-earlyaccess-repository</id>
<repositories>
<repository>
<id>redhat-earlyaccess-repository-group</id>
<name>Red Hat early access repository</name>
<url> http://maven.repository.redhat.com/earlyaccess/all/ </url>
<layout>default</layout>
<releases>
<enabled>true</enabled>
<updatePolicy>never</updatePolicy>
</releases>
<snapshots>
<enabled>true</enabled>
<updatePolicy>never</updatePolicy>
</snapshots>
</repository>
</repositories>
</profile>
</profiles>
<activeProfiles>
<activeProfile>jboss-public-repository</activeProfile>
<activeProfile>redhat-earlyaccess-repository</activeProfile>
</activeProfiles>
</settings>

7.3.2 Quick command reference


Maven places it's output in target/

JBoss Community Documentation

Page 496 of 617

Infinispan 6.0

mvn clean

Cleans out any old builds and binaries

mvn compile

Compiles java source code

mvn test

Runs the TestNG unit test suite on the compiled code. Will also
compile the tests. See the testing section below for more
information on running different test groups. The default test group
run is the "unit" group.

mvn package

Packages the module as a JAR file, the resulting JAR file will be in
target/

mvn package

Creates a JAR file without running tests

-Dmaven.test.skip.exec=true
mvn package

Creates a reduced version of the distribution with all

-Dmaven.test.skip.exec=true modules,scripts...etc but no javadoc or source code. This is very


handy to quickly build the distribution in order to run some tests.
-P minimal-distribution
mvn install

Installs the artifacts in your local repo for use by other

-Dmaven.test.skip.exec=true projects/modules, including inter-module dependencies within the


same project.
mvn install -P

In addition to install, will also use Maven's assembly plugin to build

distribution

ZIP files for distribution (in target/distribution). Contents of


various distribution are controlled by the files in
src/main/resources/assemblies.

mvn deploy

Builds and deploy the project to the JBoss snapshots repository.

mvn -Pgenerate-schema-doc

Builds the configuration reference HTML file

install -DskipTests=true
-pl core && firefox
core/target/xsd_doc
mvn install -P-extras

Avoids the extras profile disables the enforce plugin, generation of


source jars and OSGI bundleconstruction, hence making builds run
faster. Clearly, this option should not be used when making a
release or publishing a snapshot.

For non-snapshot releases (e.g., alphas, betas, release candidates and final releases) you should
use the bin/release.py script.

JBoss Community Documentation

Page 497 of 617

Infinispan 6.0

7.3.3 Publishing releases to Maven


To be able to publish releases to Maven, you need to have the following in your
${HOME}/.m2/settings.xml file:

<settings>
...
<servers>
...
<server>
<id>jboss-snapshots-repository</id>
<username>your JBoss.org username</username>
<password>your JBoss.org password</password>
</server>
<server>
<id>jboss-releases-repository</id>
<username>your JBoss.org username</username>
<password>your JBoss.org password</password>
</server>
...
</servers>
...
</settings>

Publishing snapshots
Simply running

$ mvn clean deploy -Dmaven.test.skip.exec=true

in the Infinispan root directory will deploy a snapshot.

Publishing releases
Use the bin/release.py script.

7.3.4 The Maven Archetypes


Infinispan currently has 2 separate Maven archetypes you can use to create a skeleton project and get
started using Infinispan. This is an easy way to get started using Infinispan as the archetype generates
sample code, a sample Maven pom.xml with necessary depedencies, etc.

JBoss Community Documentation

Page 498 of 617

Infinispan 6.0

You don't need to have any experience with or knowledge of Maven's Archetypes to use this! Just
follow the simple steps below.

These archetypes have only been tested with Maven 3. Please report back if you have any
success with using Maven 2.

Starting a new project


Use the newproject-archetype project. The simple command below will get you started, and

$ mvn archetype:generate \
-DarchetypeGroupId=org.infinispan.archetypes \
-DarchetypeArtifactId=newproject-archetype \
-DarchetypeVersion=1.0.5 \
-DarchetypeRepository=http://repository.jboss.org/nexus/content/groups/public

You will be prompted for a few things, including the artifactId , groupId and version of your new
project. And that's it - you're ready to go!

Exploring your new project


The skeleton project ships with a sample application class for interacting with Infinispan. You can open this
new project in your IDE - most good IDEs such as IntelliJ and Eclipse allow you to import Maven projects,
see this guide and this guide. Once you open your project in your IDE, you should examine the generated
classes and read through the comments.

On the command line...


Try running

$ mvn install -Prun

in your newly generated project. This runs the main() method in the generated application class.

Writing a test case for Infinispan


This archetype is useful if you wish to contribute a test to the Infinispan project and helps you get set up to
use Infinispan's testing harness and related tools.
Use

JBoss Community Documentation

Page 499 of 617

Infinispan 6.0

$ mvn archetype:generate \
-DarchetypeGroupId=org.infinispan.archetypes \
-DarchetypeArtifactId=testcase-archetype \
-DarchetypeVersion=1.0.5 \
-DarchetypeRepository=http://repository.jboss.org/nexus/content/groups/public

As above, this will prompt you for project details and again as above, you should open this project in your
IDE. Once you have done so, you will see some sample tests written for Infinispan making use of
Infinispan's test harness and testing tools along with extensive comments and links for further reading.

On the command line...


Try running

$ mvn test

in your newly generated project to run your tests.


The generated project has a few different profiles you can use as well, using Maven's -P flag. For example:

$ mvn test -Pudp

Available profiles
The profiles available in the generated sample project are:
udp: use UDP for network communications rather than TCP
tcp: use TCP for network communications rather than UDP
jbosstm: Use the embedded JBoss Transaction Manager rather than Infinispan's dummy test
transaction manager

Contributing tests back to Infinispan


If you have written a functional, unit or stress test for Infinispan and want to contribute this back to Infinispan,
your best bet is to fork the Infinispan sources on GitHub. The test you would have prototyped and tested in
an isolated project created using this archetype can be simply dropped in to Infinispan's test suite. Make
your changes, add your test, prove that it fails even on Infinispan's upstream source tree and issue a pull
request.
{tip:title=New to working with Infinispan and GitHub?

Want to know how best to work with the repositories and contribute code? Read
[Infinispan and Git]

JBoss Community Documentation

Page 500 of 617

Infinispan 6.0

Versions
The archetypes generate poms with dependencies to specific versions of Infinispan. You should edit these
generated poms by hand to point to other versions of Infinispan that you are interested in.

Source Code
The source code used to generate these archetypes are on GitHub. If you wish to enhance and contribute
back to the project, fork away!

7.4 API, Commons and Core


In order to provide proper separation between public APIs, common utilities and the actual implementation of
Infinispan, these are split into 3 modules: infinispan-api, infinispan-commons and infinispan-core. This
separation also makes sure that modules, such as the remote clients, don't have to depend on
infinispan-core and its transitive dependencies. The following paragraphs describe the role of each of these
modules and give indication as to what goes where.

7.4.1 API
The infinispan-api module should only contain the public interfaces which can be used in any context (local,
remote, etc). Any additions and/or modifications to this module must be discussed and approved by the
team beforehand. Ideally it should not contain any concrete classes: rare exceptions may be made for small,
self-contained classes which need to be referenced from the API interfaces and for which the introduction of
an interface would be deemed cumbersome.

7.4.2 Commons
The infinispan-commons module contains utility classes which can be reused across other modules. Classes
in infinispan-commons should be self-contained and not pull in any dependencies (apart from the existing
jboss-logging and infinispan-api). They should also make no reference to configuration aspects specific to a
particular environment.

7.4.3 Core
The infinispan-core module contains the actual implementation used for local/embedded mode. When
adding new functionality to the APIs, it is generally safe to start by putting them in infinispan-core and
promoting them to infinispan-api only when it is deemed to do so and it makes sense across the various
use-cases.

JBoss Community Documentation

Page 501 of 617

Infinispan 6.0

7.5 Running and Writing Tests


Tests are written using the TestNG framework.

7.5.1 Running the tests


Before running the actual tests it is highly recommended to configure adjust suite's memory setting by
updating the MAVEN_OPTS variables. E.g.

$ export MAVEN_OPTS="-Xms512m -Xmx2048m -XX:MaxPermSize=384m"

The default run executes all tests in the functional and unit groups. To just run the tests with txt and xml
output the command is:

$ mvn test

Alternatively, you can execute the tests and generate a report with:

$ mvn surefire-report:report

If you are running the tests on a Unix-like operating system, the default limits per user are typically
low. The Infinispan test suite creates a lot of processes/threads, thus you will have to increase your
user's limits and reboot the system to pick up the new values. Open up
/etc/security/limits.conf and add the following lines replacing the user name with your
username.

rhusar
rhusar
rhusar
rhusar

soft
hard
soft
hard

nofile
nofile
nproc
nproc

JBoss Community Documentation

16384
16384
16384
16384

Page 502 of 617

Infinispan 6.0

Specifying which tests to run


A single test can be executed using the test property. The value is the short name (not the fully qualified
package name) of the test. For example:

$ mvn -Dtest=FqnTest test

Alternatively, if there is more than one test with a given classname in your test suite, you could provide the
path to the test.

$ mvn -Dtest=org/infinispan/api/MixedModeTest test

Alternatively, you can always pass your own Log4j configuration file via -Dlog4.configuration with your
own logging settings.
Patterns are also supported:

$ mvn -Dtest=org/infinispan/api/* test

Skipping the test run


It is sometimes desirable to install the Infinispan package in your local repository without performing a full
test run. To do this, simply use the maven.test.skip.exec property:

$ mvn -Dmaven.test.skip.exec=true install

Note that you should never use -Dmaven.test.skip=true since modules' test classes depend on other
module test classes, and this will cause compilation errors.

Running tests using @Parameters


If you want to execute tests relying on TestNG's @Parameters from an IDE (such as Eclipse or IntelliJ
IDEA), please check this blog entry.

JBoss Community Documentation

Page 503 of 617

Infinispan 6.0

Enabling TRACE in test logs


When you run tests, you can get TRACE logging via using the traceTests profile

mvn test -PtraceTests

Executing this will generate a GZIP file called trace-infinispan.log.gz. This file is not fully closed, so
to extract the log file, execute:

gunzip -c trace-infinispan.log.gz > trace-infinsipan.log

Enabling code coverage generation


When you run tests, you can enable code coverage recorder for calculating and analysing the Infinispan
code coverage. You can do this using coverage and jacocoReport profiles.
As a code coverage evaluation tool, the JaCoCo is used.

mvn test -Pcoverage -Dmaven.test.failure.ignore=true

Please note, that -Dmaven.test.failure.ignore=true is used for generating JaCoCo code coverage
report, even if there are test failures.
Executing this will generate jacoco.exec file in each module's target/ directory. These are the JaCoCo
execution data files, which contain full data about the specific module's coverage.
As soon as the coverage execution command is finished, you will need to generate the JaCoCo report,
which will merge the generated jacoco.exec files as well as will create the code coverage report.
For having the report in place, run the following command from your Infinispan home directory:

mvn install -pl parent -PjacocoReport

The jacoco-html/ directory will be generated in Infinispan Home directory, which will contain the code
coverage report.

JBoss Community Documentation

Page 504 of 617

Infinispan 6.0

7.5.2 Test groups


Each test should belong to one or more group. The group acts as a filter, and is used to select which tests
are ran as part of the maven test lifecycle.

Which group should I use?


If your test does not fit into one of these group, a new group should be added.

unit

Unit tests using stubs to isolate and test each major class in Infinispan. This is the default
group run if no test group is specified

functional

Tests which test the general functionality of Infinispan

jgroups

Tests which need to send data on a JGroups Channel

transaction Tests which use a transaction manager


profiling

Tests used for manual profiling, not meant for automated test runs

manual

Other tests that are run manually

Every test (except those not intended to be run by Hudson) should at least be in the functional or
unit groups, since these are the default test groups executed by Maven, and are run when
preparing a release.

JBoss Community Documentation

Page 505 of 617

Infinispan 6.0

7.5.3 Test permutations


We use the term permutation to describe a test suite execution against a particular configuration. This allows
us to test a variety of environments and configurations without rewriting the same basic test over and over
again. For example, if we pass JVM parameter -Dinfinispan.test.jgroups.protocol=udp test suite
is executed using UDP config.

$ mvn -Dinfinispan.test.jgroups.protocol=udp test

Each permutation uses its own report directory, and its own html output file name. This allows you to execute
multiple permutations without wiping the results from the previous run. Note that due to the way Maven
operates, only one permutation can be executed per mvn command. So automating multiple runs requires
shell scripting, or some other execution framework to make multiple calls to Maven.

Running permutations manually or in an IDE


Sometimes you want to run a test using settings other than the defaults (such as UDP for jgroups group
tests or the DummyTransactionManager for transaction group tests). This can be achieved by referring to
the Maven POM file to figure out which system properties are passed in to the test when doing something
different. For example to run a jgroups group test in your IDE using TCP instead of the default UDP, set
-Dinfinispan.test.jgroups.protocol=tcp. Or, to use JBoss JTA (Arjuna TM) instead of the
DummyTransactionManager in a transaction group test, set -Dinfinispan.test.jta.tm=jbosstm
Please refer to the POM file for more properties and permutations.

7.5.4 The Parallel Test Suite


Infinispan runs its unit test suite in parallel; Infinispan tests are often IO rather than processor bound, so
executing them in parallel offers significant speed up.

Tips for writing and debugging parallel tests


There are a number of constraints and best practices that need to be followed in order to ensure correctness
and keep the execution time to a minimum. If you follow these guidelines you will find your tests are more
reliable:
Each test class is run in a single thread
There is no need to synchronize unit test's fixture, as test methods will be run in sequence. However,
multiple test classes are executed in parallel.
Each test class must have an unique test name
As a convention, the name of the test should be the FQN of the test class with the org.infinispan prefix
removed. For example, given a test class org.infinispan.mypackage.MyTest the name of the test
should be mypackage.MyTest. This convention guarantees a unique name.

JBoss Community Documentation

Page 506 of 617

Infinispan 6.0

MyTest.java
package org.infinispan.mypackage;
@Test (testName = "mypackage.MyTest")
public class MyTest { ... }

Use TestCacheManagerFactory.createXyzCacheManager and _never_create managers using


new DefaultCacheManager()
This ensures that there are no conflicts on resources e.g. a cluster created by one test won't interfere with a
cluster created by another test.
Where possible, extend SingleCacheManagerTestorMultipleCacheManagersTest
Tests inheriting from these template method classes will only create a cache/cluster once for all the test
methods, rather than before each method. This helps keep the execution time down.
Never rely onThread.sleep()
When running in heavily threaded environments this will most often not work. For example, if using
ASYNC_REPL, don't use a sleep(someValue) and expect the data will be replicated to another cache
instance after this delay has elpased. Instead, use a ReplicationListener (check the javadoc for more
information). Generally speaking, if you expect something will happen and you don't have a guarantee when,
a good approach is to try that expectation in a loop, several times, with an generous (5-10secs) timeout. For
example:

while (Systet.currentTimeMillis() - startTime < timeout) {


if (conditionMeet()) break;
Thread.sleep(50);
}

Thread.sleep(10) may not work in certain OS/JRE combos (e.g. Windows XP/Sun JRE 1.5)
Use values grater than 10 for these statements, e.g. 50. Otherwise, a System.currentTimeMillis()
might return same value when called before and after such a sleep statement.
JMX
For each cache that is create with TestCacheManagerFactory.createXyzCacheManager() the test
harness will allocate a unique JMX domain name which can be obtained through
CacheManager.getJmxDomain(). This ensures that no JMX collisions will takes place between any tests
executed in parallel. If you want to enforce a JMX domain name, this can be done by using one of the
TestCacheManagerFactory.createCacheManagerEnforceJmxDomain methods. These methods
must be used with care, and you are responsible for ensuring no domain name collisions happen when the
parallel suite is executed.
Use obscure words
Insert uncommon or obscure words into the cache that has been generated with a random word generator.
In a multi-threaded environment like Infinispan's testsuite, grepping for these words can greatly help the
debugging process. You may find this random word generator useful.

JBoss Community Documentation

Page 507 of 617

Infinispan 6.0
Use the test method name as the key
Grab the test method and use it as part of the cached key. You can dynamically grab the test method using
code like this:

Thread.currentThread().getStackTrace()(1).getMethodName()

Even though we've tried to reduce them to a min, intermittent failures might still appear from time to time. If
you see such failures in existing code please report them in the issue tracker.

7.6 Helping Others Out


Infinispan is reliant on the whole community helping each other out. Less experienced contributors are often
able to help out answering the "newbie" questions, leaving more experienced contributors to handle the
more complex questions.
Users are encouraged to follow the How to ask a forum question guide.
Forum discussions can be posed as questions (we encourage people to do this). Questions can be marked
as answered, indicating to the community that they no longer require answering, allowing easy tracking of
open questions. Open questions can be easily viewed using this filter. Community members are encouraged
to regularly view the open questions and answer any questions they can.
In order to track what questions are still open, you are encouraged to mark questions as "assumed
answered" if you provide information that you think resolves the query and you don't hear back to the
contrary after a week or so.
Approximately every month, a member of the Infinispan team will go through any open questions for the past
month and clear up any unanswered questions, either by chasing for an answer from core team, or by
checking with the user if they require more info.

7.7 Adding Configuration


We still use the old configuration system internally within Infinispan. This makes things a little
complicated. This will be switched out soon! For now, you need to also add your property to the old
config system as well as the new.

Note, these guides assume you are adding an element to the cache configuration, but apply equally to the
global configuration.
Before you start adding a configuration property, identify whether you want to add a property to an existing
configuration group/element, or whether you need to create a child object. We call the configuration group
XXX in the steps below.

JBoss Community Documentation

Page 508 of 617

Infinispan 6.0

7.7.1 Adding a property


Add the property to the relevant XXXConfiguration class. Add a private final field, add a parameter to the
constructor, and assign the value to the field in the constructor body. Add a accessor for the property. If the
property should be mutable at runtime, then add a mutator as well. Most configuration properties are not
mutable at runtime - if the configuration is runtime mutable, then Infinispan needs to take notice of this
update whilst the cache is running (you can't cache the value of the configuration in your implementation
class). Mutators and accessors don't use the classic JavaBean pattern of prepending accessors with "get"
and mutators with "set". Instead, the name of the property is used for an accessor. A mutator is an
overloaded version of the accessor which takes a parameter, the new value.
Add the property to the matching XXXConfigurationBuilder. You'll need to add a mutable field to the
class, and initialise it to it's default value in the field declaration. Add a mutator (following the above pattern).
The create() method is called by the parent object in order to instantiate the XXXConfiguration object
from the builder. Therefore, make sure to pass the value of the field in the builder to the
XXXConfiguration object's constructor here. Additionally, if you require a complex default (for example,
the value of a configuration property is defaulted conditionally based on the value of some other
configuration property), then this is the place to do this.
The validate() method is called by the parent object to validate the values the user has passed in. This
method may also be called directly by user code, should they wish to manually validate a configuration
object. You should place any validation logic here related to your configuration property. If you need to
"cross-validate" properties (validate the value of your property conditionally upon the value of another
property), and the other property is on another builder object, increase the visibility of that other property field
to "default", and reference it from this builder, by calling the getBuilder() method, which will gives you a
handle on the root configuration builder.
The final step is to add parsing logic to the Parser class. First, add the attribute to name to the Attribute
enum (this class simply provides a mapping between the non-type-safe name of the attribute in XML and a
type-safe reference to use in the parser). Locate the relevant parseXXX() method on the class, and add a
case to the switch statement for the attribute. Call the builder mutator you created above, performing any
XML related validation (you are unlikely to need this), and type conversion (using the static methods on the
primitive wrapper classes, String class, or relevant enum class).

JBoss Community Documentation

Page 509 of 617

Infinispan 6.0

7.7.2 Adding a group


In some situations you may additionally want to add a configuration grouping object, represented in XML as
an element. You might want to do this if you are adding a new area of functionality to Infinispan. Identify the
location of the new configuration grouping object. It might be added to the root Configuration object, or it
might be added to one it's children, children's children. We'll call the parent YYY in the steps below.
Create the XXXConfiguration object. Add any properties required following the guide for adding
properties. The constructors visibility should be "default".
Create the XXXConfigurationBuilder object. It should subclass the relevant configuration child builder
use the YYYConfigurationChildBuilder as the superclass. This will ensure that all builder methods
that allow the user to "escape" are provided correctly (i.e provide access to other grouping elements), and
also require you to provide a create() and validate() method. The constructor needs to take the the
YYYConfigurationBuilder as an argument, and pass this to the superclass (this simply allows access
to the root of the builder tree using the getBuilder() method).
Follow the property adding guide to add any properties you need to the builder. The create() method needs
to return a new instance of the XXXConfiguration object. Implement any validation needed in the
validate() method.
In the YYYConfiguration object, add your new configuration class as a private final field, add an
accessor, and add initialiser assignment in the constructor
In the YYYConfigurationBuilder, add your new configuration builder as a private final field, and
initialise it in the constructor with a new instance. Finally, add an accessor for it following the standard
pattern discussed in the guide.
In the YYYConfigurationBuilder ensure that your validate method is called in it's validate method, and
that result of the XXXConfiguration instances' create method is passed to the constructor of
YYYConfiguration.
Finally, add this to the parser. First, add the element to the Element class, which provides a type safe
representation of the element name in XML. In the Parser class, add a new parseXXX method, copying
one of the others that most matches your requirements (parse methods either parse elements only - look for
ParseUtils.requireNoAttributes(), attributes only look for ParseUtils.requireNoContent()
or a combination of both look for an iterator over both elements and attributes). Add any attributes as
discussed in the adding a property guide. Finally, wire this in by locating the parseYYY() method, and
adding an element to the switch statement, that calls your new parseXXX() method.

7.7.3 Don't forget to update the XSD and XSD test


Add your new elements or attributes to the XSD in src/main/resources. Update
src/test/resources/configs/all.xml to include your new elements or attributes.

JBoss Community Documentation

Page 510 of 617

Infinispan 6.0

7.7.4 Bridging to the old configuration


Until we entirely swap out the old configuration you will need to add your property to the old configuration (no
need to worry about jaxb mappings though!), and then add some code to the LegacyConfigurationAdaptor to
adapt both ways. It's fairly straightforward, just locate the relevant point in the adapt() method (near the
configuration group you are using) and map from the legacy configuration to the new configuration, or vs
versa. You will need to map both ways, in both adapt methods.

7.8 Writing Documentation and FAQs


7.8.1 Introduction
Infinispan uses this Confluence instance to store documentation and FAQs. The documentation is organised
into:
Future plans
Getting

Tutorials for using Infinispan This will be developed into a Getting Started Guide, where

Started Guide
User Guide

Glossary

each tutorial as an associated quickstart example


Goes into depth on using

This will be split into a Developer Reference Guide, a

and configuring Infinispan

Configuration Guide and a Tuning Guide

An explanation of the
terminology used by
Infinispan

Frequently

Contains both product and

Each Q&A will be moved into a document and included into

Asked

technical FAQs

the outline document

Questions
Editing and adding pages on Confluence is restricted to regular contributors to Infinispan (if you think you
should have access, or want to become a regular contributor to the documentation, then please email
infinispan-dev@lists.jboss.org.

JBoss Community Documentation

Page 511 of 617

Infinispan 6.0

7.8.2 What goes where?


Infinispan has both this Confluence instance, and the SBS instance at
http://community.jboss.org/wiki/Infinispan. Documentation and FAQs belong in Confluence, whilst design
notes, meeting notes and user contributed articles belong on SBS.

Once the final set of guides (as described in the table above) is complete, there will be additional
guidance here to describe how to decide which guide to place content in.

7.8.3 Wiki markup or rich text


You should always use wiki markup, it gives you much greater control over output format. The "Full notation
guide" link in the "Help Tips" panel to the right (on the edit page) gives a full list of markup available.

7.8.4 Markup guide


This section discusses the typical markup you would use to write a documentation chapter. The [Style and
Grammar guide] will discuss the writing style you should use.
Let's start at the beginning - headers, page structure, and the table of contents.

JBoss Community Documentation

Page 512 of 617

Infinispan 6.0

Headers, Page Structure and the Table of Contents


This Confluence instance is styled to produce structured documentation. Each node in the Infinispan space
can have children, producing a tree of nodes. Note that pages are actually stored in a flat structure in the
Infinispan space, they are just logically arranged into the tree. This means that URLs do not reflect the tree
structure, and names of documents must be unique within the space.
The child nodes of the Infinispan space represent the various guides, and the FAQs. The child nodes of
each guide represent the sections of the guides. Some sections of a guide may be further split into
subsections stored in different pages (it is likely this was done because a section was getting large).
The include macro is used to display inline the contents of the various sub pages into the top level guide
page, and if a section is made up of child pages, each child page should be inlined into the section page
using the include macro.

The include macro is not automatically updated if you change a page name!

Confluence auto-generates the table of contents (using the toc macro) for the various guides, based on the
headings used in the guide. As the include macro does not print the title of the page you are including, it is
necessary to add the title above the include macro. You should not use the toc macro except on the main
guide page.
h1 headers should only be used to name sections of guide, h2 headers to name sub-sections and so on.
You should not skip header levels. Headings should follow the same capitalization rules as a sentence - only
capitalize the first letter and proper nouns.
For an example, take a look at the wiki markup for the Contributing to Infinispan guide.

JBoss Community Documentation

Page 513 of 617

Infinispan 6.0

Marking up text
You will likely want to introduce some inline formatting for text. Here are the various styles you should use.
Style

Use

bold

Bold should be used for emphasis only. You should never use another style to give
emphasis.

italic

Italic should be used when you introduce a new piece of terminology. For example
"Infinispan is a data grid". Further uses of the term do not need to be italicised.

underline

Underline should not be used

strikethrough Strikethrough should not be used


fixed width

A fixed width font should be used whenever you refer to a class, variable, method by name,

font

whenever you make a reference to a path on filesystem, or whenever you refer to a


command the user can execute. A fixed width font should be used when referring to a
sequence of clicks required by a user in a GUI. the -> symbols should be used to indicate
the transition through a nested menu.

code block

Should be used whenever you have a multi-line code example, or are expressing an
instruction for a user to do something

quotation

Should be used whenever you refer to text someone, or something, else has written, for
example the "Help Tips" on the right hand side of the edit page. You may wish to quote a
statement to indicate that your text is not overly precise. Quotes should not be used to refer
to a variable, class or method name, or a filesystem path or command

blockquote

Should be used for multiline quotes

Color

Colored text should not be used

Lists and tables


Markup
You will normally wish to use an unordered list, however a numbered list is useful when expressing a set of
steps the user should take. There are no "definition list" macros available in Confluence, so a table makes a
good alternative.
You can make nested lists by using "double" markup.

Grammar in lists and tables


The trailing sentence in a list or a table should normally not have a full stop at the end.
Often, you will want to introduce a list or a table using a sentence. If you do this, a colon is often used to
punctuate the end of the sentence, rather than a full stop/period.

JBoss Community Documentation

Page 514 of 617

Infinispan 6.0

Links
Links should be used as normal!

Admonitions
Confluence supports three admonition styles, and you are encouraged to use them in your documentation as
they allow the flow of information to the reader to be controlled, by moving orthogonal information out of the
main body of text.
tip

A tip should be used when you want to convey useful information to the user. If the user does not
read the tip, it will have no impact on them understanding your documentation, however they will
gain useful extra information by reading the tip

note

A note should be used when you wish to convey extra information to the user. Without the
information the user may struggle to completely understand your documentation

warning A warning should be used when the there is some counter-intuitive information to be called out to
the user. For example, that the following information is out of date.
You can use the title attribute to give the admonition a title

JBoss Community Documentation

Page 515 of 617

Infinispan 6.0

Images and other media


If you are describing the use of a GUI, or showing results of some operation, images embedded in the page
can bring the documentation to life for the reader. Images can be attached to the page using the Tools
menu, and then linked. The "Full notation guide" discusses the syntax for embedding images. If you are
embedding the image to describe a series of steps taken in a GUI, it is not necessary to title your image,
otherwise you should give every image a title.
Giffy is supported in this Confluence instance, allowing you to easily create drawings online. For more, read
the Giffy documentation for more information.
Confluence supports a charting macro, however it is recommended that you embed charts as images,
generating the chart using your favourite program.
The use of the panel macro is not recommended.
Confluence allows you to natively embed video, however the use of this is not recommended, instead it is
recommended the widget macro is used to connect to Vimeo or YouTube. The [Screencasts] section
describes the creation of screencasts and upload of video to Vimeo or YouTube. To embed a video using
the widget macro simply reference the URL to the video, for example:

{widget:url=http://au.youtube.com/watch?v=-dnL00TdmLY}

This produces
You can also embed Google Docs documents, Twitter searches, slide decks from SlideShare, and
presentations from SlideRocket. Just follow the above example, substituting the URL for your media.

JBoss Community Documentation

Page 516 of 617

Infinispan 6.0

Code samples
Confluence includes a code macro, but unfortunately it is not very advanced. This Confluence instance also
supports the snippet macro which can be used to include text from other sites. The use of the snippet
macro is strongly recommended as it ensures that code samples do not get out of date. It is critical that you
add a title to the your snippet, and it is also recommended you enable linenumbers and trim the text.
For example

{snippet:title=My Code
Sample|language=none|linenumbers=true|first=2|last=5|url=github.com/infinispan/infinispan/raw/master/README.mk

Which results in:Code Snippet error: Unable to retrieve the URL:


https://github.com/infinispan/infinispan/raw/master/README.mkdn status code: 404.

The snippet macro doesn't like the default "raw" link that GitHub provides. Instead, craft a URL
like github.com/infinispan/infinispan/raw/master/README.mkdn; to do this, take the
URL from your browser, and insert raw/master after the project name and before the path to the
file.

If you want to indicate that the user needs to substitute a variable in a code sample with their own,
then use < and > around the variable name. For example, to indicate the user needs to checkout a
topic branch from git:

git checkout -b <topic>

7.8.5 Voice and grammar guide


By using a consistent voice throughout the documentation, the Infinispan documentation appears more
professional. The aim is to make it feel to the user like the documentation was written by a single person.
This can only be completely achieved by regular editing, however in order to make the workload of the editor
lighter, following these rules will produce a pretty consistent voice.
Never use abbreviations. On the other hand, contractions are fine.
Always use the project name "Infinispan". Never abbreviate it.

JBoss Community Documentation

Page 517 of 617

Infinispan 6.0
Always write in the second or third person, never the first (plural or singular forms). Use the second
person to emphasize you are giving instructions to the user.

Naturally, most people write in the first person, and, typically find it the easiest form to write,
however without a lot of care it can produce the most "unprofessional" text. Conversely,
writing in the third person is trickier, but will produce text that feels well written almost
without fail. The first person can be used for emphasis but in general it is recommended to
avoid it unless you feel confident!
Writing entirely in the third person can produce quite "dry" text, so it is recommended that
you use the second person when you are giving instructions to the user. This could be when
you are walking through a sequence of steps they should perform, or could be when you are
stating that they must do something in order for them to succeed.
So, are there any tricks to reformulate a sentence so the first person is not used?
Use the passive voice "I recommend" can become "It is recommended". However,
extensive use of the can produce boring, dry and indefinite text, so don't do this too
much!
Change the subject. For example you can change "Here we discuss" to "This section
discusses"

Use a "chatty" style. Although the use of the first person is avoided, the documentation shouldn't be
too dry. Use the second person as needed. Short sentences and good use of punctuation help too!
If you define a list, keep the ordering of the list the same whenever you express the list. For example,
if you say "In this section you will learn about interceptors, commands and factories" do not go on to
say "First, let's discuss factories". This will subconsciously confuse the user
You should only capitalize proper nouns only. For example "data grid" is lower case (it's a concept),
whilst "Infinispan" is capitalized (it's a project/product name)
You should always use American spelling. Enable a spell checker!
Use the definite article when discussing a specific instance or the indefinite article when describing a
generalization of something; generally you omit the article when using a name for a project or product.

Infinispan uses a logging framework to communicate messages to the user, the


logging framework used by Infinispan is JBoss Logging.
Let's dig into this. First, the sentence states that "Infinispan uses logging", and the indefinite
article is used - we are not stating which of many possibilities is used. Second, the sentence
goes on to discuss the logging framework Infinispan uses, and here the definite article is
used, as the specific framework in use is discussed. Finally, the sentence is concluded by
stating that the logging framework used is called "JBoss Logging", and as this is a product
name, no article is used.
This is not a formal or complete description, but is a good rule of thumb.

JBoss Community Documentation

Page 518 of 617

Infinispan 6.0
Keep the tense the same. It's very easy to slip between the present, past and future tenses, but this
produces text that is feels "unnatural" to the reader. Here's an example:

Data is collected from Infinispan every hour. Upon analysis the data showed that
Infinispan is 2 million times faster than it's nearest competitor
You may not have noticed, but the phrase starts using the present tense ( is) and slips into
the past tense (showed). This is clearly not actually the order in which the events
happened!
Of course, if you are actually describing the progression of time, then changing tenses is
fine. For example:
In the last section you were shown how to configure Infinispan using XML, and in the
next section you will be shown how to configure Infinispan programmatically.

If you are telling the user about a procedure they can follow, do be explicit about this, and enumerate
the steps clearly

7.8.6 Glossary
When writing a glossary entry, you should follow the Basically Available, Soft-state, Eventually-consistent
(BASE) as a template.
If the entry is commonly referred to using an acronym, then the title should consistent of the fully
expanded name, with the acronym in brackets. You can then use the acronym always within the main
text body
If you want to refer to other glossary articles using links in the text body, then just link them with no
alternative text
If you want to make external links (e.g. wikipedia, user guide), then add a h2 header "More
resources", and list them there. This clearly indicates to users when they are moving outside of our
definitions

7.8.7 Screencasts
TODO

JBoss Community Documentation

Page 519 of 617

Infinispan 6.0

7.9 Managing this confluence instance.


On a minor release we clone this space to a versioned name (e.g. ISPN51), leaving the ISPN space
available for development in HEAD. To do this, visit Browse -> Space Admin and choose Permissions and
make sure you have Space Admin and Space Export permissions. Then, visit Copy Space, and fill in the
name (e.g. Infinispan 5.1) and key (e.g. ISPN51). Make sure all the boxes are checked, and click Save.
Finally, you'll need to update the name of the ISPN space to reflect the minor version of the development in
HEAD (e.g. Infinispan 5.2). You can do this in Space Details.

7.10 Contributing - The Basics


In this chapter we quickly walk through the basics on contributing; future chapters go into more
depth.

7.10.1 requisites
Java 1.6

Infinispan is baselined on Java 6.0, and is built and tested using Sun Java 6.0.

Maven 3

The Infinispan build uses Maven, and we recommend using Maven 3.

Git

The Infinispan sources are stored in Git. If you don't wish to install Git, you can download

(optional)

source bundles

7.10.2 Issue Management - JIRA


Infinispan uses JIRA for issue management, hosted on issues.jboss.org. You can log in using your normal
jboss.org username and password.
If you need to create a new issue then follow these steps.

JBoss Community Documentation

Page 520 of 617

Infinispan 6.0

1. Choose between
Feature Request if you want to request an enhancement or new feature for Infinispan
Bug if you have discovered an issue
Task if you wish to request a documentation, sample or process (e.g. build system)
enhancement or issue
2. Then enter a Summary, describing briefly the problem - please try to be descriptive!
3. You should not set Priority.
4. Now, enter the version you are reporting an issue against in the Affects Version field, and leave the
Fix Version field blank.
5. In the Environment text area, describe in as much detail as possible your environment (e.g. Java
runtime and version, operating system, any network topology which is relevant).
6. In the Description field enter a detailed description of your problem or request.
7. If the issue has been discussed on the forums or the mailing list, enter a reference in the Forum
Reference field
8. Finally, hit Create

Versioning Guidelines
Only Infinispan contributors should set the Fix Version field.

When setting the Fix Version field for bugs and issues in JIRA, the following guidelines apply:
Version numbers are defined as MAJOR.MINOR.MICRO.MODIFIER. For example, 4.1.0.BETA1 would be:
MAJOR

MINOR

MICRO

MODIFIER BETA1
If the issue relates to a Task or Feature Request, please ensure that the .FINAL version is included in the
Fixed In field. For example, a new feature should contain 4.1.0.BETA1, 4.1.0.FINAL if it is new for 4.1.0 and
was first made public in BETA1. For example, see ISPN-299.
If the issue relates to a bug which affected a previous FINAL version, then the Fixed In field should also
contain the .FINAL version which contains the fix, in addition to any ALPHA, BETA or CR release. For
example, see ISPN-546.
If the issue pertains to a bug in the current release, then the .FINAL version should not be in the Fixed In
field. For example, a bug found in 4.1.0.ALPHA2 (but not in 4.1.0.ALPHA1) should be marked as fixed in
4.1.0.ALPHA3, but not in 4.1.0.FINAL. For example, see ISPN-416.

JBoss Community Documentation

Page 521 of 617

Infinispan 6.0

7.10.3 Source control - Git


Infinispan uses git, hosted on GitHub, for version control. You can find the upstream git repository at
https://github.com/infinispan. To clone the repository:

$ git clone git@github.com:infinispan/infinispan.git

or to clone your fork:

$ git clone git@github.com:YOUR_GITHB_USERNAME/infinispan.git

For more information, read the Git chapter.

Setting up your IDE


Maven supports generating IDE configuration files for easy setup of a project. Tested are Eclipse, IntelliJ
IDEA and Netbeans.
Before we import the project, we need to clone the project as described above.

Eclipse
1. Install the m2eclipse plugin if you have not already installed it. Eclipse is including it since version
"Indigo" 3.7, for older versions follow instructions at http://eclipse.org/m2e/.
2. Import the Infinispan maven project. Select File -> Import in your eclipse workbench. Select the
Existing Maven Project importer.

JBoss Community Documentation

Page 522 of 617

Infinispan 6.0
3. Select the root directory of your Infinispan checkout.

4. Select Infinispan modules that you want to import.

JBoss Community Documentation

Page 523 of 617

Infinispan 6.0
5. Finally, from Infinispan 5.0 onwards, annotation processing is used to allow log messages to be
internationalized. This processing can be done directly from Eclipse as part of compilation but it
requires some set up:
1. Open the properties for infinispan-core and locate Annotation Processing
2. Tick Enable project specific settings
3. Enter target/generated-sources/annotations as the Generated source
directory

Code Formatting. From the menu Window->Preferences-> select Java -> Code Style -> Formatter. Import
formatter.xml
Code template. From the menu Window->Preferences-> select Java -> Code Style -> Code Templates.
Import codetemplates.xml
Some modules use Scala, if you plan contributing to one of these modules it's worth installing the Scala tools
.

JBoss Community Documentation

Page 524 of 617

Infinispan 6.0

IntelliJ IDEA
Importing
When you start IntelliJ, you will be greeted by a screen as shown below:

JBoss Community Documentation

Page 525 of 617

Infinispan 6.0

If you have already obtained a copy of the Infinispan sources via Github (see 'Source Control'), then
simply follow: Import Project -> /directory/to/downloaded/sources. IntelliJ will automatically make
use of maven to import the project since it will detect a pom.xml file in the base directory.
If you have not obtained the sources already, you can simply use the Git integration provided within
IntelliJ 12. Click on Check out from Version Control -> Github. After entering your Github
credentials, you will then be prompted to enter the git repository URL along with the location that you
want to check out the source code to.

JBoss Community Documentation

Page 526 of 617

Infinispan 6.0

Compiler settings
From Infinispan 5.0 onwards, annotation processing is used to allow log messages to be
internationalized. This processing can be done directly from IntelliJ as part of compilation but it
requires some set up:
Go to "Preferences/Compiler/Annotation Processor" and click on Enable annotation processing
Add an annotation processor with "Processor FQN Name" as
org.jboss.logging.LoggingToolsProcessor
In "Processed Modules", add all modules except the root and the parent modules.

There can sometimes be issues with the generated logging classes on rebuild (particularly when you
switch Git branches). If these issues do crop up then simply run mvn clean install -DskipTests=true
on the command line to clear them out.
EXTRA: If you are running a multi-core environment (e.g. quad-core or above) then you can follow the
instructions on making use of parallelized compilation in IntelliJ 12. Information on how to do this can
be found here.

JBoss Community Documentation

Page 527 of 617

Infinispan 6.0

Scala Plugin
You will need to download the Scala plugin for IntelliJ as well. This can be done by: Project Settings
-> Plugins -> Browse Repositories. Then run a search for 'Scala'. JetBrains themselves are the
vendor for this plugin and more information on it can be found here.

You also have to configure the Scala plugin to use the Scala compiler for Scala files and the Java
compiler for Java files. You can do this by going into Settings -> Compiler -> Scala Compiler. Be
sure to add the scala compiler bundle as shown in the screenshot below.

Code Style
You can find the code style .jar file for IntelliJ in the Infinispan source download. It is located in
/path/to/infinispan/home/ide-settings/intellij.

JBoss Community Documentation

Page 528 of 617

Infinispan 6.0

7.10.4 Build - Maven


Infinispan uses Maven for builds. Make sure you have Maven 3 installed, and properly configured. For more
information, read the Maven chapter.

Continuous Integration - TeamCity


Infinispan TeamCity for continuous integration. TeamCity polls GitHub for updates and runs whenever
updates are available. You can check the status of the latest builds here.

7.10.5 Testing - TestNG


Infinispan uses TestNG for unit and functional tests, and all Infinispan tests are run in parallel. For more
information see the Test Suite chapter; this chapter gives advice on writing tests which can safely execute in
parallel.

7.10.6 Communicating with other Infinispan contributors


Infinispan contributors use a mix of mailings lists and IRC to communicate ideas and designs, with more
detailed designs often making their way into wiki pages.

JBoss Community Documentation

Page 529 of 617

Infinispan 6.0

7.10.7 Style Requirements


Infinispan uses the K&R code style for all Java source files, with two exceptions:
use 3 spaces instead of a tab character for indentations.
braces start on the same line for class, interface and method declarations as well as code blocks.
In addition, sure all new line characters used must be LF (UNIX style line feeds). Most good IDEs allow you
to set this, regardless of operating system used.
All patches or code committed must adhere to this style. Code style settings which can be imported into
IntelliJ IDEA and Eclipse are committed in the project sources, in ide-settings.

Spelling
Ensure correct spelling in code, comments, Javadocs, etc. (use American English spelling). It is
recommended that you use a spellchecker plugin for your IDE.

License header
All source files must have up-to-date license headers as described in Copyright Ownership and Licenses.
Never remove existing headers or copyrights.

Check-in comments
Please ensure any commit comments use this format if related to a task or issue in JIRA. This helps JIRA
pick out these checkins and display them on the issue, making it very useful for back/forward porting fixes. If
your comment does not follow this format, your commit may not be merged into upstream.

7.10.8 Configuration
Infinispan offers both programmatic configuration and XML configuration. For more information read the
Configuration chapter.

7.10.9 Logging
Infinispan follows the JBoss logging standards, which can be found here.
From Infinispan 5.0 onwards, Infinispan uses JBoss Logging to abstract over the logging backend. Infinispan
supports localization of log message for categories of INFO or above as explained in the JBoss Logging
guidelines. As a developer, this means that for each INFO, WARN, ERROR, FATAL message your code emits,
you need to modify the Log class in your module and add an explicit method for it with the right annotations.
For example:

JBoss Community Documentation

Page 530 of 617

Infinispan 6.0

@LogMessage(level = INFO)
@Message(value = "An informative message: %s - %s", id = 600)
void anInformativeMessage(String param1, String param2);

And then, instead of calling log.info(...), you call the method, for example
log.anInformativeMessage(param1, param2). If what you're trying to log is an error or similar
message and you want an exception to be logged as cause, simply use @Cause annotation, example:

@LogMessage(level = ERROR)
@Message(value = "An error message: %s", id = 600)
void anErrorMessage(String param1, @Cause IllegalStateException e);

The last thing to figure out is which id to give to the message. Each module that logs something in
production code that could be internationalized has been given an id range, and so the messages should
use an available id in the range for the module where the log call resides. Here are the id range assignments
per module:

JBoss Community Documentation

Page 531 of 617

Infinispan 6.0

Module name

Id range

core

1 - 1000

tree

2001 - 3000

bdbje cache store

2001 - 3000

cassandra cache store

3001 - 4000

hotrod client

4001 - 5000

server core

5001 - 6000

server hotrod

6001 - 7000

cloud cache store

7001 - 8000

jdbc cache store

8001 - 9000

jdbm cache store

9001 - 10000

remote cache store

10001 - 11000

server memcached

11001 - 12000

server rest

12001 - 13000

server websocket

13001 - 14000

query

14001 - 15000

lucene directory

15001 - 16000

rhq plugin

16001 - 17000

cdi integration

17001 - 18000

hbase cache store

18001 - 19000

cli interpreter

19001 - 20000

cli client

20001 - 21000

mongodb cache store

21001 - 22000

jpa cache store

22001 - 23000

leveldb cache store

23001 - 24000

couchbase cache store 24001 - 25000

When editing the above table, remember to update the README-i18n.txt file in the project sources!

JBoss Community Documentation

Page 532 of 617

Infinispan 6.0

You will need to enable annotation processing in order to be able to compile Infinispan and have
the logger implementation generated.

7.11 Contributing - Source Control


As a convention, upstream is used as the name of the http://github.com/infinispan/infinispan
repository. This repository is the canonical repository for Infinispan. We usually name origin the fork
on github of each contributor. So the exact meaning of origin is relative to the developer: you could
think of origin as your own fork.

7.11.1 requisites
This document assumes some working knowledge of git. We recommend Scott Chacon's excellent Pro Git
as a valuable piece of background reading. The book is released under the Creative Commons license and
can be downloaded in electronic form for free. At very least, we recommend that Chapter 2, Chapter 3 and
Chapter 5 of Pro Git are read before proceeding.

7.11.2 Repositories
Infinispan uses http://github.com/infinispan/infinispan as its canonical repository, and this repository contains
the stable code on master (currently Infinispan 5.x) as well as the maintenance branches for 4.2.x, 4.1.x and
4.0.x.
Typically, only Project Admins would be able to push to this repo while all else may clone or fork this repo.

7.11.3 Roles
The project assumes one of 3 roles an individual may assume when interacting with the Infinispan
codebase. The three roles here are:
Project Admin (typically, no more than 3 or 4 people)
Frequent Contributor
Occasional Contributor

JBoss Community Documentation

Page 533 of 617

Infinispan 6.0

None of the roles assume that you are a Red Hat employee. All it assumes is how much
responsibility over the project has been granted to you. Typically, someone may be in more than
one role at any given time, and puts on a different "hats" based on the task at hand.

Occasional Contributor
This role defines a user who browses through the source code of the project and occasionally submits
patches. Patches may be submitted in one of two ways:
Attach a patch file to the JIRA issue
Creating a pull request on GitHub
The approach a contributor chooses to use depends entirely his/her personal preference, but usually is tied
to how the contributor accesses Infinispan's source code. If the contributor directly clones the upstream
repository, they should submit patch files. If the contributor instead uses their personal GitHub account to
fork the upstream repository, then they are should issue a pull request.

A GitHub pull request is the preferred method to submit a patch!

JBoss Community Documentation

Page 534 of 617

Infinispan 6.0

Attach a patch file to the JIRA issue

In this workflow, the contributor directly clones the upstream repository, makes changes to his local clone,
adequately tests and commits his work with proper comments (more on commit comments later), and
generates a patch. The patch should then be attached to the JIRA issue.
More information on generating patches suitable for attaching to a JIRA can be found in Chapter 5, Section 2
of Pro Git, under the section titled Public Large Project .

Rather than emailing the patches to a developer mail list, please attach your patch to the JIRA
issue.

Creating a pull request on GitHub

JBoss Community Documentation

Page 535 of 617

Infinispan 6.0
In this workflow, the contributor forks the Infinispan upstream repository on GitHub, clones their fork, and
makes changes to this private fork. When changes have been tested and are ready to be contributed back to
the project, a pull request is issued via GitHub so that one of the Project Administrators can pull in the
change.

Topic Branches
It is desirable to work off a topic branch, even when using your own, forked repository. A topic
branch is created for every feature or bug fix you do. Typically you would create one topic branch
per issue, but if several patches are related it's acceptable to have several commits in the same
branch; however different changes should always be identified by different commits.

Before you push your work onto your fork of the repository, it is often a good idea to review your commits.
Consolidating them (squashing) or breaking them up as necessary and cleaning up commit messages
should all be done while still working off your local clone. Also, prior to issuing a pull request, you should
make sure you rebase your branch against the upstream branch you expect it to be merged into. Also, only
submit pull requests for your branch - not for your master!
The section on Public Small Project in Chapter 5, Section 2 of Pro Git has more information on this style of
workflow.

A worked example
1. Make sure your master is synced up with upstream. See this section for how to do this
2. Create new branch for your topic and switch to it. For the example issue, ISPN-1234:

git checkout -b ISPN-12345 master

3. Do your work. Test. Repeat


4. Commit your work on your topic branch
5. Push your topic branch to GitHub. For example:

git push origin ISPN-12345

6. Issue a pull request using the GitHub pull request system


7. Once your pull request has been applied upstream, delete the topic branch both locally and on your
fork. For example:

git branch -d ISPN-12345 && git push origin :ISPN-12345

8. Sync with upstream again so that your changes now appear in your master branch
If your topic branch has been open for a while and you are afraid changes upstream may clash with your
changes, it makes sense to rebase your topic branch before you issue a pull request. To do this:

JBoss Community Documentation

Page 536 of 617

Infinispan 6.0

1. Sync your master branch with upstream

git checkout master


git pull upstream master

2. Switch to your topic branch. For example:

git checkout ISPN-12345

3. Rebase your topic branch against master:

git rebase master

4. During the rebase process you might need to fix conflicts;


5. when you're done test your code again.
6. Push your rebased topic branch to your repo on GitHub (you will likely need to force this with the -f
option).

git push -f origin ISPN-12345

7. Continue your work on your topic branch.

If you are sharing your forked Infinispan repo with others, then do not rebase! Use a merge instead.

JBoss Community Documentation

Page 537 of 617

Infinispan 6.0

Multi-step coordination between developers using forked repositories


Sometimes a feature/task is rather complex to implement and requires competence from multiple areas of
the projects. In such occasions it is not uncommon for developers to coordinate feature implementation
using personal forks of Infinispan prior to finally issuing request to integrate into Infinispan main repository on
GitHub.
For example, developer A using his personal Infinispan fork creates a topic branch T and completes as
much work as he/she can before requesting for assistance from developer B. Developer A pushes topic T to
his personal Infinispan fork where developer B picks it up and brings it down to his local repo. Developer B
then in turn completes necessary work, commits his/her changes on branch T, and finally pushes back T to
his own personal fork. After issuing request for pull to developer A, developer B waits for notification that
developer A integrated his changes. This exchange can be repeated as much as it is necessary and can
involve multiple developers.

A worked example
This example assumes that developer A and B have added each others Infinispan forked repositories with
the git add remote command. For example, developer B would add developer A's personal Infinispan
fork repository with the command

git remote add devA https://github.com/developerA/infinispan.git

1. Developer A starts implementing feature ISPN-244 and works on a local topic branch ispn244
Developer A pushes ispn244 to personal Infinispan fork. For example:

git push origin ispn244

2. Developer B fetches branch ispn244 to local repository. For example:

git fetch devA ispn244:my_ispn244

3. Developer B works on local branch my_ispn244


4. Developer B commits changes, pushes my_ispn244 to own fork.

git push origin my_ispn244

5. Developer B sends pull request to developer A to integrate changes from my_ispn244 to ispn244

JBoss Community Documentation

Page 538 of 617

Infinispan 6.0

Frequent Contributor
A frequent contributor will only ever submit patches via a pull requests. The pull request will be submitted via
GitHub.
Frequent contributors should always fork the upstream project on GitHub and work off a clone of this fork.
This is very similar to Creating a pull request on GitHub workflow used by a Occasional Contributor.

All Infinispan core developers are considered frequent contributors and work off personal forks of
the upstream repository. This allows for complex features to be developed in parallel without
tripping up over one another. This process is certainly not restricted to just Infinispan core
developers; any contributor is welcome to also participate in this manner.

Project Admin
Project Admins have a very limited role. Only Project Admins are allowed to push to upstream, and Project
Admins never write any code directly on the upstream repository. All Project Admins do is pull in and merge
changes from contributors (even if the "contributor" happens to be themselves) into upstream, perform code
reviews and either commit or reject such changes.

All Contributors who are also Project Admins are encouraged to not merge their own changes, to
ensure that all changes are reviewed.

This approach ensures Infinispan maintains quality on the main code source tree, and allows for important
code reviews to take place again ensuring quality. Further, it ensures clean and easily traceable code history
and makes sure that more than one person knows about the changes being performed.

JBoss Community Documentation

Page 539 of 617

Infinispan 6.0

Merging in patches

Patches submitted via JIRA are audited and promoted to the upstream repository as detailed above. A
Project Admin would typically create a working branch to which the patch is applied and tested. The patch
can be further modified, cleaned up, and commit messages made clearer if necessary. The branch should
then be merged to the master or one of the maintenance branches before being pushed.
More information on applying patches can be found in Chapter 5, Section 3 of Pro Git, under Applying
Patches From Email.

Handling pull requests

Project Admins are also responsible for responding to pull requests. The process is similar to applying a
patch directly, except that when pulling in changes from a forked repository, more than a single commit may
be pulled in. Again, this should be done on a newly created working branch, code reviewed, tested and
cleaned up as necessary.

JBoss Community Documentation

Page 540 of 617

Infinispan 6.0
If commits need to be altered - e.g., rebasing to squash or split commits, or to alter commit messages - it is
often better to contact the Contributor and ask the Contributor to do so and re-issue the pull request, since
doing so on the upstream repo could cause update issues for contributors later on. If commits were altered
or three-way merge was performed during a merge instead of fast-forward, it's also a good idea to check the
log to make sure that the resulting repository history looks OK:

$ git log --pretty=oneline --graph --abbrev-commit # History messed up due to a bad merge
*
3005020 Merge branch 'ISPN-786' of git://github.com/Sanne/infinispan
|\
| * e757265 ISPN-786 Make dependency to log4j optional <-- Same with cb4e5d6 - unnecessary
* | cb4e5d6 ISPN-786 Make dependency to log4j optional <-- Cherry-picked commit by other admin
|/
* ...
$ git reset cb4e5d6

# revert the bad merge

It is therefore strongly recommended that you use the handle_pull_request script that ensures a clean
merge. If you still wish to do this manually, please consider reading through the script first to get an idea of
what needs to happen.
More information on pulling changes from remote, forked repos can be found in Chapter 5, Section 3 of Pro
Git, under Checking Out Remote Branches .

Possible trouble handling pull requests


1. If you have warnings about "Merge made by recursive" you have to fix it rebasing.
2. If you have warnings about "non-fast-forward" you have to rebase.
3. If you see "non-fast-forward updates were rejected" you shall never use "force" on upstream! It means
that another patch was merged before you and you have to update your master again, and rebase
again.
4. "force" is allowed only in special maintenance circumstances. If you find you're needing it to handle a
pull request, then you're doing it wrong, and the mistake might be a dangerous one! It's like the good
rule of never commit when you're drunk (coding is allowed).

Never use force on git push


Using -f while pushing on a shared repository such as upstream you could effectively erase other
committed patches. Noone shall ever use this option unless unanimously approved on the public
mailing list: the most dangerous aspect of it is that nobody gets any notification if this happens, and
we might think issues are solved but you silently removed the fix and it's history from the repository.

Cutting releases
Releases can only me cut by Project Admins, and must be done off a recently updated (git fetch and git pull
origin) clone of the upstream repo. Infinispan's release.py script takes care of the rest.

JBoss Community Documentation

Page 541 of 617

Infinispan 6.0

7.11.4 Contributor License Agreement (CLA)


Contributors that submit patches to Infinispan, if they're not employed by Red Hat, are required to sign the
Contributor License Agreement (CLA) following the instructions in our dedicated site.

7.11.5 Committing your work


Release branches
Infinispan has 4 main release branches. These are master (ongoing work on the 5.0.x series), 4.2.x (ongoing
work on the 4.2.x series), 4.1.x and 4.0.x (respective maintenance branches). Work should never be
committed directly to any of these release branches; topic branches should always be used for work, and
these topic branches should be merged in.

JBoss Community Documentation

Page 542 of 617

Infinispan 6.0

Topic branches
Some of the biggest features of git are speed and efficiency of branching, and accuracy of merging. As a
result, best practices involve making frequent use of branches. Creating several topic branches a day, even,
should not be considered excessive, and working on several topic branches simultaneously again should be
commonplace.
Chapter 3, Section 4 of Pro Git has a detailed discussion of topic branches. For Infinispan, it makes sense to
create a topic branch and name it after the JIRA it corresponds to. (if it doesn't correspond to a JIRA, a
simple but descriptive name should be used).

Topic Branches Affecting More Than One Release Branch


Most topic branches will only affect a single release branch, e.g. Infinispan 5.0 features only affect the
master release branch, so a topic branch should be created based off master. However, occasionally, fixes
may apply to both release branches 4.2.x as well as master. In this case, the following workflow should
apply:
Create topic branch off 4.2.x. For example:

git checkout -b <topic>_4.2.x 4.2.x

Create topic branch off master. For example:

git checkout -b <topic>_master master

Do your work on <topic>_master, test and commit your fixes


Switch to <topic>_4.2.x. For example:

git checkout <topic>_4.2.x

Cherry-pick your commit on <topic>_master onto <topic>_4.2.x. For example:

git cherry-pick <commit_id>

Test <topic>_4.2.x for correctness, modify as necessary


Issue pull requests for both topic branches

JBoss Community Documentation

Page 543 of 617

Infinispan 6.0

Comments
It is extremely important that comments for each commit are clear and follow certain conventions. This
allows for proper parsing of logs by git tools. Read this article on how to format comments for git and adhere
to them. Further to the recommendations in the article, the short summary of the commit message should be
in the following format:

ISPN-XXX Subject line of the JIRA in question

This can optionally be followed by a detailed explanation of the commit. Why it was done, how much of it
was completed, etc. You may wish to express this as a list, for example:

*
*
*
*

Add a unit test


Add more unit tests
Fix regressions
Solve major NP-Complete problems

Make sure however to split separate concerns - especially if they are unrelated - in separate commits.
It might happen that a single commit fixes multiple JIRAs. This shouldn't be the norm, but if it happens, it's
recommended that all JIRA ids are specified in the title of commit, followed by a more detailed explanation
following the example above e.g.

ISPN-XXX ISPN-YYYY Summary of JIRA issues


* Fix ISPN-XXXX by doing...
* Fix ISPN-YYYY by doing...

Commits
Sometimes work on your topic branch may include several commits. For example, committing a test. Then
committing another test. Then perhaps committing a fix. And perhaps fixing your own fix in the next commit...
Before issuing a pull request for this topic branch, consider cleaning up these commits. Interactive rebasing
helps you squash several commits into a single commit, which is often more coherent to deal with for others
merging in your work. Chapter 6, Section 4 of Pro Git has details on how to squash commits and generally,
clean up a series of commits before sharing this work with others. Note that you can also easily reorder
them, just change the order of lines during the interactive rebase process.
Also, it is important to make sure you don't accidentally commit files for which no real changes have
happened, but rather, whitespace has been modified. This often happens with some IDEs. git diff
--check should be run before you issue such a pull request, which will check for such "noise" commits and
warn you accordingly. Such files should be reverted and not be committed to the branch.
Adhering to Infinispan's code style guidelines will help minimise "noise" commits. Project Admins are going
to ask contributors to reformat their code if necessary.

JBoss Community Documentation

Page 544 of 617

Infinispan 6.0

7.11.6 Keeping your repo in sync with upstream


If you have cloned upstream
If you have a clone of the upstream, you may want to update it from time to time. Running:

$ git fetch origin


$ git fetch origin --tags

will often do the trick. You could then pull the specific branches you would need to update:

$
$
$
$

git
git
git
git

checkout master
pull origin master
checkout 4.2.x
pull origin 4.2.x

Updating topic branches


You should rebase your topic branches at this point so that they are up-to-date and when pulled by
upstream, upstream can fast-forward the release branches:

$ git checkout <topic>_master


$ git rebase master

and/or

$ git checkout topic_4.2.x


$ git rebase 4.2.x

JBoss Community Documentation

Page 545 of 617

Infinispan 6.0

If you have forked upstream


If you have a fork of upstream, you should probably define upstream as one of your remotes:

$ git remote add upstream git://github.com/infinispan/infinispan.git

You should now be able to fetch and pull changes from upstream into your local repository, though you
should make sure you have no uncommitted changes. (You do use topic branches, right?)

$
$
$
$
$
$
$
$

git
git
git
git
git
git
git
git

fetch upstream
fetch upstream --tags
checkout master
pull upstream master
push origin master
checkout 4.2.x
pull upstream 4.2.x
push origin 4.2.x

A script can do this for you - have a look at sync_with_upstream.

Updating topic branches


Again, you should rebase your topic branches at this point so that they are up-to-date and when pulled by
upstream, upstream can fast-forward the release branches:

$ git checkout topic_master


$ git rebase master

and/or

$ git checkout topic_4.2.x


$ git rebase 4.2.x

The sync_with_upstream script can do this for you if your topic branch naming conventions match the script.

JBoss Community Documentation

Page 546 of 617

Infinispan 6.0

7.11.7 Tips on enhancing git


Auto-completions
Save this script as /.git-completion.bash and in /.bash_profile, add the following on one line:
source ~/.git-completion.bash

After logging out and back in again, typing git <TAB> will give you a list of git commands, as would git
c<TAB>, etc. This even works for options, e.g. git commit --<TAB>. The completions are even aware of
your refs, so even git checkout my_br<TAB> will complete to git checkout my_branch!
Note that you get git autocompletion for free if you use zsh instead of bash.

Terminal colours
Add the following to your ~/.gitconfig

[color]
ui = yes
[color "branch"]
current = yellow reverse
local = yellow
remote = green
[color "diff"]
meta = yellow bold
frag = magenta bold
old = red bold
new = green bold
[color "status"]
added = yellow
changed = green
untracked = cyan

JBoss Community Documentation

Page 547 of 617

Infinispan 6.0

Aliases
Some git commands are pretty long to type, especially with various switches. Aliases help you to map
shortcuts to more complex commands.; Again, For example, add the following to ~/.gitconfig:

[alias]
co = checkout
undo = reset --hard
cb = checkout -b
br = branch
cp = cherry-pick
st = status
l = log --pretty=oneline --decorate --abbrev-commit
lg = log --decorate --abbrev-commit
last = log --decorate -1 -p --abbrev-commit
ci = commit -a
pom = push origin master
graph = log --pretty=oneline --graph --abbrev-commit
dt = difftool

Visual History
Git ships with gitk, a GUI that visually represents a log. If you use Mac OS X, GitX is a good alternative. Try
typing gitk or gitx in a git project directory.
For Linux users, there are lots of alternatives: gitk, gitg, giggle, ... up to egit for Eclipse.

Visual diff and merge tools


There are several options available, including KDiff3, meld and Perforce's P4Merge which are all either open
source or available for free. See this link on setting these up (section under External Merge and Diff Tools)

Choosing an Editor
You can customise the editor used by git editing ~/.gitconfig. The following fires up MacVIM instead of
the default vi editor:

[core]
editor = mvim -f

Alternatively, you could fire up TextMate or another editors of your choice.

JBoss Community Documentation

Page 548 of 617

Infinispan 6.0

Shell prompt
You can change your Bash shell prompt to print the current repository's branch name. Add the following to
your ~/.bashrc:

function git_current_branch {
git branch --no-color 2> /dev/null | sed -e '/^[^*]/d' -e 's/* \(.*\)/[\1]/'
}
if [ "$PS1" ]; then
PS1='[\u@\h:\W]$(git_current_branch)\$ '
fi

The resulting shell prompt will look like:

trustin@matrix:infinispan-4.2][4.2.x]$

If you're a ZSH user, you can get even more interesting branch information thanks to this blog post, such as:
whether your branch is dirty ()
whether it's ahead of the remote()
whether it diverges with the remote ()
whether it's behind ()
For example, the following prompt indicates that the current branch is 't_ispn775_master' and that the
branch is dirty:

[~/Go/code/infinispan.git]% (t_ispn775_master)

7.12 Contributing - The build


Infinispan uses Maven as a build system.

7.12.1 Requirements
Java 6.0 or above
Maven 3 or above

JBoss Community Documentation

Page 549 of 617

Infinispan 6.0

Make sure you follow the steps outlined in Maven Getting Started - Users to set up your JBoss
repository correctly. This step is crucial to ensure your Maven setup can locate JBoss artifacts! If
you also want to test the EAP integration modules you should also add the appropriate Enterprise
Red Hat Maven Repository.

The following is an example settings.xml to get you started:

<settings xmlns="http://maven.apache.org/SETTINGS/1.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/SETTINGS/1.0.0
http://maven.apache.org/xsd/settings-1.0.0.xsd" >
<localRepository/>
<interactiveMode/>
<usePluginRegistry/>
<offline/>
<proxies/>
<profiles>
<profile>
<id>jboss-public-repository</id>
<repositories>
<repository>
<id>jboss-public-repository-group</id>
<name>JBoss Public Maven Repository Group</name>
<url> https://repository.jboss.org/nexus/content/groups/public-jboss/ </url>
<layout>default</layout>
<releases>
<enabled>true</enabled>
<updatePolicy>never</updatePolicy>
</releases>
<snapshots>
<enabled>true</enabled>
<updatePolicy>never</updatePolicy>
</snapshots>
</repository>
</repositories>
<pluginRepositories>
<pluginRepository>
<id>jboss-public-repository-group</id>
<name>JBoss Public Maven Repository Group</name>
<url> https://repository.jboss.org/nexus/content/groups/public-jboss/ </url>
<layout>default</layout>
<releases>
<enabled>true</enabled>
<updatePolicy>never</updatePolicy>
</releases>
<snapshots>
<enabled>true</enabled>
<updatePolicy>never</updatePolicy>
</snapshots>
</pluginRepository>
</pluginRepositories>
</profile>

JBoss Community Documentation

Page 550 of 617

Infinispan 6.0

<!-- Include early access of application server and other products -->
<profile>
<id>redhat-earlyaccess-repository</id>
<repositories>
<repository>
<id>redhat-earlyaccess-repository-group</id>
<name>Red Hat early access repository</name>
<url> http://maven.repository.redhat.com/earlyaccess/all/ </url>
<layout>default</layout>
<releases>
<enabled>true</enabled>
<updatePolicy>never</updatePolicy>
</releases>
<snapshots>
<enabled>true</enabled>
<updatePolicy>never</updatePolicy>
</snapshots>
</repository>
</repositories>
</profile>
</profiles>
<activeProfiles>
<activeProfile>jboss-public-repository</activeProfile>
<activeProfile>redhat-earlyaccess-repository</activeProfile>
</activeProfiles>
</settings>

7.12.2 Quick command reference


Maven places it's output in target/

JBoss Community Documentation

Page 551 of 617

Infinispan 6.0

mvn clean

Cleans out any old builds and binaries

mvn compile

Compiles java source code

mvn test

Runs the TestNG unit test suite on the compiled code. Will also
compile the tests. See the testing section below for more
information on running different test groups. The default test group
run is the "unit" group.

mvn package

Packages the module as a JAR file, the resulting JAR file will be in
target/

mvn package

Creates a JAR file without running tests

-Dmaven.test.skip.exec=true
mvn package

Creates a reduced version of the distribution with all

-Dmaven.test.skip.exec=true modules,scripts...etc but no javadoc or source code. This is very


handy to quickly build the distribution in order to run some tests.
-P minimal-distribution
mvn install

Installs the artifacts in your local repo for use by other

-Dmaven.test.skip.exec=true projects/modules, including inter-module dependencies within the


same project.
mvn install -P

In addition to install, will also use Maven's assembly plugin to build

distribution

ZIP files for distribution (in target/distribution). Contents of


various distribution are controlled by the files in
src/main/resources/assemblies.

mvn deploy

Builds and deploy the project to the JBoss snapshots repository.

mvn -Pgenerate-schema-doc

Builds the configuration reference HTML file

install -DskipTests=true
-pl core && firefox
core/target/xsd_doc
mvn install -P-extras

Avoids the extras profile disables the enforce plugin, generation of


source jars and OSGI bundleconstruction, hence making builds run
faster. Clearly, this option should not be used when making a
release or publishing a snapshot.

For non-snapshot releases (e.g., alphas, betas, release candidates and final releases) you should
use the bin/release.py script.

JBoss Community Documentation

Page 552 of 617

Infinispan 6.0

7.12.3 Publishing releases to Maven


To be able to publish releases to Maven, you need to have the following in your
${HOME}/.m2/settings.xml file:

<settings>
...
<servers>
...
<server>
<id>jboss-snapshots-repository</id>
<username>your JBoss.org username</username>
<password>your JBoss.org password</password>
</server>
<server>
<id>jboss-releases-repository</id>
<username>your JBoss.org username</username>
<password>your JBoss.org password</password>
</server>
...
</servers>
...
</settings>

Publishing snapshots
Simply running

$ mvn clean deploy -Dmaven.test.skip.exec=true

in the Infinispan root directory will deploy a snapshot.

Publishing releases
Use the bin/release.py script.

7.12.4 The Maven Archetypes


Infinispan currently has 2 separate Maven archetypes you can use to create a skeleton project and get
started using Infinispan. This is an easy way to get started using Infinispan as the archetype generates
sample code, a sample Maven pom.xml with necessary depedencies, etc.

JBoss Community Documentation

Page 553 of 617

Infinispan 6.0

You don't need to have any experience with or knowledge of Maven's Archetypes to use this! Just
follow the simple steps below.

These archetypes have only been tested with Maven 3. Please report back if you have any
success with using Maven 2.

Starting a new project


Use the newproject-archetype project. The simple command below will get you started, and

$ mvn archetype:generate \
-DarchetypeGroupId=org.infinispan.archetypes \
-DarchetypeArtifactId=newproject-archetype \
-DarchetypeVersion=1.0.5 \
-DarchetypeRepository=http://repository.jboss.org/nexus/content/groups/public

You will be prompted for a few things, including the artifactId , groupId and version of your new
project. And that's it - you're ready to go!

Exploring your new project


The skeleton project ships with a sample application class for interacting with Infinispan. You can open this
new project in your IDE - most good IDEs such as IntelliJ and Eclipse allow you to import Maven projects,
see this guide and this guide. Once you open your project in your IDE, you should examine the generated
classes and read through the comments.

On the command line...


Try running

$ mvn install -Prun

in your newly generated project. This runs the main() method in the generated application class.

Writing a test case for Infinispan


This archetype is useful if you wish to contribute a test to the Infinispan project and helps you get set up to
use Infinispan's testing harness and related tools.
Use

JBoss Community Documentation

Page 554 of 617

Infinispan 6.0

$ mvn archetype:generate \
-DarchetypeGroupId=org.infinispan.archetypes \
-DarchetypeArtifactId=testcase-archetype \
-DarchetypeVersion=1.0.5 \
-DarchetypeRepository=http://repository.jboss.org/nexus/content/groups/public

As above, this will prompt you for project details and again as above, you should open this project in your
IDE. Once you have done so, you will see some sample tests written for Infinispan making use of
Infinispan's test harness and testing tools along with extensive comments and links for further reading.

On the command line...


Try running

$ mvn test

in your newly generated project to run your tests.


The generated project has a few different profiles you can use as well, using Maven's -P flag. For example:

$ mvn test -Pudp

Available profiles
The profiles available in the generated sample project are:
udp: use UDP for network communications rather than TCP
tcp: use TCP for network communications rather than UDP
jbosstm: Use the embedded JBoss Transaction Manager rather than Infinispan's dummy test
transaction manager

Contributing tests back to Infinispan


If you have written a functional, unit or stress test for Infinispan and want to contribute this back to Infinispan,
your best bet is to fork the Infinispan sources on GitHub. The test you would have prototyped and tested in
an isolated project created using this archetype can be simply dropped in to Infinispan's test suite. Make
your changes, add your test, prove that it fails even on Infinispan's upstream source tree and issue a pull
request.
{tip:title=New to working with Infinispan and GitHub?

Want to know how best to work with the repositories and contribute code? Read
[Infinispan and Git]

JBoss Community Documentation

Page 555 of 617

Infinispan 6.0

Versions
The archetypes generate poms with dependencies to specific versions of Infinispan. You should edit these
generated poms by hand to point to other versions of Infinispan that you are interested in.

Source Code
The source code used to generate these archetypes are on GitHub. If you wish to enhance and contribute
back to the project, fork away!

7.12.5 The Maven Archetypes


Infinispan currently has 2 separate Maven archetypes you can use to create a skeleton project and get
started using Infinispan. This is an easy way to get started using Infinispan as the archetype generates
sample code, a sample Maven pom.xml with necessary depedencies, etc.

You don't need to have any experience with or knowledge of Maven's Archetypes to use this! Just
follow the simple steps below.

These archetypes have only been tested with Maven 3. Please report back if you have any
success with using Maven 2.

JBoss Community Documentation

Page 556 of 617

Infinispan 6.0

Starting a new project


Use the newproject-archetype project. The simple command below will get you started, and

$ mvn archetype:generate \
-DarchetypeGroupId=org.infinispan.archetypes \
-DarchetypeArtifactId=newproject-archetype \
-DarchetypeVersion=1.0.5 \
-DarchetypeRepository=http://repository.jboss.org/nexus/content/groups/public

You will be prompted for a few things, including the artifactId , groupId and version of your new
project. And that's it - you're ready to go!

Exploring your new project


The skeleton project ships with a sample application class for interacting with Infinispan. You can open this
new project in your IDE - most good IDEs such as IntelliJ and Eclipse allow you to import Maven projects,
see this guide and this guide. Once you open your project in your IDE, you should examine the generated
classes and read through the comments.

On the command line...


Try running

$ mvn install -Prun

in your newly generated project. This runs the main() method in the generated application class.

Writing a test case for Infinispan


This archetype is useful if you wish to contribute a test to the Infinispan project and helps you get set up to
use Infinispan's testing harness and related tools.
Use

$ mvn archetype:generate \
-DarchetypeGroupId=org.infinispan.archetypes \
-DarchetypeArtifactId=testcase-archetype \
-DarchetypeVersion=1.0.5 \
-DarchetypeRepository=http://repository.jboss.org/nexus/content/groups/public

As above, this will prompt you for project details and again as above, you should open this project in your
IDE. Once you have done so, you will see some sample tests written for Infinispan making use of
Infinispan's test harness and testing tools along with extensive comments and links for further reading.

JBoss Community Documentation

Page 557 of 617

Infinispan 6.0

On the command line...


Try running

$ mvn test

in your newly generated project to run your tests.


The generated project has a few different profiles you can use as well, using Maven's -P flag. For example:

$ mvn test -Pudp

Available profiles
The profiles available in the generated sample project are:
udp: use UDP for network communications rather than TCP
tcp: use TCP for network communications rather than UDP
jbosstm: Use the embedded JBoss Transaction Manager rather than Infinispan's dummy test
transaction manager

Contributing tests back to Infinispan


If you have written a functional, unit or stress test for Infinispan and want to contribute this back to Infinispan,
your best bet is to fork the Infinispan sources on GitHub. The test you would have prototyped and tested in
an isolated project created using this archetype can be simply dropped in to Infinispan's test suite. Make
your changes, add your test, prove that it fails even on Infinispan's upstream source tree and issue a pull
request.
{tip:title=New to working with Infinispan and GitHub?

Want to know how best to work with the repositories and contribute code? Read
[Infinispan and Git]

Versions
The archetypes generate poms with dependencies to specific versions of Infinispan. You should edit these
generated poms by hand to point to other versions of Infinispan that you are interested in.

Source Code
The source code used to generate these archetypes are on GitHub. If you wish to enhance and contribute
back to the project, fork away!

JBoss Community Documentation

Page 558 of 617

Infinispan 6.0

7.13 Contributing - The test suite


Tests are written using the TestNG framework.

7.13.1 Running the tests


Before running the actual tests it is highly recommended to configure adjust suite's memory setting by
updating the MAVEN_OPTS variables. E.g.

$ export MAVEN_OPTS="-Xms512m -Xmx2048m -XX:MaxPermSize=384m"

The default run executes all tests in the functional and unit groups. To just run the tests with txt and xml
output the command is:

$ mvn test

Alternatively, you can execute the tests and generate a report with:

$ mvn surefire-report:report

If you are running the tests on a Unix-like operating system, the default limits per user are typically
low. The Infinispan test suite creates a lot of processes/threads, thus you will have to increase your
user's limits and reboot the system to pick up the new values. Open up
/etc/security/limits.conf and add the following lines replacing the user name with your
username.

rhusar
rhusar
rhusar
rhusar

soft
hard
soft
hard

nofile
nofile
nproc
nproc

JBoss Community Documentation

16384
16384
16384
16384

Page 559 of 617

Infinispan 6.0

Specifying which tests to run


A single test can be executed using the test property. The value is the short name (not the fully qualified
package name) of the test. For example:

$ mvn -Dtest=FqnTest test

Alternatively, if there is more than one test with a given classname in your test suite, you could provide the
path to the test.

$ mvn -Dtest=org/infinispan/api/MixedModeTest test

Alternatively, you can always pass your own Log4j configuration file via -Dlog4.configuration with your
own logging settings.
Patterns are also supported:

$ mvn -Dtest=org/infinispan/api/* test

Skipping the test run


It is sometimes desirable to install the Infinispan package in your local repository without performing a full
test run. To do this, simply use the maven.test.skip.exec property:

$ mvn -Dmaven.test.skip.exec=true install

Note that you should never use -Dmaven.test.skip=true since modules' test classes depend on other
module test classes, and this will cause compilation errors.

Running tests using @Parameters


If you want to execute tests relying on TestNG's @Parameters from an IDE (such as Eclipse or IntelliJ
IDEA), please check this blog entry.

JBoss Community Documentation

Page 560 of 617

Infinispan 6.0

Enabling TRACE in test logs


When you run tests, you can get TRACE logging via using the traceTests profile

mvn test -PtraceTests

Executing this will generate a GZIP file called trace-infinispan.log.gz. This file is not fully closed, so
to extract the log file, execute:

gunzip -c trace-infinispan.log.gz > trace-infinsipan.log

Enabling code coverage generation


When you run tests, you can enable code coverage recorder for calculating and analysing the Infinispan
code coverage. You can do this using coverage and jacocoReport profiles.
As a code coverage evaluation tool, the JaCoCo is used.

mvn test -Pcoverage -Dmaven.test.failure.ignore=true

Please note, that -Dmaven.test.failure.ignore=true is used for generating JaCoCo code coverage
report, even if there are test failures.
Executing this will generate jacoco.exec file in each module's target/ directory. These are the JaCoCo
execution data files, which contain full data about the specific module's coverage.
As soon as the coverage execution command is finished, you will need to generate the JaCoCo report,
which will merge the generated jacoco.exec files as well as will create the code coverage report.
For having the report in place, run the following command from your Infinispan home directory:

mvn install -pl parent -PjacocoReport

The jacoco-html/ directory will be generated in Infinispan Home directory, which will contain the code
coverage report.

JBoss Community Documentation

Page 561 of 617

Infinispan 6.0

7.13.2 Test groups


Each test should belong to one or more group. The group acts as a filter, and is used to select which tests
are ran as part of the maven test lifecycle.

Which group should I use?


If your test does not fit into one of these group, a new group should be added.

unit

Unit tests using stubs to isolate and test each major class in Infinispan. This is the default
group run if no test group is specified

functional

Tests which test the general functionality of Infinispan

jgroups

Tests which need to send data on a JGroups Channel

transaction Tests which use a transaction manager


profiling

Tests used for manual profiling, not meant for automated test runs

manual

Other tests that are run manually

Every test (except those not intended to be run by Hudson) should at least be in the functional or
unit groups, since these are the default test groups executed by Maven, and are run when
preparing a release.

JBoss Community Documentation

Page 562 of 617

Infinispan 6.0

7.13.3 Test permutations


We use the term permutation to describe a test suite execution against a particular configuration. This allows
us to test a variety of environments and configurations without rewriting the same basic test over and over
again. For example, if we pass JVM parameter -Dinfinispan.test.jgroups.protocol=udp test suite
is executed using UDP config.

$ mvn -Dinfinispan.test.jgroups.protocol=udp test

Each permutation uses its own report directory, and its own html output file name. This allows you to execute
multiple permutations without wiping the results from the previous run. Note that due to the way Maven
operates, only one permutation can be executed per mvn command. So automating multiple runs requires
shell scripting, or some other execution framework to make multiple calls to Maven.

Running permutations manually or in an IDE


Sometimes you want to run a test using settings other than the defaults (such as UDP for jgroups group
tests or the DummyTransactionManager for transaction group tests). This can be achieved by referring to
the Maven POM file to figure out which system properties are passed in to the test when doing something
different. For example to run a jgroups group test in your IDE using TCP instead of the default UDP, set
-Dinfinispan.test.jgroups.protocol=tcp. Or, to use JBoss JTA (Arjuna TM) instead of the
DummyTransactionManager in a transaction group test, set -Dinfinispan.test.jta.tm=jbosstm
Please refer to the POM file for more properties and permutations.

7.13.4 The Parallel Test Suite


Infinispan runs its unit test suite in parallel; Infinispan tests are often IO rather than processor bound, so
executing them in parallel offers significant speed up.

Tips for writing and debugging parallel tests


There are a number of constraints and best practices that need to be followed in order to ensure correctness
and keep the execution time to a minimum. If you follow these guidelines you will find your tests are more
reliable:
Each test class is run in a single thread
There is no need to synchronize unit test's fixture, as test methods will be run in sequence. However,
multiple test classes are executed in parallel.
Each test class must have an unique test name
As a convention, the name of the test should be the FQN of the test class with the org.infinispan prefix
removed. For example, given a test class org.infinispan.mypackage.MyTest the name of the test
should be mypackage.MyTest. This convention guarantees a unique name.

JBoss Community Documentation

Page 563 of 617

Infinispan 6.0

MyTest.java
package org.infinispan.mypackage;
@Test (testName = "mypackage.MyTest")
public class MyTest { ... }

Use TestCacheManagerFactory.createXyzCacheManager and _never_create managers using


new DefaultCacheManager()
This ensures that there are no conflicts on resources e.g. a cluster created by one test won't interfere with a
cluster created by another test.
Where possible, extend SingleCacheManagerTestorMultipleCacheManagersTest
Tests inheriting from these template method classes will only create a cache/cluster once for all the test
methods, rather than before each method. This helps keep the execution time down.
Never rely onThread.sleep()
When running in heavily threaded environments this will most often not work. For example, if using
ASYNC_REPL, don't use a sleep(someValue) and expect the data will be replicated to another cache
instance after this delay has elpased. Instead, use a ReplicationListener (check the javadoc for more
information). Generally speaking, if you expect something will happen and you don't have a guarantee when,
a good approach is to try that expectation in a loop, several times, with an generous (5-10secs) timeout. For
example:

while (Systet.currentTimeMillis() - startTime < timeout) {


if (conditionMeet()) break;
Thread.sleep(50);
}

Thread.sleep(10) may not work in certain OS/JRE combos (e.g. Windows XP/Sun JRE 1.5)
Use values grater than 10 for these statements, e.g. 50. Otherwise, a System.currentTimeMillis()
might return same value when called before and after such a sleep statement.
JMX
For each cache that is create with TestCacheManagerFactory.createXyzCacheManager() the test
harness will allocate a unique JMX domain name which can be obtained through
CacheManager.getJmxDomain(). This ensures that no JMX collisions will takes place between any tests
executed in parallel. If you want to enforce a JMX domain name, this can be done by using one of the
TestCacheManagerFactory.createCacheManagerEnforceJmxDomain methods. These methods
must be used with care, and you are responsible for ensuring no domain name collisions happen when the
parallel suite is executed.
Use obscure words
Insert uncommon or obscure words into the cache that has been generated with a random word generator.
In a multi-threaded environment like Infinispan's testsuite, grepping for these words can greatly help the
debugging process. You may find this random word generator useful.

JBoss Community Documentation

Page 564 of 617

Infinispan 6.0
Use the test method name as the key
Grab the test method and use it as part of the cached key. You can dynamically grab the test method using
code like this:

Thread.currentThread().getStackTrace()(1).getMethodName()

Even though we've tried to reduce them to a min, intermittent failures might still appear from time to time. If
you see such failures in existing code please report them in the issue tracker.

7.14 Contributing - Helping Others Out


Infinispan is reliant on the whole community helping each other out. Less experienced contributors are often
able to help out answering the "newbie" questions, leaving more experienced contributors to handle the
more complex questions.
Users are encouraged to follow the How to ask a forum question guide.
Forum discussions can be posed as questions (we encourage people to do this). Questions can be marked
as answered, indicating to the community that they no longer require answering, allowing easy tracking of
open questions. Open questions can be easily viewed using this filter. Community members are encouraged
to regularly view the open questions and answer any questions they can.
In order to track what questions are still open, you are encouraged to mark questions as "assumed
answered" if you provide information that you think resolves the query and you don't hear back to the
contrary after a week or so.
Approximately every month, a member of the Infinispan team will go through any open questions for the past
month and clear up any unanswered questions, either by chasing for an answer from core team, or by
checking with the user if they require more info.

7.15 Contributing - Adding configuration options


We still use the old configuration system internally within Infinispan. This makes things a little
complicated. This will be switched out soon! For now, you need to also add your property to the old
config system as well as the new.

Note, these guides assume you are adding an element to the cache configuration, but apply equally to the
global configuration.
Before you start adding a configuration property, identify whether you want to add a property to an existing
configuration group/element, or whether you need to create a child object. We call the configuration group
XXX in the steps below.

JBoss Community Documentation

Page 565 of 617

Infinispan 6.0

7.15.1 Adding a property


Add the property to the relevant XXXConfiguration class. Add a private final field, add a parameter to the
constructor, and assign the value to the field in the constructor body. Add a accessor for the property. If the
property should be mutable at runtime, then add a mutator as well. Most configuration properties are not
mutable at runtime - if the configuration is runtime mutable, then Infinispan needs to take notice of this
update whilst the cache is running (you can't cache the value of the configuration in your implementation
class). Mutators and accessors don't use the classic JavaBean pattern of prepending accessors with "get"
and mutators with "set". Instead, the name of the property is used for an accessor. A mutator is an
overloaded version of the accessor which takes a parameter, the new value.
Add the property to the matching XXXConfigurationBuilder. You'll need to add a mutable field to the
class, and initialise it to it's default value in the field declaration. Add a mutator (following the above pattern).
The create() method is called by the parent object in order to instantiate the XXXConfiguration object
from the builder. Therefore, make sure to pass the value of the field in the builder to the
XXXConfiguration object's constructor here. Additionally, if you require a complex default (for example,
the value of a configuration property is defaulted conditionally based on the value of some other
configuration property), then this is the place to do this.
The validate() method is called by the parent object to validate the values the user has passed in. This
method may also be called directly by user code, should they wish to manually validate a configuration
object. You should place any validation logic here related to your configuration property. If you need to
"cross-validate" properties (validate the value of your property conditionally upon the value of another
property), and the other property is on another builder object, increase the visibility of that other property field
to "default", and reference it from this builder, by calling the getBuilder() method, which will gives you a
handle on the root configuration builder.
The final step is to add parsing logic to the Parser class. First, add the attribute to name to the Attribute
enum (this class simply provides a mapping between the non-type-safe name of the attribute in XML and a
type-safe reference to use in the parser). Locate the relevant parseXXX() method on the class, and add a
case to the switch statement for the attribute. Call the builder mutator you created above, performing any
XML related validation (you are unlikely to need this), and type conversion (using the static methods on the
primitive wrapper classes, String class, or relevant enum class).

JBoss Community Documentation

Page 566 of 617

Infinispan 6.0

7.15.2 Adding a group


In some situations you may additionally want to add a configuration grouping object, represented in XML as
an element. You might want to do this if you are adding a new area of functionality to Infinispan. Identify the
location of the new configuration grouping object. It might be added to the root Configuration object, or it
might be added to one it's children, children's children. We'll call the parent YYY in the steps below.
Create the XXXConfiguration object. Add any properties required following the guide for adding
properties. The constructors visibility should be "default".
Create the XXXConfigurationBuilder object. It should subclass the relevant configuration child builder
use the YYYConfigurationChildBuilder as the superclass. This will ensure that all builder methods
that allow the user to "escape" are provided correctly (i.e provide access to other grouping elements), and
also require you to provide a create() and validate() method. The constructor needs to take the the
YYYConfigurationBuilder as an argument, and pass this to the superclass (this simply allows access
to the root of the builder tree using the getBuilder() method).
Follow the property adding guide to add any properties you need to the builder. The create() method needs
to return a new instance of the XXXConfiguration object. Implement any validation needed in the
validate() method.
In the YYYConfiguration object, add your new configuration class as a private final field, add an
accessor, and add initialiser assignment in the constructor
In the YYYConfigurationBuilder, add your new configuration builder as a private final field, and
initialise it in the constructor with a new instance. Finally, add an accessor for it following the standard
pattern discussed in the guide.
In the YYYConfigurationBuilder ensure that your validate method is called in it's validate method, and
that result of the XXXConfiguration instances' create method is passed to the constructor of
YYYConfiguration.
Finally, add this to the parser. First, add the element to the Element class, which provides a type safe
representation of the element name in XML. In the Parser class, add a new parseXXX method, copying
one of the others that most matches your requirements (parse methods either parse elements only - look for
ParseUtils.requireNoAttributes(), attributes only look for ParseUtils.requireNoContent()
or a combination of both look for an iterator over both elements and attributes). Add any attributes as
discussed in the adding a property guide. Finally, wire this in by locating the parseYYY() method, and
adding an element to the switch statement, that calls your new parseXXX() method.

7.15.3 Don't forget to update the XSD and XSD test


Add your new elements or attributes to the XSD in src/main/resources. Update
src/test/resources/configs/all.xml to include your new elements or attributes.

JBoss Community Documentation

Page 567 of 617

Infinispan 6.0

7.15.4 Bridging to the old configuration


Until we entirely swap out the old configuration you will need to add your property to the old configuration (no
need to worry about jaxb mappings though!), and then add some code to the LegacyConfigurationAdaptor to
adapt both ways. It's fairly straightforward, just locate the relevant point in the adapt() method (near the
configuration group you are using) and map from the legacy configuration to the new configuration, or vs
versa. You will need to map both ways, in both adapt methods.

7.16 Contributing - Documentation and FAQs


7.16.1 Introduction
Infinispan uses this Confluence instance to store documentation and FAQs. The documentation is organised
into:
Future plans
Getting

Tutorials for using Infinispan This will be developed into a Getting Started Guide, where

Started Guide
User Guide

Glossary

each tutorial as an associated quickstart example


Goes into depth on using

This will be split into a Developer Reference Guide, a

and configuring Infinispan

Configuration Guide and a Tuning Guide

An explanation of the
terminology used by
Infinispan

Frequently

Contains both product and

Each Q&A will be moved into a document and included into

Asked

technical FAQs

the outline document

Questions
Editing and adding pages on Confluence is restricted to regular contributors to Infinispan (if you think you
should have access, or want to become a regular contributor to the documentation, then please email
infinispan-dev@lists.jboss.org.

JBoss Community Documentation

Page 568 of 617

Infinispan 6.0

7.16.2 What goes where?


Infinispan has both this Confluence instance, and the SBS instance at
http://community.jboss.org/wiki/Infinispan. Documentation and FAQs belong in Confluence, whilst design
notes, meeting notes and user contributed articles belong on SBS.

Once the final set of guides (as described in the table above) is complete, there will be additional
guidance here to describe how to decide which guide to place content in.

7.16.3 Wiki markup or rich text


You should always use wiki markup, it gives you much greater control over output format. The "Full notation
guide" link in the "Help Tips" panel to the right (on the edit page) gives a full list of markup available.

7.16.4 Markup guide


This section discusses the typical markup you would use to write a documentation chapter. The [Style and
Grammar guide] will discuss the writing style you should use.
Let's start at the beginning - headers, page structure, and the table of contents.

JBoss Community Documentation

Page 569 of 617

Infinispan 6.0

Headers, Page Structure and the Table of Contents


This Confluence instance is styled to produce structured documentation. Each node in the Infinispan space
can have children, producing a tree of nodes. Note that pages are actually stored in a flat structure in the
Infinispan space, they are just logically arranged into the tree. This means that URLs do not reflect the tree
structure, and names of documents must be unique within the space.
The child nodes of the Infinispan space represent the various guides, and the FAQs. The child nodes of
each guide represent the sections of the guides. Some sections of a guide may be further split into
subsections stored in different pages (it is likely this was done because a section was getting large).
The include macro is used to display inline the contents of the various sub pages into the top level guide
page, and if a section is made up of child pages, each child page should be inlined into the section page
using the include macro.

The include macro is not automatically updated if you change a page name!

Confluence auto-generates the table of contents (using the toc macro) for the various guides, based on the
headings used in the guide. As the include macro does not print the title of the page you are including, it is
necessary to add the title above the include macro. You should not use the toc macro except on the main
guide page.
h1 headers should only be used to name sections of guide, h2 headers to name sub-sections and so on.
You should not skip header levels. Headings should follow the same capitalization rules as a sentence - only
capitalize the first letter and proper nouns.
For an example, take a look at the wiki markup for the Contributing to Infinispan guide.

JBoss Community Documentation

Page 570 of 617

Infinispan 6.0

Marking up text
You will likely want to introduce some inline formatting for text. Here are the various styles you should use.
Style

Use

bold

Bold should be used for emphasis only. You should never use another style to give
emphasis.

italic

Italic should be used when you introduce a new piece of terminology. For example
"Infinispan is a data grid". Further uses of the term do not need to be italicised.

underline

Underline should not be used

strikethrough Strikethrough should not be used


fixed width

A fixed width font should be used whenever you refer to a class, variable, method by name,

font

whenever you make a reference to a path on filesystem, or whenever you refer to a


command the user can execute. A fixed width font should be used when referring to a
sequence of clicks required by a user in a GUI. the -> symbols should be used to indicate
the transition through a nested menu.

code block

Should be used whenever you have a multi-line code example, or are expressing an
instruction for a user to do something

quotation

Should be used whenever you refer to text someone, or something, else has written, for
example the "Help Tips" on the right hand side of the edit page. You may wish to quote a
statement to indicate that your text is not overly precise. Quotes should not be used to refer
to a variable, class or method name, or a filesystem path or command

blockquote

Should be used for multiline quotes

Color

Colored text should not be used

Lists and tables


Markup
You will normally wish to use an unordered list, however a numbered list is useful when expressing a set of
steps the user should take. There are no "definition list" macros available in Confluence, so a table makes a
good alternative.
You can make nested lists by using "double" markup.

Grammar in lists and tables


The trailing sentence in a list or a table should normally not have a full stop at the end.
Often, you will want to introduce a list or a table using a sentence. If you do this, a colon is often used to
punctuate the end of the sentence, rather than a full stop/period.

JBoss Community Documentation

Page 571 of 617

Infinispan 6.0

Links
Links should be used as normal!

Admonitions
Confluence supports three admonition styles, and you are encouraged to use them in your documentation as
they allow the flow of information to the reader to be controlled, by moving orthogonal information out of the
main body of text.
tip

A tip should be used when you want to convey useful information to the user. If the user does not
read the tip, it will have no impact on them understanding your documentation, however they will
gain useful extra information by reading the tip

note

A note should be used when you wish to convey extra information to the user. Without the
information the user may struggle to completely understand your documentation

warning A warning should be used when the there is some counter-intuitive information to be called out to
the user. For example, that the following information is out of date.
You can use the title attribute to give the admonition a title

JBoss Community Documentation

Page 572 of 617

Infinispan 6.0

Images and other media


If you are describing the use of a GUI, or showing results of some operation, images embedded in the page
can bring the documentation to life for the reader. Images can be attached to the page using the Tools
menu, and then linked. The "Full notation guide" discusses the syntax for embedding images. If you are
embedding the image to describe a series of steps taken in a GUI, it is not necessary to title your image,
otherwise you should give every image a title.
Giffy is supported in this Confluence instance, allowing you to easily create drawings online. For more, read
the Giffy documentation for more information.
Confluence supports a charting macro, however it is recommended that you embed charts as images,
generating the chart using your favourite program.
The use of the panel macro is not recommended.
Confluence allows you to natively embed video, however the use of this is not recommended, instead it is
recommended the widget macro is used to connect to Vimeo or YouTube. The [Screencasts] section
describes the creation of screencasts and upload of video to Vimeo or YouTube. To embed a video using
the widget macro simply reference the URL to the video, for example:

{widget:url=http://au.youtube.com/watch?v=-dnL00TdmLY}

This produces
You can also embed Google Docs documents, Twitter searches, slide decks from SlideShare, and
presentations from SlideRocket. Just follow the above example, substituting the URL for your media.

JBoss Community Documentation

Page 573 of 617

Infinispan 6.0

Code samples
Confluence includes a code macro, but unfortunately it is not very advanced. This Confluence instance also
supports the snippet macro which can be used to include text from other sites. The use of the snippet
macro is strongly recommended as it ensures that code samples do not get out of date. It is critical that you
add a title to the your snippet, and it is also recommended you enable linenumbers and trim the text.
For example

{snippet:title=My Code
Sample|language=none|linenumbers=true|first=2|last=5|url=github.com/infinispan/infinispan/raw/master/README.mk

Which results in:Code Snippet error: Unable to retrieve the URL:


https://github.com/infinispan/infinispan/raw/master/README.mkdn status code: 404.

The snippet macro doesn't like the default "raw" link that GitHub provides. Instead, craft a URL
like github.com/infinispan/infinispan/raw/master/README.mkdn; to do this, take the
URL from your browser, and insert raw/master after the project name and before the path to the
file.

If you want to indicate that the user needs to substitute a variable in a code sample with their own,
then use < and > around the variable name. For example, to indicate the user needs to checkout a
topic branch from git:

git checkout -b <topic>

7.16.5 Voice and grammar guide


By using a consistent voice throughout the documentation, the Infinispan documentation appears more
professional. The aim is to make it feel to the user like the documentation was written by a single person.
This can only be completely achieved by regular editing, however in order to make the workload of the editor
lighter, following these rules will produce a pretty consistent voice.
Never use abbreviations. On the other hand, contractions are fine.
Always use the project name "Infinispan". Never abbreviate it.

JBoss Community Documentation

Page 574 of 617

Infinispan 6.0
Always write in the second or third person, never the first (plural or singular forms). Use the second
person to emphasize you are giving instructions to the user.

Naturally, most people write in the first person, and, typically find it the easiest form to write,
however without a lot of care it can produce the most "unprofessional" text. Conversely,
writing in the third person is trickier, but will produce text that feels well written almost
without fail. The first person can be used for emphasis but in general it is recommended to
avoid it unless you feel confident!
Writing entirely in the third person can produce quite "dry" text, so it is recommended that
you use the second person when you are giving instructions to the user. This could be when
you are walking through a sequence of steps they should perform, or could be when you are
stating that they must do something in order for them to succeed.
So, are there any tricks to reformulate a sentence so the first person is not used?
Use the passive voice "I recommend" can become "It is recommended". However,
extensive use of the can produce boring, dry and indefinite text, so don't do this too
much!
Change the subject. For example you can change "Here we discuss" to "This section
discusses"

Use a "chatty" style. Although the use of the first person is avoided, the documentation shouldn't be
too dry. Use the second person as needed. Short sentences and good use of punctuation help too!
If you define a list, keep the ordering of the list the same whenever you express the list. For example,
if you say "In this section you will learn about interceptors, commands and factories" do not go on to
say "First, let's discuss factories". This will subconsciously confuse the user
You should only capitalize proper nouns only. For example "data grid" is lower case (it's a concept),
whilst "Infinispan" is capitalized (it's a project/product name)
You should always use American spelling. Enable a spell checker!
Use the definite article when discussing a specific instance or the indefinite article when describing a
generalization of something; generally you omit the article when using a name for a project or product.

Infinispan uses a logging framework to communicate messages to the user, the


logging framework used by Infinispan is JBoss Logging.
Let's dig into this. First, the sentence states that "Infinispan uses logging", and the indefinite
article is used - we are not stating which of many possibilities is used. Second, the sentence
goes on to discuss the logging framework Infinispan uses, and here the definite article is
used, as the specific framework in use is discussed. Finally, the sentence is concluded by
stating that the logging framework used is called "JBoss Logging", and as this is a product
name, no article is used.
This is not a formal or complete description, but is a good rule of thumb.

JBoss Community Documentation

Page 575 of 617

Infinispan 6.0
Keep the tense the same. It's very easy to slip between the present, past and future tenses, but this
produces text that is feels "unnatural" to the reader. Here's an example:

Data is collected from Infinispan every hour. Upon analysis the data showed that
Infinispan is 2 million times faster than it's nearest competitor
You may not have noticed, but the phrase starts using the present tense ( is) and slips into
the past tense (showed). This is clearly not actually the order in which the events
happened!
Of course, if you are actually describing the progression of time, then changing tenses is
fine. For example:
In the last section you were shown how to configure Infinispan using XML, and in the
next section you will be shown how to configure Infinispan programmatically.

If you are telling the user about a procedure they can follow, do be explicit about this, and enumerate
the steps clearly

7.16.6 Glossary
When writing a glossary entry, you should follow the Basically Available, Soft-state, Eventually-consistent
(BASE) as a template.
If the entry is commonly referred to using an acronym, then the title should consistent of the fully
expanded name, with the acronym in brackets. You can then use the acronym always within the main
text body
If you want to refer to other glossary articles using links in the text body, then just link them with no
alternative text
If you want to make external links (e.g. wikipedia, user guide), then add a h2 header "More
resources", and list them there. This clearly indicates to users when they are moving outside of our
definitions

7.16.7 Screencasts
TODO

JBoss Community Documentation

Page 576 of 617

Infinispan 6.0

7.16.8 Managing this confluence instance.


On a minor release we clone this space to a versioned name (e.g. ISPN51), leaving the ISPN space
available for development in HEAD. To do this, visit Browse -> Space Admin and choose Permissions and
make sure you have Space Admin and Space Export permissions. Then, visit Copy Space, and fill in the
name (e.g. Infinispan 5.1) and key (e.g. ISPN51). Make sure all the boxes are checked, and click Save.
Finally, you'll need to update the name of the ISPN space to reflect the minor version of the development in
HEAD (e.g. Infinispan 5.2). You can do this in Space Details.

7.17 Contributing - API, Commons and Core


In order to provide proper separation between public APIs, common utilities and the actual implementation of
Infinispan, these are split into 3 modules: infinispan-api, infinispan-commons and infinispan-core. This
separation also makes sure that modules, such as the remote clients, don't have to depend on
infinispan-core and its transitive dependencies. The following paragraphs describe the role of each of these
modules and give indication as to what goes where.

7.17.1 API
The infinispan-api module should only contain the public interfaces which can be used in any context (local,
remote, etc). Any additions and/or modifications to this module must be discussed and approved by the
team beforehand. Ideally it should not contain any concrete classes: rare exceptions may be made for small,
self-contained classes which need to be referenced from the API interfaces and for which the introduction of
an interface would be deemed cumbersome.

7.17.2 Commons
The infinispan-commons module contains utility classes which can be reused across other modules. Classes
in infinispan-commons should be self-contained and not pull in any dependencies (apart from the existing
jboss-logging and infinispan-api). They should also make no reference to configuration aspects specific to a
particular environment.

7.17.3 Core
The infinispan-core module contains the actual implementation used for local/embedded mode. When
adding new functionality to the APIs, it is generally safe to start by putting them in infinispan-core and
promoting them to infinispan-api only when it is deemed to do so and it makes sense across the various
use-cases.

JBoss Community Documentation

Page 577 of 617

Infinispan 6.0

8 Frequently Asked Questions


8.1 Project FAQs
What is Infinispan?
What would I use Infinispan for?
How is Infinispan related to JBoss Cache?
What version of Java does Infinispan need to run? Does Infinispan need an application server to run?
Will there be a POJO Cache replacement in Infinispan?
How come Infinispan's first release is 4.0.0? This sounds weird!
What should I use, JBoss Cache or Infinispan?
Where can I get more information on Infinispan?
How is this related to JSR 107, the JCACHE specification?
Can I use Infinispan with Hibernate?

8.2 Technical FAQs


These are questions pertaining to the Infinispan code. Typically, most of these questions would only be
relevant to specific versions of Infinispan.
General FAQs
What APIs does Infinispan offer?
Which JVMs (JDKs) does Infinispan work with?
Is Infinispan's configuration compatible with JBoss Cache?
Grouping API vs Key Affinity Service
Does Infinispan store data by value or by reference?
Cache Loaders and Cache Store FAQs
Cache loaders and cache stores - what's the difference?
Are modifications to asynchronous cache stores coalesced or aggregated?
In JBoss Cache, the JDBC and File CacheLoaders had restrictions such as only being able to
use Strings in Fqns. Is this still the case in Infinispan?
What does the passivation flag do?
What if I get IOException "Unsupported protocol version 48" with
JdbcStringBasedCacheStore?
Is there any way I can boost cache store's performance? SKIP_CACHE_LOAD
Locking FAQs
Does Infinispan support distributed eager locking?
How does Infinispan support explicit eager locking?
How does Infinispan support implicit eager locking?
JBoss Cache exposed several different locking schemes - pessimistic, optimistic and MVCC. I
don't see a way to specify locking scheme in Infinispan. Why is this?
What isolation levels does Infinispan support?

JBoss Community Documentation

Page 578 of 617

Infinispan 6.0
Transaction FAQs
When using Atomikos transaction manager, distributed caches are not distributing data, what is
the problem?
Eviction and Expiration FAQs
Cache's number of entries never reaches configured maxEntries, why is that?
Expiration does not work, what is the problem?
Why is cache size sometimes even higher than specified maxEntries of the eviction
configuration element?
Why isn't there a notification for the expiration of a cache entry?
Cache Manager FAQs
Can I create caches using different cache modes using the same cache manager?
Can transactions span different Cache instances from the same cache manager?
How does multi-tenancy work?
Infinispan allows me to create several Caches from a single CacheManager. Are there any
reasons to create separate CacheManagers?
Cache Mode FAQs
What is the difference between a replicated cache and a distributed cache?
Does DIST support both synchronous and asynchronous communications?
I have caches configured with asynchronous replication or distribution, but these caches
appear to be behaving synchronously (waiting for responses), what is going on?
I notice that when using DIST, the cache does a remote get before a write command. Why is
this?
I use a clustered cache. I want the guarantees of synchronous replication with the parallelism
of asynchronous replication. What can I do?
Is buddy replication supported?
What is the L1 cache?
What consistency guarantees do I have with different Asynchronous processing settings ?
Listener FAQs
In a cache entry modified listener, can the modified value be retrieved via Cache.get() when
isPre=false?
When annotating a method with CacheEntryCreated, how do I retrieve the value of the cache
entry added?
Cloud FAQs
How do you make Infinispan send replication traffic over a specific network when you don't
know the IP address?
Demo FAQs
When using the GUI Demo, I've just put an entry in the cache with lifespan of -1. Why do I see
it as having a lifespan of 60,000?
Query Module FAQs
When I run an application based on the Query module, I get a ClassNotFoundException for
org.slf4j.impl.StaticLoggerBinder. How do I solve it?
JBoss Application Server Integration FAQs
Can I run my own Infinispan cache within JBoss Application Server 5 or 4?
Can I run my own Infinispan cache within JBoss Application Server 6?
Logging FAQs
How can I enable logging?

JBoss Community Documentation

Page 579 of 617

Infinispan 6.0
Third Party Container FAQs
Can I use Infinispan on Google App Engine for Java?
When running on Glassfish or Apache, creating a cache throws an exception saying "Unable to
construct a GlobalComponentRegistry", what is it wrong?
Language FAQs
Can I use Infinispan with Groovy? What about Jython, Clojure, JRuby or Scala etc.?
Marshalling & Unmarshalling
Best practices implementing java.io.Externalizable
Does Infinispan support storing Non-Serializable objects?
Do Externalizer implementations need to access internal Externalizer implementations?
Do I need to register an application cacheloader when using an isolated deployment?
During state transfer, the state receiver logs an EOFException when applying state saying
"Read past end of file". Should I worry about this?
How do I get more information on marshalling & unmarshalling exceptions?
Why am I getting invalid data passed to readExternal?
Tuning FAQs
When running Infinispan under load, I see RejectedExecutionException, how can I fix it?
JNDI FAQs
Can I bind Cache or CacheManager to JNDI?
Hibernate 2nd Level Cache FAQs
Can I use Infinispan as a remote JPA or Hibernate second level cache?
I'm adding the Infinispan 2nd level cache provider to existing servers that already use JGroups.
Should I set Infinispan to use the same JGroups cluster, or should I use two separate cluster
names?
Is it possible to use the Infinispan 2nd level cache outside of a J2EE server, and if so how do I
set up the transaction manager lookup?
What are the pitfalls of not using a non-JTA transaction factory such as
JDBCTransactionFactory with Hibernate when Infinispan is used as 2nd level cache provider?
Cache Server FAQs
After running a Hot Rod server for a while, I get a NullPointerException in
HotRodEncoder.getTopologyResponse(), how can I get around it?
Is there a way to do a Bulk Get on a remote cache?
What is the startServer.sh script used for? What is the startServer.bat script used for?
Debugging FAQs
How can I get Infinispan to show the full byte array? The log only shows partial contents of byte
arrays...
Clustering Transport FAQs
How do I retrieve the clustering physical address?
CLI FAQs
Can data stored via CLI be read using Infinispan remote clients (Hot Rod, Memcached,
REST)?

JBoss Community Documentation

Page 580 of 617

Infinispan 6.0

8.3 Project Evaluation FAQs


What is Infinispan?
What would I use Infinispan for?
How is Infinispan related to JBoss Cache?
What version of Java does Infinispan need to run? Does Infinispan need an application server to run?
Will there be a POJO Cache replacement in Infinispan?
How come Infinispan's first release is 4.0.0? This sounds weird!
What should I use, JBoss Cache or Infinispan?
Where can I get more information on Infinispan?
How is this related to JSR 107, the JCACHE specification?
Can I use Infinispan with Hibernate?

8.3.1 What is Infinispan?


Infinispan is an open source data grid platform. It exposes a JSR-107 compatible Cache interface (which in
turn extends java.util.Map) in which you can store objects. While Innispan can be run in local mode, its
real value is in distributed mode where caches cluster together and expose a large memory heap.
Distributed mode is more powerful than simple replication since each data entry is spread out only to a xed
number of replicas thus providing resilience to server failures as well as scalability since the work done to
store each entry is constant in relation to a cluster size.
So, why would you use it? Infinispan offers:

JBoss Community Documentation

Page 581 of 617

Infinispan 6.0

Massive heap and high availability - If you have 100 blade servers, and each node has 2GB of
space to dedicate to a replicated cache, you end up with 2 GB of total data. Every server is just a
copy. On the other hand, with a distributed grid - assuming you want 1 copy per data item - you get a
100 GB memory backed virtual heap that is efficiently accessible from anywhere in the grid. If a
server fails, the grid simply creates new copies of the lost data, and puts them on other servers.
Applications looking for ultimate performance are no longer forced to delegate the majority of their
data lookups to a large single database server - the bottleneck that exists in over 80% of enterprise
applications!
Scalability - Since data is evenly distributed there is essentially no major limit to the size of the grid,
except group communication on the network - which is minimised to just discovery of new nodes. All
data access patterns use peer-to-peer communication where nodes directly speak to each other,
which scales very well. Infinispan does not require entire infrastructure shutdown to allow scaling up
or down. Simply add/remove machines to your cluster without incurring any down-time.
Data distribution - Infinispan uses consistent hash algorithm to determine where keys should be
located in the cluster. Consistent hashing allows for cheap, fast and above all, deterministic location
of keys with no need for further metadata or network traffic. The goal of data distribution is to maintain
enough copies of state in the cluster so it can be durable and fault tolerant, but not too many copies to
prevent Infinispan from being scalable.
Persistence - Innispan exposes a CacheStore interface, and several high-performance
implementations - including JDBC cache stores, lesystem-based cache stores, Amazon S3 cache
stores, etc. CacheStores can be used for "warm starts", or simply to ensure data in the grid survives
complete grid restarts, or even to overow to disk if you really do run out of memory.
Language bindings (PHP, Python, Ruby, C, etc.) - Infinispan offers support for both the popular
memcached protocol - with existing clients for almost every popular programming language - as well
as an optimised Infinispan-specific protocol called HotRod. This means that Infinispan is not just
useful to Java. Any major website or application that wants to take advantage of a fast data grid will
be able to do so.
Management - When you start thinking about running a grid on several hundred servers,
management is no longer an extra, it becomes a necessity. The preferred way to manage multiple
Infinispan instances spread accross different servers is to use RHQ which is JBoss' enterprise
management solution. Thanks to RHQ's agent and auto discovery capabilities, monitoring both Cache
Manager and Cache instances is a very simple.
Support for Compute Grids - Infinispan 5 adds the ability to pass a Runnable around the grid. This
allows you to push complex processing towards the server where data is local, and pull back results
using a Future. This map/reduce style paradigm is common in applications where a large amount of
data is needed to compute relatively small results.

8.3.2 What would I use Infinispan for?


Infinispan's org.infinispan.Cache is a simple, flat data structure that can optionally include characteristics
such as distribution, eviction, JTA compatibility.

JBoss Community Documentation

Page 582 of 617

Infinispan 6.0

8.3.3 How is Infinispan related to JBoss Cache?


Certain design ideas and indeed some code have been borrowed from JBoss Cache 3.x, however JBoss
Cache is in no way a dependency. Infinispan is a complete, separate and standalone project. Some may
consider this a fork, but the people behind Infinispan and JBoss Cache see it as an evolution, since all future
effort will be on Infinispan and not JBoss Cache.
The current release of JBoss Cache, 3.2.3, is considered stable enough. No new features will be added to
JBoss Cache or POJO Cache, although critical fixes will still be addressed. Consider both JBoss Cache and
POJO Cache to be in maintenance mode.
So, why not just call it JBoss Cache 4?. Several reasons. Binary and even API compatibility with older
JBoss Cache releases is no longer maintained, and the new API is simpler and easier to use. Also, the
internal data structure used is not compatible with JBoss Cache.

8.3.4 What version of Java does Infinispan need to run? Does


Infinispan need an application server to run?
All that is needed is a Java 6.0 compatible JVM. An application server is not a requirement.

8.3.5 Will there be a POJO Cache replacement in Infinispan?


Yes, and this is called Hibernate OGM.

8.3.6 How come Infinispan's first release is 4.0.0? This sounds


weird!
We didn't want to release Infinispan as a 1.0, as in all fairness it is not a virgin codebase. A lot of the code,
designs and ideas in Infinispan are from JBoss Cache, and has been tried and tested, proven in high stress
environments. Infinispan should thus be viewed as a mature and stable platform and not a new,
experimental one.

8.3.7 What should I use, JBoss Cache or Infinispan?


If you are starting a new project, by all means use Infinispan. If you already use JBoss Cache, consider
upgrading to Infinispan as this is where most of our focus and efforts will be. There is a compatibility layer to
help people migrate, although we recommend only using this if you (a) absolutely need a tree structure, or
(b) only for a short time as a stepping stone. You will find that Infinispan's Map based API performs much
better. In addition, we plan to provide migration guides and configuration conversion tools.

JBoss Community Documentation

Page 583 of 617

Infinispan 6.0

8.3.8 Where can I get more information on Infinispan?


The Infinispan project page is your best place to start things off, whether you are interested in using
Infinispan in your work or are interested in collaborating on and contributing to Infinispan.

8.3.9 How is this related to JSR 107, the JCACHE


specification?
JSR 107 is not complete, but Infinispan's primary API is as close as possible to JSR 107's
javax.cache.Cache interface. The goal is once JSR 107 is complete, the org.infinispan.Cache
interface would extend javax.cache.Cache. The key thing to note is that just like javax.cache.Cache,
org.infinispan.Cache looks just like a java.util.concurrent.ConcurrentMap which would
make migration between JSR 107 compliant data structures simple.
Manik Surtani, who is project lead on Infinispan, and Pete Muir are on the JSR 107 expert group.

JBoss Community Documentation

Page 584 of 617

Infinispan 6.0

8.3.10 Can I use Infinispan with Hibernate?


Yes, you can combine one or more of these integrations in the same application:
Caching database access: Hibernate can cache frequently loaded entities and queries in Infinispan,
taking advantage of state of the art eviction algorithms, and clustering if needed but it provides a good
performance boost in non-clustered deployments too.
See Using Infinispan as JPA/Hibernate Second Level Cache Provider for details on how to do this.
Storing Lucene indexes: When using Hibernate Search to provide full-text capabilities to your
Hibernate/JPA enabled application, you need to store an Apache Lucene index separately from the
database. You can store the index in Infinispan: this is ideal for clustered applications since it's
otherwise tricky to share the index with correct locking on shared file systems, but is an interesting
option for non-clustered deployments too as it can combine the benefits of in-memory performance
with reliability and write-through to cloud storage backends like S3, or the Hibernate database itself.
See Infinispan Directory Configuration in the Hibernate Search reference documentation for the
integration details, or learn more about it at Infinispan as a storage for Lucene indexes.
Using Infinispan as a database replacement: using the experimental Hibernate Object/Grid Mapper
(OGM) you can remove the database and store your entities and relations in the grid directly,
interacting with it through the well known JPA(2) interface, with some limitations in the query
capabilities.
For more details see Hibernate Object/Grid Mapper (OGM).
Using full-text queries on Infinispan: If you liked the powerful full-text and data mining capabilities
of Hibernate Search, but don't need JPA or a database, you can use the indexing and query engine
only: the Infinispan Query module reuses Hibernate Search internally, depending on some Hibernate
libraries but exposing the Search capabilities only. See Querying Infinispan.

8.4 Technical FAQs


General FAQs
What APIs does Infinispan offer?
Which JVMs (JDKs) does Infinispan work with?
Is Infinispan's configuration compatible with JBoss Cache?
Grouping API vs Key Affinity Service
Does Infinispan store data by value or by reference?

JBoss Community Documentation

Page 585 of 617

Infinispan 6.0
Cache Loaders and Cache Store FAQs
Cache loaders and cache stores - what's the difference?
Are modifications to asynchronous cache stores coalesced or aggregated?
In JBoss Cache, the JDBC and File CacheLoaders had restrictions such as only being able to
use Strings in Fqns. Is this still the case in Infinispan?
What does the passivation flag do?
What if I get IOException "Unsupported protocol version 48" with
JdbcStringBasedCacheStore?
Is there any way I can boost cache store's performance? SKIP_CACHE_LOAD
Locking FAQs
Does Infinispan support distributed eager locking?
How does Infinispan support explicit eager locking?
How does Infinispan support implicit eager locking?
JBoss Cache exposed several different locking schemes - pessimistic, optimistic and MVCC. I
don't see a way to specify locking scheme in Infinispan. Why is this?
What isolation levels does Infinispan support?
Transaction FAQs
When using Atomikos transaction manager, distributed caches are not distributing data, what is
the problem?
Eviction and Expiration FAQs
Cache's number of entries never reaches configured maxEntries, why is that?
Expiration does not work, what is the problem?
Why is cache size sometimes even higher than specified maxEntries of the eviction
configuration element?
Why isn't there a notification for the expiration of a cache entry?
Cache Manager FAQs
Can I create caches using different cache modes using the same cache manager?
Can transactions span different Cache instances from the same cache manager?
How does multi-tenancy work?
Infinispan allows me to create several Caches from a single CacheManager. Are there any
reasons to create separate CacheManagers?
Cache Mode FAQs
What is the difference between a replicated cache and a distributed cache?
Does DIST support both synchronous and asynchronous communications?
I have caches configured with asynchronous replication or distribution, but these caches
appear to be behaving synchronously (waiting for responses), what is going on?
I notice that when using DIST, the cache does a remote get before a write command. Why is
this?
I use a clustered cache. I want the guarantees of synchronous replication with the parallelism
of asynchronous replication. What can I do?
Is buddy replication supported?
What is the L1 cache?
What consistency guarantees do I have with different Asynchronous processing settings ?

JBoss Community Documentation

Page 586 of 617

Infinispan 6.0
Listener FAQs
In a cache entry modified listener, can the modified value be retrieved via Cache.get() when
isPre=false?
When annotating a method with CacheEntryCreated, how do I retrieve the value of the cache
entry added?
Cloud FAQs
How do you make Infinispan send replication traffic over a specific network when you don't
know the IP address?
Demo FAQs
When using the GUI Demo, I've just put an entry in the cache with lifespan of -1. Why do I see
it as having a lifespan of 60,000?
Query Module FAQs
When I run an application based on the Query module, I get a ClassNotFoundException for
org.slf4j.impl.StaticLoggerBinder. How do I solve it?
JBoss Application Server Integration FAQs
Can I run my own Infinispan cache within JBoss Application Server 5 or 4?
Can I run my own Infinispan cache within JBoss Application Server 6?
Logging FAQs
How can I enable logging?
Third Party Container FAQs
Can I use Infinispan on Google App Engine for Java?
When running on Glassfish or Apache, creating a cache throws an exception saying "Unable to
construct a GlobalComponentRegistry", what is it wrong?
Language FAQs
Can I use Infinispan with Groovy? What about Jython, Clojure, JRuby or Scala etc.?
Marshalling & Unmarshalling
Best practices implementing java.io.Externalizable
Does Infinispan support storing Non-Serializable objects?
Do Externalizer implementations need to access internal Externalizer implementations?
Do I need to register an application cacheloader when using an isolated deployment?
During state transfer, the state receiver logs an EOFException when applying state saying
"Read past end of file". Should I worry about this?
How do I get more information on marshalling & unmarshalling exceptions?
Why am I getting invalid data passed to readExternal?
Tuning FAQs
When running Infinispan under load, I see RejectedExecutionException, how can I fix it?
JNDI FAQs
Can I bind Cache or CacheManager to JNDI?

JBoss Community Documentation

Page 587 of 617

Infinispan 6.0
Hibernate 2nd Level Cache FAQs
Can I use Infinispan as a remote JPA or Hibernate second level cache?
I'm adding the Infinispan 2nd level cache provider to existing servers that already use JGroups.
Should I set Infinispan to use the same JGroups cluster, or should I use two separate cluster
names?
Is it possible to use the Infinispan 2nd level cache outside of a J2EE server, and if so how do I
set up the transaction manager lookup?
What are the pitfalls of not using a non-JTA transaction factory such as
JDBCTransactionFactory with Hibernate when Infinispan is used as 2nd level cache provider?
Cache Server FAQs
After running a Hot Rod server for a while, I get a NullPointerException in
HotRodEncoder.getTopologyResponse(), how can I get around it?
Is there a way to do a Bulk Get on a remote cache?
What is the startServer.sh script used for? What is the startServer.bat script used for?
Debugging FAQs
How can I get Infinispan to show the full byte array? The log only shows partial contents of byte
arrays...
Clustering Transport FAQs
How do I retrieve the clustering physical address?
CLI FAQs
Can data stored via CLI be read using Infinispan remote clients (Hot Rod, Memcached,
REST)?

8.4.1 General FAQs


What APIs does Infinispan offer?
Which JVMs (JDKs) does Infinispan work with?
Is Infinispan's configuration compatible with JBoss Cache?
Grouping API vs Key Affinity Service
Does Infinispan store data by value or by reference?

JBoss Community Documentation

Page 588 of 617

Infinispan 6.0

What APIs does Infinispan offer?


Infinispan's primary API - org.infinispan.Cache - extends java.util.concurrent.ConcurrentMap and
closely resembles javax.cache.Cache from JSR 107. This is the most performant API to use, and should
be used for all new projects.
org.infinispan.tree.TreeCache is a tree structured API that looks a lot like JBoss Cache's API. Note that the
similarities end at the interface though, since internal implementation and representation of the tree is
completely different, using a much more efficient flat structure.
TreeCache should be considered as a compatibility API, if you are migrating from JBoss Cache and cannot
invest the time in rewriting your application, or your application specifically relies on a tree structure.

Coming Soon
An API for fine-grained replication is planned. This will provide the same benefits of JBoss Cache's
POJOCache variant, but far simpler and more robust. It will not rely on bytecode weaving or AOP,
and present users with a much more familiar JPA-style session interface. When released, the
fine-grained API will sacrifice performance, but give you cache data organization and fine-grained
replication. This organisation inevitably involves heavy use of reflection, proxies and comparisons,
and isn't nearly as efficient as more explicit use of the Cache API.

Which JVMs (JDKs) does Infinispan work with?


Infinispan is developed and primarily tested against Sun's Java SE 6. It should work with most Java SE 6
implementations, including those from IBM, HP, Apple, Oracle (BEA), and IcedTea. We expect to test on
Java SE 7 once this is finalized as well.

Is Infinispan's configuration compatible with JBoss Cache?


No. But we intend to provide transformation scripts. Keep in mind though that as long as you use custom
components - custom interceptors, cache loaders, eviction policies - we will not be able to translate these
and this would have to be done manually.

Grouping API vs Key Affinity Service


The key affinity (for keys generated with the Key Affinity Service) might be lost during topology changes. E.g.
if k1 maps to node N1 and another node is added to the system, k1 can me migrated to N2 (affinity is lost).
With grouping API you have the guarantee that the same node (you don't know/control which node) hosts all
the data from the same group even after topology changes.

JBoss Community Documentation

Page 589 of 617

Infinispan 6.0

Does Infinispan store data by value or by reference?


By default, Infinispan stores data by reference. So once clients store some data, clients can still modify
entries via original object references. This means that since client references are valid, clients can make
changes to entries in the cache using those references, but these modifications are only local and you still
need to call one of the cache's put/replace... methods in order for changes to replicate.
Obviously, allowing clients to modify cache contents directly, without any cache invocation, has some risks
and that's why Infinispan offers the possibility to store data by value instead. The way store-by-value is
enabled is by enabling Infinispan to store data in binary format and forcing it to do these binary
transformations eagerly.
The reason Infinispan stores data by-reference instead of by-value is performance. Storing data by reference
is quicker than doing it by value because it does not have the penalty of having to transform keys and values
into their binary format.

8.4.2 Cache Loaders and Cache Store FAQs


Cache loaders and cache stores - what's the difference?
Are modifications to asynchronous cache stores coalesced or aggregated?
In JBoss Cache, the JDBC and File CacheLoaders had restrictions such as only being able to use
Strings in Fqns. Is this still the case in Infinispan?
What does the passivation flag do?
What if I get IOException "Unsupported protocol version 48" with JdbcStringBasedCacheStore?
Is there any way I can boost cache store's performance? SKIP_CACHE_LOAD

Cache loaders and cache stores - what's the difference?


JBoss Cache shipped with a CacheLoader interface and a number of implementations. Infinispan has
broken this up into two separate interfaces - a CacheLoader simply loads state from elsewhere, while a
CacheStore - which extends CacheLoader - exposes methods to store state as well. This makes it simpler
to define read-only sources.

Infinispan ships with several high performance implementations of these interfaces.

JBoss Community Documentation

Page 590 of 617

Infinispan 6.0

Are modifications to asynchronous cache stores coalesced or


aggregated?
Before 4.0.0.Beta1, cache store modifications were queued in such way that a modification processor thread
would empty the modification queue and apply each modification individually. This implementation was not
able to detect multiple changes for the same key within the queue which meant that if the queue contained
10 modifications for the same key, it would apply all 10 modifications individually.
Since 4.0.0.Beta1 (ISPN-116), modifications are coalesced or aggregated for the interval that the
modification processor thread is currently applying. This means that while changes are being queued, if
multiple modifications are made to the same key, only the key's last state will be applied, hence reducing the
number of calls to the cache store.

In JBoss Cache, the JDBC and File CacheLoaders had restrictions such
as only being able to use Strings in Fqns. Is this still the case in
Infinispan?
No. We have completely re-written these implementations with a much better design which allows us to use
arbitrary keys (or Fqn elements if using the TreeCache API), provided they are serializable. For details, see
the BucketBasedCacheStore.

What does the passivation flag do?


Passivation is a mode of storing entries in the cache store only when they are evicted from memory. The
benefit of this approach is to prevent a lot of expensive writes to the cache store if an entry is hot (frequently
used) and hence not evicted from memory. The reverse process, known as activation , occurs when a
thread attempts to access an entry which is not in memory but is in the store (i.e., a passivated entry).
Activation involves loading the entry into memory, and then removing it from the cache store. With
passivation enabled, the cache uses the cache store as an overflow tank, akin to swapping memory pages
to disk in virtual memory implementations in operating systems.
If passivation is disabled, the cache store behaves as a Write-through (or Write-behind if asynchronous)
cache, where all entries in memory are also maintained in the cache store. The effect of this is that the
cache store will always contain a superset of what is in memory.

What if I get IOException "Unsupported protocol version 48" with


JdbcStringBasedCacheStore?
You have probably set your data column type to VARCHAR, CLOB or something similar, but it should be
BLOB/VARBINARY. Even though it's called JdbcStringBasedCacheStore, only the keys are required to
be strings; the values can be anything, so they need to be stored in a binary column. See the
setDataColumnType javadoc for more details.

JBoss Community Documentation

Page 591 of 617

Infinispan 6.0

Is there any way I can boost cache store's performance?


SKIP_CACHE_LOAD
If, for put operations, you don't need the previous values existing in the cache/store then the following
optimisation can be made:
Skip cache store read
cache.getAdvancedCache().withFlags(Flag.SKIP_CACHE_LOAD).put(key, value);

Note that in this case the value returned by cache.put is not reliable.
This optimisation skips a cache store read and can have very significant performance improvement effects.
More flags are described at Per-Invocation Flags

8.4.3 Locking FAQs


Does Infinispan support distributed eager locking?
How does Infinispan support explicit eager locking?
How does Infinispan support implicit eager locking?
JBoss Cache exposed several different locking schemes - pessimistic, optimistic and MVCC. I don't
see a way to specify locking scheme in Infinispan. Why is this?
What isolation levels does Infinispan support?

Does Infinispan support distributed eager locking?


Yes it does. Infinispan, by default, acquires remote locks lazily. Locks are acquired locally on a node that
runs a transaction while other cluster nodes attempt to lock cache keys involved in a transaction during
two-phase prepare/commit phase. However, if desired, Infinispan can eagerly lock cache keys either
explicitly or implicitly.

How does Infinispan support explicit eager locking?


Infinispan cache interface exposes lock API that allows cache users to explicitly lock set of cache keys
eagerly during a transaction. Lock call attempts to lock specified cache keys across all cluster nodes and it
either succeeds or fails. All locks are released during commit or rollback phase.
Consider a transaction running on one of the cache nodes:

tx.begin()
cache.lock(K)
cache.put(K,V5)
tx.commit()

// acquire cluster wide lock on K


// guaranteed to succeed
// releases locks

JBoss Community Documentation

Page 592 of 617

Infinispan 6.0

How does Infinispan support implicit eager locking?


Implicit locking goes one step ahead and locks cache keys behind the scene as keys are accessed for
modification operations.
Consider a transaction running on one of the cache nodes:

tx.begin()
cache.put(K,V)
cache.put(K2,V2)
cache.put(K,V5)
tx.commit()

//
//
//
//

acquire cluster wide lock on K


acquire cluster wide lock on K2
no-op, we already own cluster wide lock for K
releases locks

Implicit eager locking locks cache keys across cluster nodes only if it is necessary to do so. In a nutshell, if
implicit eager locking is turned on then for each modification Infinispan checks if cache key is locked locally.
If it is then a global cluster wide lock has already been obtained, otherwise a cluster wide lock request is sent
and lock is acquired.
Implicit eager locking is enabled as follows:

<transaction useEagerLocking="true" />

JBoss Cache exposed several different locking schemes - pessimistic,


optimistic and MVCC. I don't see a way to specify locking scheme in
Infinispan. Why is this?
This is because Infinispan only supports MVCC. MVCC is by far more performant, threadsafe and
consistent than the other locking schemes.

What isolation levels does Infinispan support?


Infinispan only supports the isolation levels READ COMMITTED and REPEATABLE READ.
The default isolation mode is READ COMMITTED. Unlike JBoss Cache, which used REPEATABLE READ
by default. We consider READ COMMITTED to be good enough for most applications and hence its use as
a default.

JBoss Community Documentation

Page 593 of 617

Infinispan 6.0

8.4.4 Transaction FAQs


When using Atomikos transaction manager, distributed caches are not distributing data, what is the
problem?

When using Atomikos transaction manager, distributed caches are not


distributing data, what is the problem?
For efficiency reasons, Atomikos transaction manager commits transactions in a separate thread to the
thread making the cache operations and until 4.2.1.CR1, Infinispan had problems with this type of scenarios
and resulted on distributed caches not sending data to other nodes (see ISPN-927 for more details). Please
note that replicaticated, invalidated or local caches would work fine. It's only distributed caches that would
suffer this problem.
There're two ways to get around this issue, either:
1. Upgrade to Infinispan 4.2.1.CR2 or higher where the issue has been fixed.
2. If using Infinispan 4.2.1.CR1 or earlier, configure Atomikos so that com.atomikos.icatch.threaded_2pc
is set to false. This results in commits happening in the same thread that made the cache operations.

8.4.5 Eviction and Expiration FAQs


Cache's number of entries never reaches configured maxEntries, why is that?
Expiration does not work, what is the problem?
Why is cache size sometimes even higher than specified maxEntries of the eviction configuration
element?
Why isn't there a notification for the expiration of a cache entry?

Cache's number of entries never reaches configured maxEntries, why is


that?
In the current eviction design, eviction happens per map segment, so when the segment gets filled up,
eviction runs in that segment. This means that the theoretical maxEntries might never be achieved, but it'll
be close enough. For more information, see the eviction documentation.

JBoss Community Documentation

Page 594 of 617

Infinispan 6.0

Expiration does not work, what is the problem?


Multiple cache operations such as put() can take a lifespan as parameter which defines the time when the
entry should be expired. If you have no eviction configured and and you let this time expire, it can look as
Infinispan has not removed the entry. For example, the JMX stats such as number of entries might not
updated or the persistent store associated with Infinispan might still contain the entry. To understand what's
happening, it's important to note that Infinispan has marked the entry as expired but has not actually
removed it. Removal of expired entries happens in one of 2 ways:
1. You try and do a get() or containsKey() for that entry. The entry is then detected as expired and
is removed.
2. You have enabled eviction and an eviction thread wakes up periodically and purges expired entries.
If you have not enabled (2), or your eviction thread wakeup interval is large and you probe jconsole before
the eviction thread kicks in, you will still see the expired entry. You can be assured that if you tried to
retrieve the entry via a get() or containsKey() though, you won't see the entry (and the entry will be
removed).

Why is cache size sometimes even higher than specified maxEntries of


the eviction configuration element?
Although one can specify maxEntries to be a value that is not a power of two, the underlying algorithm will
size it to the value V closest to power of two that is larger than maxEntries specified. Eviction algorithms
guarantee that the size of cache container will never be greater than V.

Why isn't there a notification for the expiration of a cache entry?


Infinispan does not guarantee that an eviction will occur immediately on timeout, but instead uses a number
of mechanisms to perform eviction:
a user thread asks for the entry and it is determined that the entry has expired; it will be removed from
the cache at this point.
the entry is passivated/overflowed to disk but it is determined that the entry has expired; it will
removed from the cache at this point.
an eviction maintenance thread kicks in and determines that the entry has been expired; it will
removed from the cache at this point.
As the eviction is only guaranteed to happen some time later than the eviction timeout has elapsed, it has
been decided that it is less surprising to not provide a callback than to provide a callback at this later point.

JBoss Community Documentation

Page 595 of 617

Infinispan 6.0

8.4.6 Cache Manager FAQs


Can I create caches using different cache modes using the same cache manager?
Can transactions span different Cache instances from the same cache manager?
How does multi-tenancy work?
Infinispan allows me to create several Caches from a single CacheManager. Are there any reasons
to create separate CacheManagers?

Can I create caches using different cache modes using the same cache
manager?
Yes. You can create caches using different cache modes, both synchronous and asynchronous, using the
same cache manager.

Can transactions span different Cache instances from the same cache
manager?
Yes. Each cache behaves as a separate, standalone JTA resource. Internally though, components may be
shared as an optimization but this in no way affects how the caches interact with a JTA manager.

How does multi-tenancy work?


Multi-tenancy is achieved by namespacing. A single Infinispan cluster can have several named caches
(attached to the same CacheManager), and different named caches can have duplicate keys. So this is, in
effect, multi-tenancy for your key/value store.

Infinispan allows me to create several Caches from a single


CacheManager. Are there any reasons to create separate
CacheManagers?
As far as possible, internal components are shared between Cache instances. Notably, RPC and
networking components are shared. If you need caches that have different network characteristics - such as
one cache using TCP while another uses UDP - we recommend you create these using different cache
managers.

JBoss Community Documentation

Page 596 of 617

Infinispan 6.0

8.4.7 Cache Mode FAQs


What is the difference between a replicated cache and a distributed cache?
Does DIST support both synchronous and asynchronous communications?
I have caches configured with asynchronous replication or distribution, but these caches appear to be
behaving synchronously (waiting for responses), what is going on?
I notice that when using DIST, the cache does a remote get before a write command. Why is this?
I use a clustered cache. I want the guarantees of synchronous replication with the parallelism of
asynchronous replication. What can I do?
Is buddy replication supported?
What is the L1 cache?
What consistency guarantees do I have with different Asynchronous processing settings ?

What is the difference between a replicated cache and a distributed


cache?
Distribution is a new cache mode in Infinispan, in addition to replication and invalidation. In a replicated
cache all nodes in a cluster hold all keys i.e. if a key exists on one nodes, it will also exist on all other
mpdes. In a distributed cache, a number of copies are maintained to provide redundancy and fault
tolerance, however this is typically far fewer than the number of nodes in the cluster. A distributed cache
provides a far greater degree of scalability than a replicated cache.
A distributed cache is also able to transparently locate keys across a cluster, and provides an [L1 cache] for
fast local read access of state that is stored remotely. You can read more in the reference guide.

Does DIST support both synchronous and asynchronous


communications?
Officially, no. And unofficially, yes. Here's the logic. For certain public API methods to have meaningful
return values (i.e., to stick to the interface contracts), if you are using DIST, synchronized communications
are necessary. For example, you have 3 caches in a cluster, A, B and C. Key K maps to A and B. On C,
you perform an operation that requires a return value e.g., Cache.remove(K). For this to work, the call
needs to be forwarded to A and B synchronously , and would have to wait for the result from either A or B to
return to the caller. If communications were asynchronous, the return values cannot be guaranteed to be
useful - even though the operation would behave as expected.
Now unofficially, we will add a configuration option to allow you to set your cache mode to DIST and use
asynchronous communications, but this would be an additional configuration option (perhaps something like
break_api_contracts) so that users are aware of what they are getting into.

JBoss Community Documentation

Page 597 of 617

Infinispan 6.0

I have caches configured with asynchronous replication or distribution,


but these caches appear to be behaving synchronously (waiting for
responses), what is going on?
If you have state transfer configured and you have asynchronous mode configured, caches will behave in a
synchronous way. This is done so that state transfer can work as expected, but the current solution expands
the synchronous calls to cache operations as well, which results in this unexpected behaivour. A better
solution that will resolve this confusion is already in the making (this issue also contains currently viable
workarounds).

I notice that when using DIST, the cache does a remote get before a
write command. Why is this?
Certain methods, such as Cache.put(), are supposed to return the previous value associated with the
specified key according to the java.util.Map contract. If this is performed on an instance that does not
own the key in question and the key is not in L1 cache, the only way to reliably provide this return value is to
do a remote GET before the put. This GET is always sync (regardless of whether the cache is configured to
be sync or async) since we need to wait for that return value.

Isn't that expensive? How can I optimize this away?


It isn't as expensive as it sounds. A remote GET, although sync, will not wait for all responses. It will accept
the first valid response and move on, thus making its performance has no relation to cluster size.
If you feel your code has no need for these return values, then this can be disabled completely (by specifying
the <unsafe unreliableReturnValues="true" /> configuration element for a cache-wide setting or
the Flag.SKIP_REMOTE_LOOKUP for a per-invocation setting). Note that while this will not impair cache
operations and accurate functioning of all public methods is still maintained. However, it will break the
java.util.Map interface contract by providing unreliable and inaccurate return values to certain methods,
so you would need to be certain that your code does not use these return values for anything useful.

I use a clustered cache. I want the guarantees of synchronous


replication with the parallelism of asynchronous replication. What can I
do?
Infinispan offers a new async API to provide just this. These async methods return Future which can be
queried, causing the thread to block till you get a confirmation that any network calls succeeded. You can
read more about it.

Is buddy replication supported?


Buddy Replication is not available in Infinispan. The new distributed cache mode solves the same problems
in a far more elegant and scalable manner. Read this blog article for a more detailed discussion on the
subject.

JBoss Community Documentation

Page 598 of 617

Infinispan 6.0

What is the L1 cache?


An L1 cache (disabled by default) only exists if you set your cache mode to distribution. An L1 cache
prevents unnecessary remote fetching of entries mapped to remote caches by storing them locally for a
short time after the first time they are accessed. By default, entries in L1 have a lifespan of 60,000
milliseconds (though you can configure how long L1 entries are cached for). L1 entries are also invalidated
when the entry is changed elsewhere in the cluster so you are sure you don't have stale entries cached in
L1. Caches with L1 enabled will consult the L1 cache before fetching an entry from a remote cache.
Also known as a near cache in competing distributed cache products.

JBoss Community Documentation

Page 599 of 617

Infinispan 6.0

What consistency guarantees do I have with different Asynchronous


processing settings ?
There are 3 main configuration settings (modes of usage) that affect the behaviour of Infinispan in terms of
Asynchronous processing, summarized in the following table:
Config /

Description

Mode of
usage
Usage ofAsynchronous API, i.e. methods of the Cache interface like e.g. putAsync(key, val)

API

Marshalling Allowing Asynchronous Marshalling, in cache configuration (via XML or programmatic


configuration)
Replication Configuring a clustered cache to replicate data asychronously. In Infinispan XML
configuration this is done by using <sync> or <async> sub-elements under<clustering>
element.
Switching to asynchronous mode in each of these areas causes loss of some consistency guarrantees. The
known problems are summarised here:
API

Replication Marshalling Consistency problems

Sync

Sync

Sync

Sync

Async

Sync

1 - Cache entry is replicated with a delay or not at all in case of


network error.
2 - Node where the operation originated won't be notified about errors
that happened on network or on the receiving side.

Sync

Async

Async

1, 2
3 - Calling order of sync API method might not be preserved
depends on which operation finishes marshalling first in the
asyncExecutor
4 - Replication of put operation can be applied on different nodes in
different order this may result in inconsistent values

Async Sync

Sync

Async Async

Sync

1, 2, 3

Async Async

Async

1, 2, 3, 4

JBoss Community Documentation

Page 600 of 617

Infinispan 6.0

8.4.8 Listener FAQs


In a cache entry modified listener, can the modified value be retrieved via Cache.get() when
isPre=false?
When annotating a method with CacheEntryCreated, how do I retrieve the value of the cache entry
added?

In a cache entry modified listener, can the modified value be retrieved


via Cache.get() when isPre=false?
No, it cannot. Use CacheEntryModifiedEvent.getValue() to retrieve the value of the entry that was
modified.

When annotating a method with CacheEntryCreated, how do I retrieve


the value of the cache entry added?
Cache listeners can be defined to listen for cache entry created events by annotation methods with
@CacheEntryCreated and having CacheEntryCreatedEvent as method parameter.
CacheEntryCreatedEvent does not provide a method to retrieve the value that was created in the cache
though. To retrieve this value, a method annotated with @CacheEntryModified needs to be added because
every time a cache entry is created, cache entry modified event is also fired.

JBoss Community Documentation

Page 601 of 617

Infinispan 6.0

8.4.9 Cloud FAQs


How do you make Infinispan send replication traffic over a specific network when you don't know the
IP address?

How do you make Infinispan send replication traffic over a specific


network when you don't know the IP address?
Some cloud providers charge you less for traffic over internal IP addresses compared to public IP
addresses, in fact, some cloud providers do not even charge a thing for traffic over the internal network (i.e.
GoGrid). In these circumstances, it's really advantageous to configure Infinispan in such way that replication
traffic is sent via the internal network. The problem though is that quite often you don't know which internal
IP address you'll be assigned (unless you use elastic IPs and dyndns.org), so how do you configure
Infinispan to cope with those situations?
JGroups, which is the underlying group communication library to interconnect Infinispan instances, has come
up with a way to enable users to bind to a type of address rather than to a specific IP address. So now you
can configure bind_addr property in JGroups configuration file, or the -Djgroups.bind_addr system
property to a keyword rather than a dotted decimal or symbolic IP address:
GLOBAL: pick a public IP address. You want to avoid this for replication traffic
SITE_LOCAL: use a private IP address, e.g. 192.168.x.x. This avoids charges for bandwith from
GoGrid, for example
LINK_LOCAL: use a 169.x.x.x, 254.0.0.0 address. I've never used this, but this would be for traffic
only within 1 box
NON_LOOPBACK: use the first address found on an interface (which is up), which is not a 127.x.x.x
address

8.4.10 Demo FAQs


When using the GUI Demo, I've just put an entry in the cache with
lifespan of -1. Why do I see it as having a lifespan of 60,000?
This is probably a L1 caching event. When you put an entry in the cache, the entry is mapped to specific
nodes in a cluster using a consistent hashing algorithm. This means that key K could map on to caches A
and B (or however many owners you have configured). If you happen to have done the cache.put(K, V)
on cache C , however, K still maps to A and B (and will be added to caches A and B with their proper
lifespans), but it will also be put in cache C's L1 cache.

JBoss Community Documentation

Page 602 of 617

Infinispan 6.0

8.4.11 Query Module FAQs


When I run an application based on the Query module, I get a ClassNotFoundException for
org.slf4j.impl.StaticLoggerBinder. How do I solve it?

When I run an application based on the Query module, I get a


ClassNotFoundException for org.slf4j.impl.StaticLoggerBinder. How do
I solve it?
See the SLF4J section in the reference guide.

JBoss Community Documentation

Page 603 of 617

Infinispan 6.0

8.4.12 JBoss Application Server Integration FAQs


Can I run my own Infinispan cache within JBoss Application Server 5 or 4?
Can I run my own Infinispan cache within JBoss Application Server 6?

Can I run my own Infinispan cache within JBoss Application Server 5 or


4?
Yes, you can, but since Infinispan uses different JGroups jar libraries to the ones shipped by these
application servers, you need to make sure that the code using Infinispan, and the Infinispan libraries, are
deployed in an isolated WAR/EAR. Information on how to isolate deployments can be found in:
Isolating deployments in JBoss AS 4 or earlier
For AS5, follow instructions on adding jars and adding isolated deployment descriptor in here
Apart from isolating your deployment, you can use Maven's Shade plugin to build Infinispan and all its
dependencies in a single jar, and then shade the library that might clash with the one in the app server. For
example, to shade org.jgroups, you'd build Infinispan with:

<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>1.4</version>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
<configuration>
<relocations>
<relocation>
<pattern>org.jgroups</pattern>
<shadedPattern>org.shaded.jgroups</shadedPattern>
</relocation>
</relocations>
</configuration>
</execution>
</executions>
</plugin>

Can I run my own Infinispan cache within JBoss Application Server 6?


Yes you can, it's all explained in the Infinispan and AS6 integration wiki.

JBoss Community Documentation

Page 604 of 617

Infinispan 6.0

8.4.13 Logging FAQs


How can I enable logging?

How can I enable logging?


By default Infinispan uses JBoss Logging 3.0 as logging framework. JBoss Logging acts as a delegator to
either JBoss Log Manager, Apache Log4j, Slf4j or JDK Logging. The way it chooses which logging provider
to delegate to is by:
1. checking whether the JBoss Log Manager is configured (e.g. Infinispan is running in JBoss
Application Server 7) and if it is, using it
2. otherwise, checking if Apache Log4j is in the classpath (JBoss Logging checks if the classes
org.apache.log4j.LogManager and org.apache.log4j.Hierarchy are available) and if it is,
using it
3. otherwise, checking if LogBack in the classpath (JBoss Logging checks if the class
ch.qos.logback.classic.Logger is available) and if it is, using it
4. finally, if none of the above are available, using JDK logging
You can use this log4j.xml as base for any Infinispan related logging, and you can pass it to your system via
system parameter (e.g., -Dlog4j.configuration=file:/path/to/log4j.xml).

8.4.14 Third Party Container FAQs


Can I use Infinispan on Google App Engine for Java?
When running on Glassfish or Apache, creating a cache throws an exception saying "Unable to
construct a GlobalComponentRegistry", what is it wrong?

Can I use Infinispan on Google App Engine for Java?


Not at this moment. Due to GAE/J restricting classes that can be loaded, and restrictions around use of
threads, Infinispan will not work on GAE/J. However, we do plan to fix this - if you wish to track the progress
of Infinispan on GAE/J, have a look at ISPN-57.

When running on Glassfish or Apache, creating a cache throws an


exception saying "Unable to construct a GlobalComponentRegistry",
what is it wrong?
It appears that this happens due to some classloading issue. A workaround that is know to work is to call the
following before creating the cache manager or container:

Thread.currentThread().setContextClassLoader(this.getClass().getClassLoader());

JBoss Community Documentation

Page 605 of 617

Infinispan 6.0

8.4.15 Language FAQs


Can I use Infinispan with Groovy? What about Jython, Clojure, JRuby or Scala etc.?

Can I use Infinispan with Groovy? What about Jython, Clojure, JRuby or
Scala etc.?
While we haven't extensively tested Infinispan on anything other than Java, there is no reason why it cannot
be used in any other environment that sits atop a JVM. We encourage you to try, and we'd love to hear your
experiences on using Infinispan from other JVM languages.

8.4.16 Marshalling & Unmarshalling


Best practices implementing java.io.Externalizable
Does Infinispan support storing Non-Serializable objects?
Do Externalizer implementations need to access internal Externalizer implementations?
Do I need to register an application cacheloader when using an isolated deployment?
During state transfer, the state receiver logs an EOFException when applying state saying "Read past
end of file". Should I worry about this?
How do I get more information on marshalling & unmarshalling exceptions?
Why am I getting invalid data passed to readExternal?

Best practices implementing java.io.Externalizable


If you decide to implement Externalizable interface, please make sure that the readExternal() method is
thread safe, otherwise you run the risk of potential getting corrupted data and OutOfMemoryException, as
seen in this forum post.

Does Infinispan support storing Non-Serializable objects?


See the reference guide.

JBoss Community Documentation

Page 606 of 617

Infinispan 6.0

Do Externalizer implementations need to access internal Externalizer


implementations?
No, they don't. Here's an example of what should not be done:

public static class ABCMarshallingExternalizer implements AdvancedExternalizer<ABCMarshalling> {


@Override
public void writeObject(ObjectOutput output, ABCMarshalling object) throws IOException {
MapExternalizer ma = new MapExternalizer();
ma.writeObject(output, object.getMap());
}
@Override
public ABCMarshalling readObject(ObjectInput input) throws IOException,
ClassNotFoundException {
ABCMarshalling hi = new ABCMarshalling();
MapExternalizer ma = new MapExternalizer();
hi.setMap((ConcurrentHashMap<Long, Long>) ma.readObject(input));
return hi;
}
...
}

End user externalizers should not need to fiddle with Infinispan internal externalizer classes. Instead, this
code should have been written as:

public static class ABCMarshallingExternalizer implements AdvancedExternalizer<ABCMarshalling> {


@Override
public void writeObject(ObjectOutput output, ABCMarshalling object) throws IOException {
output.writeObject(object.getMap());
}
@Override
public ABCMarshalling readObject(ObjectInput input) throws IOException,
ClassNotFoundException {
ABCMarshalling hi = new ABCMarshalling();
hi.setMap((ConcurrentHashMap<Long, Long>) input.readObject());
return hi;
}
...
}

Do I need to register an application cacheloader when using an isolated


deployment?
In JBossCache when dealing with isolated deployments, registering application cacheloader with cache was
needed for replication to work. With Infinispan, there's no such need, lazy deserialization is used to get
around the issue.

JBoss Community Documentation

Page 607 of 617

Infinispan 6.0

During state transfer, the state receiver logs an EOFException when


applying state saying "Read past end of file". Should I worry about this?
It depends on whether the state provider encountered an error or not when generating the state. For
example, sometimes the state provider might already be providing state to another node, so when the node
requests the state, the state generator might log:

2010-12-09 10:26:21,533 20267 ERROR [org.infinispan.remoting.transport.jgroups.JGroupsTransport]


(STREAMING_STATE_TRANSFER-sender-1,Infinispan-Cluster,NodeJ-2368:) Caught while responding to
state transfer request
org.infinispan.statetransfer.StateTransferException: java.util.concurrent.TimeoutException:
Could not obtain exclusive processing lock
at
org.infinispan.statetransfer.StateTransferManagerImpl.generateState(StateTransferManagerImpl.java:175)
at
org.infinispan.remoting.InboundInvocationHandlerImpl.generateState(InboundInvocationHandlerImpl.java:119)
at
org.infinispan.remoting.transport.jgroups.JGroupsTransport.getState(JGroupsTransport.java:586)
at
org.jgroups.blocks.MessageDispatcher$ProtocolAdapter.handleUpEvent(MessageDispatcher.java:691)
at org.jgroups.blocks.MessageDispatcher$ProtocolAdapter.up(MessageDispatcher.java:772)
at org.jgroups.JChannel.up(JChannel.java:1465)
at org.jgroups.stack.ProtocolStack.up(ProtocolStack.java:954)
at org.jgroups.protocols.pbcast.FLUSH.up(FLUSH.java:478)
at
org.jgroups.protocols.pbcast.STREAMING_STATE_TRANSFER$StateProviderHandler.process(STREAMING_STATE_TRANSFER.ja
at
org.jgroups.protocols.pbcast.STREAMING_STATE_TRANSFER$StateProviderThreadSpawner$1.run(STREAMING_STATE_TRANSFE
at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908)
at java.lang.Thread.run(Thread.java:680)
Caused by: java.util.concurrent.TimeoutException: Could not obtain exclusive processing lock
at
org.infinispan.remoting.transport.jgroups.JGroupsDistSync.acquireProcessingLock(JGroupsDistSync.java:71)
at
org.infinispan.statetransfer.StateTransferManagerImpl.generateTransactionLog(StateTransferManagerImpl.java:202
at
org.infinispan.statetransfer.StateTransferManagerImpl.generateState(StateTransferManagerImpl.java:165)
... 12 more

This exception is basically saying that the state generator was not able to generate the transaction log and
so the output to which it was writing is closed. In this situation, it's common to see the state receiver log an
EOFException, as shown below, when trying to read the transaction log because the sender did not write
the transaction log:

JBoss Community Documentation

Page 608 of 617

Infinispan 6.0

2010-12-09 10:26:21,535 20269 TRACE [org.infinispan.marshall.VersionAwareMarshaller]


(Incoming-2,Infinispan-Cluster,NodeI-38030:) Log exception reported
java.io.EOFException: Read past end of file
at org.jboss.marshalling.AbstractUnmarshaller.eofOnRead(AbstractUnmarshaller.java:184)
at
org.jboss.marshalling.AbstractUnmarshaller.readUnsignedByteDirect(AbstractUnmarshaller.java:319)
at
org.jboss.marshalling.AbstractUnmarshaller.readUnsignedByte(AbstractUnmarshaller.java:280)
at org.jboss.marshalling.river.RiverUnmarshaller.doReadObject(RiverUnmarshaller.java:207)
at org.jboss.marshalling.AbstractUnmarshaller.readObject(AbstractUnmarshaller.java:85)
at
org.infinispan.marshall.jboss.GenericJBossMarshaller.objectFromObjectStream(GenericJBossMarshaller.java:175)
at
org.infinispan.marshall.VersionAwareMarshaller.objectFromObjectStream(VersionAwareMarshaller.java:184)
at
org.infinispan.statetransfer.StateTransferManagerImpl.processCommitLog(StateTransferManagerImpl.java:228)
at
org.infinispan.statetransfer.StateTransferManagerImpl.applyTransactionLog(StateTransferManagerImpl.java:250)
at
org.infinispan.statetransfer.StateTransferManagerImpl.applyState(StateTransferManagerImpl.java:320)
at
org.infinispan.remoting.InboundInvocationHandlerImpl.applyState(InboundInvocationHandlerImpl.java:102)
at
org.infinispan.remoting.transport.jgroups.JGroupsTransport.setState(JGroupsTransport.java:603)
...

The current logic is for the state receiver to back off in these scenarios and retry after a few seconds. Quite
often, after the retry the state generator might have already finished dealing with the other node and hence
the state receiver will be able to fully receive the state.

How do I get more information on marshalling & unmarshalling


exceptions?
See the reference guide.

Why am I getting invalid data passed to readExternal?


If you are using Cache.putAsync() you may find your object is modified after serialization starts, thus
corrupting the datastream passed to readExternal. To solve this, make sure you synchronize access to
the object.

Read More
You can read more about this issue in this forum thread.

JBoss Community Documentation

Page 609 of 617

Infinispan 6.0

8.4.17 Tuning FAQs


When running Infinispan under load, I see RejectedExecutionException, how can I fix it?

When running Infinispan under load, I see RejectedExecutionException,


how can I fix it?
Internally Infinispan uses executors to do some processing asynchronously, so the first thing to do is to
figure out which of these executors is causing issues. For example, if you see a stacktrace that looks like
this, the problem is located in the asyncTransportExecutor:

java.util.concurrent.RejectedExecutionException
at
java.util.concurrent.ThreadPoolExecutor$AbortPolicy.rejectedExecution(ThreadPoolExecutor.java:1759)
at java.util.concurrent.ThreadPoolExecutor.reject(ThreadPoolExecutor.java:767)
at java.util.concurrent.ThreadPoolExecutor.execute(ThreadPoolExecutor.java:658)
at java.util.concurrent.AbstractExecutorService.submit(AbstractExecutorService.java:92)
at
org.infinispan.remoting.transport.jgroups.CommandAwareRpcDispatcher.invokeRemoteCommands(CommandAwareRpcDispat

To solve this issue, you should try any of these options:


Increase the maxThreads property in asyncTransportExecutor. At the time of writing, the default
value for this particular executor is 25.
Define your own ExecutorFactory which creates an executor with a bigger queue. You can find
more information about different queueing strategies in ThreadPoolExecutor javadoc.
Disable async marshalling (see the <async ... > element for details). This would mean that an
executor is not used when replicating, so you will never have a RejectedExecutionException.
However this means each put() will take a little longer since marshalling will now happen on the
critical path. The RPC is still async though as the thread won't wait for a response from the recipient
(fire-and-forget).

JBoss Community Documentation

Page 610 of 617

Infinispan 6.0

8.4.18 JNDI FAQs


Can I bind Cache or CacheManager to JNDI?

Can I bind Cache or CacheManager to JNDI?


Cache or CacheManager can be bound to JNDI, but only to the java: namespace because they are not
designed to be exported outside the Java Virtual Machine. In other words, you shouldn't expect that you'll be
able to access them remotely by binding them to JNDI and downloading a remote proxy to them because
neither Cache nor CacheManager are serializable.
To find an example on how to bind Cache or CacheManager to the java: namespace, simply check this unit
test case.

JBoss Community Documentation

Page 611 of 617

Infinispan 6.0

8.4.19 Hibernate 2nd Level Cache FAQs


Can I use Infinispan as a remote JPA or Hibernate second level cache?
I'm adding the Infinispan 2nd level cache provider to existing servers that already use JGroups.
Should I set Infinispan to use the same JGroups cluster, or should I use two separate cluster names?
Is it possible to use the Infinispan 2nd level cache outside of a J2EE server, and if so how do I set up
the transaction manager lookup?
What are the pitfalls of not using a non-JTA transaction factory such as JDBCTransactionFactory with
Hibernate when Infinispan is used as 2nd level cache provider?

Can I use Infinispan as a remote JPA or Hibernate second level cache?


See the reference guide.

I'm adding the Infinispan 2nd level cache provider to existing servers
that already use JGroups. Should I set Infinispan to use the same
JGroups cluster, or should I use two separate cluster names?
TODO

Is it possible to use the Infinispan 2nd level cache outside of a J2EE


server, and if so how do I set up the transaction manager lookup?
The reference guide provides details on configuring a transaction manager outside of Java EE. The
reference guide also provides details on how to use Atomikos, JTOM and Bitronix.

What are the pitfalls of not using a non-JTA transaction factory such as
JDBCTransactionFactory with Hibernate when Infinispan is used as 2nd
level cache provider?
The problem is that Hibernate will create a Transaction instance via java.sql.Connection and Infinispan
will create a transaction via whatever TransactionManager returned by
hibernate.transaction.manager_lookup_class. If
hibernate.transaction.manager_lookup_class has not been populated, it will default to the
dummy transaction manager.
So, any work on the 2nd level cache will be done under a different transaction to the one used to commit the
stuff to the database via Hibernate. In other words, your operations on the database and the 2LC are not
treated as a single unit. Risks here include failures to update the 2LC leaving it with stale data while the
database committed data correctly.

JBoss Community Documentation

Page 612 of 617

Infinispan 6.0

8.4.20 Cache Server FAQs


After running a Hot Rod server for a while, I get a NullPointerException in
HotRodEncoder.getTopologyResponse(), how can I get around it?
Is there a way to do a Bulk Get on a remote cache?
What is the startServer.sh script used for? What is the startServer.bat script used for?

After running a Hot Rod server for a while, I get a NullPointerException


in HotRodEncoder.getTopologyResponse(), how can I get around it?
This is a bug (see ISPN-669) in the Hot Rod code where we didn't specifically set the topology cache to
have no eviction and no expiration. So, if someone configured the default cache in the Infinispan
configuration file for Hot Rod with expiration or eviction, the topology cache would end up having those
capabilities and the topology view could after a while be removed from memory. To get around this issue
either:
Avoid having expiration and eviction on for the default cache.
Or, make sure you create a namedCache for ___hotRodTopologyCache with sync replication,
state transfer, no expiration and no eviction.

Is there a way to do a Bulk Get on a remote cache?


There's no bulk get operation in Hot Rod, but the Java Hot Rod client has implemented via RemoteCache
the getAsync() operation, which returns a org.infinispan.util.concurrent.NotifyingFuture (extends
java.util.concurrent.Future).
So, if you want to retrieve multiple keys in parallel, just call multiple times getAsync() and when you need the
values, just call Future.get(), or attach a FutureListener to the NotifyingFuture to get notified when the value
is ready.

What is the startServer.sh script used for? What is the startServer.bat


script used for?
These scripts are used for starting Infinispan server instances that can be talked to remotely using either our
own Hot Rod protocol or the Memcached text protocol. See Using Hot Rod Server and Client and Using
Infinispan Memcached server wikis for more information on the usage of these scripts.

JBoss Community Documentation

Page 613 of 617

Infinispan 6.0

8.4.21 Debugging FAQs


How can I get Infinispan to show the full byte array? The log only shows
partial contents of byte arrays...
Since version 4.1, whenever Infinispan needs to print byte arrays to logs, these are partially printed in order
to avoid unnecessarily printing potentially big byte arrays. This happens in situations where either, Infinispan
caches have been configured with lazy deserialization, or your running an Memcached or Hot Rod server.
So in these cases, only the first 10 positions of the byte array are shown in the logs. If you want Infinispan to
show the full byte array in the logs, simply pass the -Dinfinispan.arrays.debug=true system
property at startup. In the future, this might be controllable at runtime via a JMX call or similar.
Here's an example of log message with a partially displayed byte array:

2010-04-14 15:46:09,342 TRACE [ReadCommittedEntry] (HotRodWorker-1-1) Updating entry


(key=CacheKey{data=ByteArray{size=19, hashCode=1b3278a,
array=[107, 45, 116, 101, 115, 116, 82, 101, 112, 108, ..]}}
removed=false valid=true changed=true created=true value=CacheValue{data=ByteArray{size=19,
array=[118, 45, 116, 101, 115, 116, 82, 101, 112, 108, ..]},
version=281483566645249}]

And here's a log message where the full byte array is shown:

2010-04-14 15:45:00,723 TRACE [ReadCommittedEntry] (Incoming-2,Infinispan-Cluster,eq-6834)


Updating entry
(key=CacheKey{data=ByteArray{size=19, hashCode=6cc2a4,
array=[107, 45, 116, 101, 115, 116, 82, 101, 112, 108, 105, 99, 97, 116, 101, 100, 80, 117,
116]}}
removed=false valid=true changed=true created=true value=CacheValue{data=ByteArray{size=19,
array=[118, 45, 116, 101, 115, 116, 82, 101, 112, 108, 105, 99, 97, 116, 101, 100, 80, 117,
116]},
version=281483566645249}]

8.4.22 Clustering Transport FAQs


How do I retrieve the clustering physical address?
You can retrieve the physical address via AdvancedCache.getRpcManager().getTransport().
getPhysicalAddresses()

JBoss Community Documentation

Page 614 of 617

Infinispan 6.0

8.4.23 CLI FAQs


Can data stored via CLI be read using Infinispan remote clients (Hot
Rod, Memcached, REST)?
The CLI stores data as-is within Infinispan, so it stores data as Java POJOs. In order to be able to read that
data remotely, Infinispan needs to have compatibility or interoperability mode enabled.

JBoss Community Documentation

Page 615 of 617

Infinispan 6.0

9 Videos
Monitoring
Geographic failover

9.1 Monitoring
Monitoring Infinispan with Jopr console (screencast)
How to install Jopr, the Jopr agent and the Infinispan Jopr plugin (video)
Montoring an Infinispan instance that was automatically discovered (video)
Montoring an Infinispan instance that was manually added (video)

9.2 Geographic failover


http://www.vimeo.com/24825312

JBoss Community Documentation

Page 616 of 617

Infinispan 6.0

10 Contributor Dashboard
Could not access the content at the URL because it is not from an allowed source.

https://issues.jboss.org/activity?maxResults=10&streams=key+IS+ISPN&os_authType=basic&title=Activity%20on%20Infin
You may contact your site administrator and request that this URL be added to the list of allowed sources.

JBoss Community Documentation

Page 617 of 617

You might also like