2

I'm trying to follow this spring-lemon Getting started tutorial (https://naturalprogrammer.gitbooks.io/spring-lemon-getting-started/content/index.html), but I can't go further at a certain point. I created a new spring starter project (Spring boot), and I was able to add spring lemon to it. I did nothing else than following the instructions, but when I started maven build, the test failed with the following error:

org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'lmnDemoController': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire method: public void com.naturalprogrammer.spring.lemon.LemonController.setLemonService(com.naturalprogrammer.spring.lemon.LemonService); nested exception is org.springframework.beans.factory.BeanCurrentlyInCreationException: Error creating bean with name 'lmnDemoService': Bean with name 'lmnDemoService' has been injected into other beans [authenticationSuccessHandler] in its raw version as part of a circular reference, but has eventually been wrapped. This means that said other beans do not use the final version of the bean. This is often the result of over-eager type matching - consider using 'getBeanNamesOfType' with the 'allowEagerInit' flag turned off, for example.

My LmnDemoService.java is:

package com.example;

import org.springframework.stereotype.Service;
import com.naturalprogrammer.spring.lemon.LemonService;

@Service
public class LmnDemoService extends LemonService<User, Long> { 
    @Override
    protected User newUser() {
        return new User();
    }
}

It has nothing else just the lines the tutorial says. What am I missing?

EDIT:

LmndemoApplication.java

package com.example;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import com.naturalprogrammer.spring.lemon.LemonConfig;

@SpringBootApplication(scanBasePackageClasses = {LmndemoApplication.class, LemonConfig.class})
public class LmndemoApplication {

    public static void main(String[] args) {
        SpringApplication.run(LmndemoApplication.class, args);
    }
}

LmnDemoController.java

package com.example;

import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import com.naturalprogrammer.spring.lemon.LemonController;

@RestController
@RequestMapping("/api/core")
public class LmnDemoController extends LemonController<User, Long> {

}

LmnDemoService.java

package com.example;

import org.springframework.stereotype.Service;

import com.naturalprogrammer.spring.lemon.LemonService;

@Service
public class LmnDemoService extends LemonService<User, Long> {

    @Override
    protected User newUser() {
        return new User();
    }
}

SecurityConfig.java

package com.example;

import org.springframework.context.annotation.Configuration;

import com.naturalprogrammer.spring.lemon.security.LemonSecurityConfig;

@Configuration
public class SecurityConfig extends LemonSecurityConfig {

}

ServletInitializer.java

package com.example;

import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.boot.context.web.SpringBootServletInitializer;

public class ServletInitializer extends SpringBootServletInitializer {

    @Override
    protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
        return application.sources(LmndemoApplication.class);
    }

}

User.java

package com.example;

import javax.persistence.Entity;
import javax.persistence.Table;

import com.naturalprogrammer.spring.lemon.domain.AbstractUser;

@Entity 
@Table(name="usr")
public class User extends AbstractUser<User,Long> {

    private static final long serialVersionUID = 2716710947175132319L;

}

UserRepository.java

package com.example;

import com.naturalprogrammer.spring.lemon.domain.AbstractUserRepository;

public interface UserRepository extends AbstractUserRepository<User, Long> {

}

application.properties

#Database configuration
spring.jpa.database: MYSQL
spring.jpa.hibernate.ddl-auto: update

spring.datasource.url: jdbc:mysql://localhost:3306/mydatabase
spring.datasource.username: myuser
spring.datasource.password: mypassword

#DevTools configuration
spring.devtools.livereload.enabled: false
spring.devtools.restart.enabled: false

#Application URL
#lemon.application-url: http://localhost:9000

#reCAPTCHA configuration
#lemon.recaptcha.sitekey: your google recaptcha site key
#lemon.recaptcha.secretkey: your google recaptcha secret key

#Remember me configuration
#lemon.remember-me-key: someSecret

#First administrator
lemon.admin.username: admin@example.com
lemon.admin.password: admin

#Email configuration
#spring.mail.host = smtp.gmail.com
#spring.mail.username = xxxxxx@gmail.com
#spring.mail.password = xxxxxx
#
#spring.mail.properties.mail.smtp.auth = true
#spring.mail.properties.mail.smtp.socketFactory.port = 465
#spring.mail.properties.mail.smtp.socketFactory.class =        javax.net.ssl.SSLSocketFactory
#spring.mail.properties.mail.smtp.socketFactory.fallback = false
#spring.mail.properties.mail.smtp.ssl.enable = true

#Handling cross origin requests configuration
#lemon.cors.allowed-origins: http://localhost:9000

#This will disable the protection against JSON vulnerability
#lemon.enabled.json-prefix: false

pom.xml

http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0

<groupId>com.example</groupId>
<artifactId>demo</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>war</packaging>

<name>lmndemo</name>
<description>Demo project for Spring Boot</description>

<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>1.3.3.RELEASE</version>
    <relativePath/> <!-- lookup parent from repository -->
</parent>

<properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <java.version>1.8</java.version>
</properties>

<dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>

    <dependency>
        <groupId>mysql</groupId>
        <artifactId>mysql-connector-java</artifactId>
        <scope>runtime</scope>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-tomcat</artifactId>
        <scope>provided</scope>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-test</artifactId>
        <scope>test</scope>
    </dependency>

    <!-- Spring-lemon -->
    <dependency>
        <groupId>com.naturalprogrammer.spring</groupId>
        <artifactId>spring-lemon</artifactId>
        <version>0.8.5</version><!-- See https://github.com/naturalprogrammer/spring-lemon/releases for latest release -->
    </dependency>
</dependencies>

<build>
    <finalName>lmndemo</finalName>
    <plugins>
        <plugin>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-maven-plugin</artifactId>
        </plugin>
    </plugins>
</build>

Siriann
  • 405
  • 1
  • 6
  • 16

1 Answers1

4

Looks to me like a circular reference issue. It's not happening in my environment, and I think ideally Spring should have been able to resolve it itself, but best would be to fix Spring Lemon code to make it more robust, I think.

So, can you try adding a @Lazy annotation on the setLemonService method of the AuthenticationSuccessHandler class in the checked out Spring Lemon code in your workspace? Make it look as below:

@Autowired
@Lazy // add this line
public void setLemonService(LemonService<?, ?> lemonService) {
    this.lemonService = lemonService;
}

I haven't tried @Lazy before, but I think it should work. If not, we'll need to think another way to break the circular dependency.

Let me know. After a solution is found, I'll check in the fix to Spring Lemon repository.

Sanjay
  • 8,755
  • 7
  • 46
  • 62
  • Unfortunately it doesn't work. It throws the same error. I tried it with another project too to check if I did wrong something with the first one that I can't recognize, but the same happened. I also tried it with both jar and war packaging. – Siriann May 03 '16 at 18:01
  • If you could share a minimal project depicting the issue, I can have a look at it by running on my machine. – Sanjay May 04 '16 at 03:27
  • Should I paste some of my source files here, or upload the complete project to somewhere? If the first, which files are interesting in this case? – Siriann May 04 '16 at 17:51
  • Uploading the complete project source will be helpful, so that I can download and run that and reproduce the issue. If your project contains more code than just what's needed to reproduce the issue, you can create another minimal project which will be having the issue, and upload that instead. – Sanjay May 05 '16 at 04:27
  • I uploaded my project here in a zip archive: https://www.dropbox.com/s/jpch59srfk72byk/lmndemo.zip?dl=0 – Siriann May 05 '16 at 17:40
  • I was able to reproduce the error, but then introducing `@Lazy` fixed it for me. I guess maybe your build process caught the old spring-lemon jar somewhere. I've released Spring Lemon 0.8.6 with the fix. Would you try using that and check? Also, in your code given to me, I had to uncomment `lemon.remember-me-key: someSecret` in application.properties. – Sanjay May 06 '16 at 07:26
  • I tried it again with a new project using the newest release, but I've got the same error. The interesting thing is that if I download a the spring-lemon demoapp, that builds without any problem. And that uses the same library I guess. – Siriann May 07 '16 at 10:25
  • Strange. Are you sure you mentioned `0.8.6` as the version of Spring Lemon in the pom.xml of your new project? – Sanjay May 07 '16 at 10:28
  • Actually I mentioned 0.8.5., you've got a point. But after mentioning 0.8.6. I get the following error: The POM for com.naturalprogrammer.spring:spring-lemon:jar:0.8.6 is missing, no dependency information available I use the latest version downloaded from here: https://github.com/naturalprogrammer/spring-lemon/releases I also can see the added @Lazy annotation in the SuccessHandler. – Siriann May 07 '16 at 10:50
  • My dependency: com.naturalprogrammer.spring spring-lemon 0.8.6 – Siriann May 07 '16 at 10:51
  • Did you follow the exact steps as mentioned at https://naturalprogrammer.gitbooks.io/spring-lemon-getting-started/content/creating-a-new-project.html, which will import Spring Lemon 0.8.6 to your workspace and install it in your local maven repository? – Sanjay May 07 '16 at 11:07
  • You're right, the Maven install step were missing. I did it now, and was able to build it without any exception. Thank you for your help! I'm looking forward to test it. Thanks again! – Siriann May 07 '16 at 11:22