I have an Infinispan cache that I created through JBoss7.1 web interface. It is configured as an indexed, distributed cache.
In my jboss-deployment-structure.xml
file I have added dependencies on org.infinispan
and org.hibernate
so I have access to my cache. I have also added a maven dependency on the following:
<dependency>
<groupId>org.infinispan</groupId>
<artifactId>infinispan-core</artifactId>
<version>5.1.7.Final</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.infinispan</groupId>
<artifactId>infinispan-query</artifactId>
<version>5.1.7.Final</version>
</dependency>
5.1.7.Final is the version included in the org.infinispan module in JBoss7.1.3 which I am using. This pulls in all the necessary dependencies (including lucene
and hibernate-search-engine
) so I do have the necessary libs in my project. However when doing the initial step mentioned here:
SearchManager searchManager = Search.getSearchManager( cache );
It calls ComponentRegistryUtils.getComponent(cache, SearchFactoryIntegrator.class)
which fails throwing IllegalArgumentException
:
Indexing was not enabled on this cache. interface
org.hibernate.search.spi.SearchFactoryIntegrator not found in registry
My cache has indexing enabled as can be seen by cache.getCacheConfiguration().indexing().enabled()
returning true
. But the application thinks it is not. Maybe this is because the cache's ComponentRegistry
does not have access to the org.hibernate.search.spi.SearchFactoryIntegrator
class (the cache being a JBoss global component, while the hibernate search lib is in my WAR's WEB-INF/lib
directory).
Is there another way I should be doing this?
JBoss AS 7 includes an org.infinispan module as it's used internally by the clustering subsystem, but this module does not include the lucene and hibernate-search-engine dependencies.
By specifying those dependencies in your application you are (correctly) adding the missing dependencies, but the included org.infinispan doesn't "see" the extensions as the module can not load extension points from your application's classpath.
So a possible solution is to add those dependencies to the AS7 modules and patch the org.infinispan module to import these resources from your custom module.
An alternative solution is to not rely on the org.infinispan module included by the AS but include it all in your application. This way you also have more flexibility on using a different version, possibly a more recent one.
I ended up excluding infinispan and hibernate (rather not including them, which amounts to the same thing) from the jboss-deployment-structure.xml
file.
Then I added a dependency in my pom.xml
file on org.infinispan:infinispan-query:5.2.1.Final
to pull all the jars into my WAR
artifact's WEB-INF/lib
directory.
Then I built the cache programmatically:
package com.myproduct.cache;
import org.infinispan.Cache;
import org.infinispan.configuration.cache.CacheMode;
import org.infinispan.configuration.cache.Configuration;
import org.infinispan.configuration.cache.ConfigurationBuilder;
import org.infinispan.configuration.cache.ConfigurationChildBuilder;
import org.infinispan.configuration.global.GlobalConfiguration;
import org.infinispan.configuration.global.GlobalConfigurationBuilder;
import org.infinispan.configuration.global.GlobalConfigurationChildBuilder;
import org.infinispan.eviction.EvictionStrategy;
import org.infinispan.manager.DefaultCacheManager;
import org.infinispan.manager.EmbeddedCacheManager;
import org.infinispan.transaction.LockingMode;
import org.infinispan.transaction.TransactionMode;
import org.infinispan.transaction.lookup.GenericTransactionManagerLookup;
import org.infinispan.util.concurrent.IsolationLevel;
import org.jetbrains.annotations.NotNull;
class MyObjectCacheFactory
{
private static EmbeddedCacheManager m_cacheManager = null;
private static Cache<String, MyObject> m_cache = null;
@NotNull
public static Cache<String, MyObject> getMyObjectCache ()
{
if( m_cache == null )
createMyObjectCache();
return m_cache;
}
private static synchronized void createMyObjectCache ()
{
if( m_cacheManager == null )
createCacheManager();
if( !m_cacheManager.cacheExists( "MyObjects" ) )
{
Configuration cacheConfig = createMyObjectCacheConfig();
m_cacheManager.defineConfiguration( "MyObjects", cacheConfig );
}
if( !m_cacheManager.isRunning( "MyObjects" ) )
m_cacheManager.getCache( "MyObjects" ).start();
m_cache = m_cacheManager.getCache( "MyObjects" );
}
private static void createCacheManager ()
{
GlobalConfiguration globalConfiguration = createGlobalConfiguration();
Configuration defaultCacheConfig = createDefaultCacheConfiguration();
m_cacheManager = new DefaultCacheManager( globalConfiguration, defaultCacheConfig );
}
@NotNull
private static Configuration createDefaultCacheConfiguration ()
{
ConfigurationChildBuilder builder = new ConfigurationBuilder();
builder = builder.jmxStatistics().enable();
builder = builder.clustering()
.cacheMode( CacheMode.DIST_SYNC )
.stateTransfer()
.timeout( 100 );
builder = builder.transaction()
.transactionMode( TransactionMode.TRANSACTIONAL )
.autoCommit( false )
.lockingMode( LockingMode.OPTIMISTIC );
return builder.build();
}
@NotNull
private static GlobalConfiguration createGlobalConfiguration ()
{
GlobalConfigurationChildBuilder builder = new GlobalConfigurationBuilder().clusteredDefault();
builder = builder.globalJmxStatistics()
.enable()
.cacheManagerName( "MyCacheManager" )
.jmxDomain( "com.myproduct.cache" );
return builder.build();
}
@NotNull
private static Configuration createMyObjectCacheConfig ()
{
ConfigurationChildBuilder builder = new ConfigurationBuilder();
builder = builder.jmxStatistics().enable();
builder = builder.clustering().cacheMode( CacheMode.DIST_SYNC );
builder = builder.transaction()
.transactionMode( TransactionMode.TRANSACTIONAL )
.autoCommit( false )
.lockingMode( LockingMode.OPTIMISTIC )
.transactionManagerLookup( new GenericTransactionManagerLookup() );
builder = builder.locking().isolationLevel( IsolationLevel.REPEATABLE_READ );
builder = builder.eviction().maxEntries( 100 ).strategy( EvictionStrategy.LRU );
builder = builder.expiration().maxIdle( 30000 ).lifespan( -1 ).enableReaper();
builder = builder.loaders().passivation( true ).addFileCacheStore().purgeOnStartup( true );
builder = builder.indexing().enable().addProperty( "default.directory_provider", "ram" );
return builder.build();
}
}
and added @Field
annotation to MyObject
:
package com.myproduct.cache;
import org.hibernate.search.annotations.Field;
import org.hibernate.search.annotations.Indexed;
import java.io.Serializable;
@Indexed
public class MyObject
implements Serializable
{
@NotNull private String m_id;
@Field(name = "searchNumber")
private int m_searchNumber;
public MyObject (
@NotNull String id,
int searchNumber )
{
m_id = id;
m_searchNumber = searchNumber;
}
@NotNull
public String getId ()
{
return m_id;
}
public int getSearchNumber ()
{
return m_searchNumber;
}
}
and the search method:
import org.apache.lucene.search.Query;
import org.hibernate.search.query.dsl.QueryBuilder;
import org.infinispan.Cache;
import org.infinispan.query.CacheQuery;
import org.infinispan.query.Search;
import org.infinispan.query.SearchManager;
[...]
private Cache<String, MyObject> m_cache;
@PostConstruct
public void setup ()
{
m_cache = MyObjectCacheFactory.getMyObjectCache();
}
@NotNull
public List<MyObject> getMyObjects ( int searchNumber )
{
SearchManager searchManager = Search.getSearchManager( m_cache );
QueryBuilder queryBuilder = searchManager.buildQueryBuilderForClass( MyObject.class ).get();
Query luceneQuery = queryBuilder.keyword().onField( "searchNumber" ).matching( searchNumber ).createQuery();
CacheQuery cacheQuery = searchManager.getQuery( luceneQuery, MyObject.class );
//noinspection unchecked
return (List)cacheQuery.list();
}
I've found: https://community.jboss.org/message/807112#807112 I hope, it could be possibly helpful for you as well.