2

I am trying to create an "employee" Region and put some data into it. But, I am getting Exception below:

[warn 2018/12/27 17:15:46.518 IST tid=0x1] Exception encountered during context initialization - cancelling refresh attempt: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'gemfireConfiguration': Injection of resource dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'gemfireCache': FactoryBean threw exception on object creation; nested exception is java.lang.NoClassDefFoundError: it/unimi/dsi/fastutil/ints/Int2ObjectOpenHashMap

[warn 2018/12/27 17:15:46.519 IST tid=0x1] Invocation of destroy method failed on bean with name 'gemfireCache': org.apache.geode.cache.CacheClosedException: A cache has not yet been created.

[error 2018/12/27 17:15:46.522 IST tid=0x1] Caught exception while allowing TestExecutionListener [org.springframework.test.context.web.ServletTestExecutionListener@c667f46] to prepare test instance [com.gemfire.demo.Gemfire1ApplicationTests@48bfb884]

Domain class

 @Region("employee")
    public class Employee {
            @Id
            public String name;
            public double salary;
            ...
    }

Repository class

@Repository
public interface EmployeeRepository extends CrudRepository<Employee, String> {

    Employee findByName(String name);
}

Configuration class

@Configuration
@ComponentScan
@EnableGemfireRepositories(basePackages = "com.gemfire.demo")
public class GemfireConfiguration {

    @Autowired
    EmployeeRepository employeeRepository;

    @Bean
    Properties gemfireProperties() {
        Properties gemfireProperties = new Properties();
        gemfireProperties.setProperty("name", "SpringDataGemFireApplication");
        gemfireProperties.setProperty("mcast-port", "0");
        gemfireProperties.setProperty("log-level", "config");
        return gemfireProperties;
    }

    @Bean
    @Autowired
    CacheFactoryBean gemfireCache() {
        CacheFactoryBean gemfireCache = new CacheFactoryBean();
        gemfireCache.setClose(true);
        gemfireCache.setProperties(gemfireProperties());
        return gemfireCache;
    }

    @Bean(name="employee")
    @Autowired
    LocalRegionFactoryBean<String, Employee> getEmployee(final GemFireCache cache) {
        LocalRegionFactoryBean<String, Employee> employeeRegion = new LocalRegionFactoryBean<String, Employee>();
        employeeRegion.setCache(cache);
        employeeRegion.setClose(false);
        employeeRegion.setName("employee");
        employeeRegion.setPersistent(false);
        employeeRegion.setDataPolicy(DataPolicy.PRELOADED);
        return employeeRegion;
    }

} 

POM.XML

<parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.0.5.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
<dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-cache</artifactId>
            <exclusions>
                <exclusion>
                    <groupId>org.apache.logging.log4j</groupId>
                    <artifactId>log4j-to-slf4j</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
        <dependency>
            <groupId>org.springframework.session</groupId>
            <artifactId>spring-session-core</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-devtools</artifactId>
            <scope>runtime</scope>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
         <dependency>
            <groupId>org.springframework.data</groupId>
            <artifactId>spring-data-gemfire</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.apache.logging.log4j</groupId>
            <artifactId>log4j-core</artifactId>
            <version>2.9.0</version>
        </dependency>  
John Blum
  • 7,381
  • 1
  • 20
  • 30
Arunprasad
  • 567
  • 4
  • 14
  • 29
  • **java.lang.NoClassDefFoundError: it/unimi/dsi/fastutil/ints/Int2ObjectOpenHashMap** - You should make sure this dependency (with correct version) is added in your pom and is available in your classpath – Ram Dec 27 '18 at 12:10
  • after adding the dependency . i am getting different exception now Added Dependency it.unimi.dsi fastutil 6.3 Exception Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'gemfireCache': FactoryBean threw exception on object creation; nested exception is java.lang.NoClassDefFoundError: javax/transaction/Synchronization – Arunprasad Dec 27 '18 at 12:19
  • Looks like java transaction library is missing. Please the corresponding dependency – Ram Dec 27 '18 at 12:22
  • After added below dependencies , now i am getting 'Caused by: java.lang.ClassNotFoundException: org.apache.lucene.analysis.miscellaneous.PerFieldAnalyzerWrapper' `shiro-all-1.1.0 commons-lang-2.6 lucene-analyzers-3.6.0` – Arunprasad Dec 27 '18 at 13:13
  • Seems i am referring wrong `lucene-analyzers` version – Arunprasad Dec 27 '18 at 13:14
  • After adding `lucene-analyzers-common-4.1.0 &lucene-queryparser-4.1.0`, looks fine – Arunprasad Dec 28 '18 at 04:57
  • There has to be something wrong with your Maven POM file since Maven would pull in all the non-optional/non-provided transitive dependencies, especially given the set of dependencies you have explicitly declared. For example, declaring a dependency on `org.springframework.data:spring-data-gemfire` is enough to pull in the Lucene dependencies. You should also remove this: `` from the parent. – John Blum Feb 05 '19 at 19:23

2 Answers2

1

Adding additional tips with your above GemFire/Spring JavaConfig configuration class above.

Given you are using Spring Data Kay (implied by your use of the Spring Boot 2.0.x parent POM, i.e. org.springframework.boot:spring-boot-dependencies; see here), then you could be using Spring Data GemFire's (relatively) new and convenient Annotation-based configuration model.

By doing so, your GemfireConfiguration class above would become...

@PeerCacheApplication
@EnableGemfireRepositories(basePackages = "com.gemfire.demo")
class GemfireConfiguration {


    @Bean(name="employee")
    LocalRegionFactoryBean<String, Employee> getEmployee(GemFireCache cache) {

        LocalRegionFactoryBean<String, Employee> employeeRegion = 
            new LocalRegionFactoryBean<String, Employee>();

        employeeRegion.setCache(cache);
        employeeRegion.setClose(false);
        employeeRegion.setDataPolicy(DataPolicy.PRELOADED);

        return employeeRegion;
    }
}

A few things to keep in mind:

  1. @PeerCacheApplication is meta-annotated with @Configuration so you do not need the explicit Spring @Configuration annotation on the configuration class.

  2. @PeerCacheApplication allows you to adjust the GemFire log-level (along with other logging configuration) using the logLevel annotation attribute. Similarly, you can set the log-level using the corresponding property, spring.data.gemfire.cache.log-level in a Spring Boot application.properties file (see here). There are many other attributes and corresponding properties (e.g. name) you can use to adjust and customize other configuration.

  3. While String-based package names are supported on @EnableGemfireRepositories and similar annotations, we generally prefer and recommend users to use the type-safe variant basePacakgeClasses. You only need to refer to a single type from each top-level package where your application Repositories are kept.

  4. The explicit @Autowired annotation is not needed on your bean definitions. You do not need to explicit inject the EmployeeRepository in the configuration class to have it initialized; just inject it into the @Service class where it will be used.

  5. For convenience, the name ("employee") of the Region bean definition on your LOCAL "employee" Region, will also be used as the name of the Region, so employeeRegion.setName("employee") is unnecessary.

  6. You should not combine LocalRegionFactoryBean.setPersistent(:boolean) with LocalRegionFactoryBean.setDataPolicy(:DataPolicy) since the DataPolicy is going to take precedence.

  7. While @ComponentScan is perfectly acceptable and even convenient in development, I generally do not prefer nor recommend users to use component-scanning. It is usually always better to be explicit.

  8. As stated in the comments, you chould remove <relativePath/> from your parent definition in your application Maven POM file.

  9. Final note, as of this post, Spring Boot 2.0.8.RELEASE is the latest release.

As for your classpath issues, if you are using Maven correctly, then Maven should take care of pulling in the correct transitive dependencies.

You can refer to the many examples I have in this repo for further clarification.

Hope this helps!

John Blum
  • 7,381
  • 1
  • 20
  • 30
  • I should also point out that you would not need the explicit "employee" (LOCAL/Preloaded) Region bean definition if you used the `@EnableEntityDefinedRegions` annotation (https://docs.spring.io/spring-data/geode/docs/current/api/org/springframework/data/gemfire/config/annotation/EnableEntityDefinedRegions.html) either. See documentation (https://docs.spring.io/spring-data/gemfire/docs/2.0.10.RELEASE/reference/html/#bootstrap-annotation-config-regions) for more details. – John Blum Feb 05 '19 at 20:03
  • Finally, given you are using Spring Boot, you might also be interested in https://github.com/spring-projects/spring-boot-data-geode, FYI. – John Blum Feb 05 '19 at 20:04
0

As mentioned in comments, the error shows some dependencies (java.lang.NoClassDefFoundError: it/unimi/dsi/fastutil/ints/Int2ObjectOpenHashMap) are missing. Please add corresponding dependencies in your pom.xml

Ram
  • 1,743
  • 2
  • 18
  • 40
  • adding fastutil is not good enough , added shiro-all-1.1.0 commons-lang-2.6 lucene-analyzers-4.1.0 & lucene-queryparser-4.1.0. to resolve the issue – Arunprasad Dec 31 '18 at 10:44