thymeleaf-spring icon indicating copy to clipboard operation
thymeleaf-spring copied to clipboard

thymeleaf-spring5 ClassNotFoundException ognl/PropertyProcessor

Open tcuje opened this issue 6 years ago • 7 comments

I tried to use thymeleaf in my project, but get the following exception: java.lang.NoClassDefFoundError: ognl/PropertyAccessor

My versions copied from mvn dependency:tree

org.thymeleaf:thymeleaf-spring5:jar:3.0.11.RELEASE:compile
  \- org.thymeleaf:thymeleaf:jar:3.0.11.RELEASE:compile
     +- org.attoparser:attoparser:jar:2.0.5.RELEASE:compile
     \- org.unbescape:unbescape:jar:1.1.6.RELEASE:compile

I think the issue here is that ognl is excluded by thymeleaf-spring5/pom.xml, see https://github.com/thymeleaf/thymeleaf-spring/blob/3.0-master/thymeleaf-spring5/pom.xml#L318

Unfortunately the relevant commits do not state why it was excluded, see b6a4911 and 896a147

tcuje avatar Jan 08 '19 10:01 tcuje

OGNL is excluded when Thymeleaf is in a Spring project (when including the thymeleaf-spring module) so that the Spring Expression Language (SpEL) is used over OGNL in your templates.

If you've got a Spring Boot project, then this should be taken care of automatically if you import the right starter modules and so no use of OGNL will come up and no ClassNotFoundException should be thrown. If you're using Spring Framework and manually configuring your app to use Thymeleaf, then the setup/configuration is a bit more involved but is described in the Thymeleaf + Spring Tutorial doc which you can find here: https://www.thymeleaf.org/doc/tutorials/3.0/thymeleafspring.html#the-springstandard-dialect

ultraq avatar Jan 09 '19 05:01 ultraq

Im using the following package for the project:

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

It's the only reference to thymeleaf I have in my pom.xml

tcuje avatar Apr 02 '19 12:04 tcuje

I had the same issue as you, and adding this solve the problem for me:

        <dependency>
            <groupId>ognl</groupId>
            <artifactId>ognl</artifactId>
            <version>3.1.12</version>
        </dependency>

mermetbt avatar May 23 '19 06:05 mermetbt

Hello there,

In my case I am using it in a junit test:

import java.util.HashMap;
import java.util.Map;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit.jupiter.SpringExtension;
import org.thymeleaf.TemplateEngine;

/**
 *
 * @author lurodrig
 */
@ExtendWith(SpringExtension.class)
@EnableConfigurationProperties
@SpringBootTest(classes = {MessageFactoryServiceImpl.class,TemplateEngine.class})
public class MessageFactoryServiceTest {
    
    @Value("${test.emailAddress}")
    private String emailAddress;
    
    @Value("${test.barcodeText}")
    private String barcodeText;
    
    @Value("${test.registrationLink}")
    private String registrationLink;
    
    @Value("${test.barcodeBase64}")
    private String barcodeBase64;
    
    @Autowired
    private MessageFactoryService messageFactoryService;
    
    @Test
    public void test_A_emailTextIsRightlyProcessed() {
        Map<String, Object> messageVariables = new HashMap<>();
        messageVariables.put(TemplateConstants.EMAIL_ADDRESS, emailAddress);
        messageVariables.put(TemplateConstants.BARCODE_BASE_64, barcodeBase64);
        messageVariables.put(TemplateConstants.BARCODE_TEXT, barcodeText);
        messageVariables.put(TemplateConstants.REGISTRATION_LINK, registrationLink);
        String message = messageFactoryService.buildVerificationMessage(messageVariables);
        System.out.println(message);
    }
}

The trick of @mermetbt worked for me...

        <dependency>
            <groupId>ognl</groupId>
            <artifactId>ognl</artifactId>
            <version>3.2.10</version>
            <scope>test</scope>
        </dependency>

But now I am facing the issue (yet another :) of spring not taking into account the configuration from src/test/resources/application.properties for thymeleaf :(

Thanks,

Luis

lurodrig avatar May 24 '19 15:05 lurodrig

After lot of experimentation, following line makes the issue OGNL issue disappear for both Spring and Spring boot: TemplateEngine templateEngine = new SpringTemplateEngine();

Further, for spring boot to work properly, I had to configure engine as below: @Bean @Primary public TemplateEngine textTemplateEngine() { TemplateEngine templateEngine = new SpringTemplateEngine(); templateEngine.setTemplateResolver(templateResolver()); return templateEngine; }

As my use case is about simple string replacement in text templates, following is template resolver configuration: private ITemplateResolver templateResolver() { StringTemplateResolver templateResolver = new StringTemplateResolver(); templateResolver.setTemplateMode(TemplateMode.TEXT); return templateResolver; }

amanbhole avatar Nov 12 '20 22:11 amanbhole

I can confirm that replacing TemplateEngine templateEngine = new TemplateEngine(); with TemplateEngine templateEngine = new SpringTemplateEngine(); as suggested by @amanbhole worked for us, too. Much thanks!

tcuje avatar Jun 09 '22 21:06 tcuje

Hello Everyone, @tcuje's solution worked for me. TemplateEngine templateEngine = new SpringTemplateEngine(); SpringBoot version: 2.7.11-SNAPSHOT Thanks.

AlperMulayim avatar Apr 14 '23 19:04 AlperMulayim