groupe-sii / ogham

Sending email, sms or whatever is a piece of cake
https://groupe-sii.github.io/ogham/
Apache License 2.0
21 stars 14 forks source link

Migrate to Spring Boot 3 and Java 17 #112

Open amirbec86 opened 1 year ago

amirbec86 commented 1 year ago

Hi, I want to migrate my messaging api to spring Boot 3 and java 17, I used this dependency :

fr.sii.ogham ogham-spring-boot-starter-all 3.0.0

but I could not inject MessagingService using : @Autowired

I don't know if there is a solution for this problem by still using orgham with java 17

aurelien-baudet commented 1 year ago

Hello,

I am investigating it. There are many changes in Spring Boot 3 (dependencies and internal changes). I will give you some information when I know the amount of work it represents.

amirbec86 commented 1 year ago

hello @aurelien-baudet, thank you for your feedback, I look forward to your reply

aurelien-baudet commented 1 year ago

Hello, I succeded to compile the whole project. But tests are not running yet. It is due to java version clash. I am currently trying to fix this while keeping backward compatibility.

I think I know why the service is not injected because auto-configuration check if there is javax.servlet.Servlet in the classpath. However, since Spring Boot 3, the javax libs are replaced by jakarta so the new package is jakarta.servlet. You can still use Ogham by manually creating the bean (even if you don't get all features and full integration with Spring, you can still send email or sms and develop this part using tests)

amirbec86 commented 1 year ago

can you please tell me what I'm going to put in the bean

@Bean public MessagingService messagingService() { return ......; }

aurelien-baudet commented 1 year ago
@Bean
public MessagingService messagingService() {
    // configure properties (could be stored in a properties file or defined
    // in System properties)
    Properties properties = new Properties();
    properties.setProperty("mail.smtp.host", "<your server host>");
    properties.setProperty("mail.smtp.port", "<your server port>");
    properties.setProperty("ogham.email.from.default-value", "<email address to display for the sender user>");
    // Instantiate the messaging service using default behavior and
    // provided properties
    return MessagingBuilder.standard()                           
        .environment()
          .properties(properties)                                              
          .and()
        .build();                                                                
}

This is an example from documentation : https://groupe-sii.github.io/ogham/v3.0.0/user-manual.html#quick_start

You won't have any Spring Boot integration but you can still send emails and sms by configuring the property values

aurelien-baudet commented 1 year ago

Ok I may have a temporary solution. The biggest issues are:

  1. javax dependencies (javax.mail, javax.activation, javax.servlet, ...) are renamed into jakarta. It is not only dependencies but also internal packages. The issue is not only with Spring Boot but also with many other libraries that have made the exact same change. So, it is too much work to be able to support both by Ogham (for now at least). Therefore, there is a simple quick fix: you have to also include javax dependencies manually. Then Ogham will work with the fix I am making. I am currently testing this workaround with Spring Boot 3.0.6.
  2. Spring Boot 3, Mockito 5 and others have updated the minimum java version. So trying to run Ogham in Java 8 throwsjava.lang.UnsupportedClassVersionError because other libraries are compiled with Java 11+. In the meantime, trying to keep backward compatibility with Spring Boot 2 is not possible if Ogham is compiled in Java 17. So it is not possible to have the latest version for all libraries for compiling and developing Ogham while keeping backward compatibility with Spring Boot 1 and Spring Boot 2. I am currently testing a way to be able to do both.
amirbec86 commented 1 year ago

hello @aurelien-baudet, Thank you very much for your help, I managed to solve the problem by adding the Bean as you explained it to me. I will remain attentive to the evolution of the solution compatible with java 17 (version of the dependency)

aurelien-baudet commented 1 year ago

After many efforts, it requires too much work to maintain Spring Boot 1 + Sprig Boot 2 + Spring Boot 3 compatible with same Ogham version. It is technically possible but it breaks the purpose of Ogham wich is "Ogham adpats to what developer chooses". By keeping old Spring Boot versions, developer has to fix dependencies and classpath since there is a big mess between javax and jakarta. Renaming of the package creates big issues if there are both com.sun.mail:javax-mail and com.sun.mail.jakarta-mail dependencies (the first one brought by Ogham when using ogham-email-javamail and the second by Spring Boot mail starter). Even duplicating Ogham javamail module (one for handling javax, the other to handle jakarta) will not work if both dependencies are present. There is a clash in the declaration of service providers for javax (META-INF/services/javax.mail.Provider) because it points to the sames classes that implement jakarta.mail.Provider now !

So the decision is to break retro-compatibility. This is not what I wanted but I have no other choice. By breaking compatibility, I will upgrade everything (minimum java version, upgrade of all dependencies, ...).

I will be able to provide a new version soon.

aurelien-baudet commented 1 year ago

Everything seems to work. I finally found an acceptable solution to keep support for Spring Boot 1 and Spring Boot 2. I have some issues with the CI on Windows. Once the CI is fixed, I will deploy a SNAPSHOT version so that you can test it.

aurelien-baudet commented 1 year ago

I have issues with the CI. I need to update everything before being able to make a release.

However, I deployed a SNAPSHOT version. So you can test that my fix works.

You need to add the repository for snapshots

    <repositories>
        <repository>
            <id>ossrh-snapshots</id>
            <url>https://oss.sonatype.org/content/repositories/snapshots</url>
            <snapshots><enabled>true</enabled></snapshots>
        </repository>
    </repositories>

And then use the version 4.0.0-SNAPSHOT for Ogham.

Please tell me if it works for you.

Thanks

aurelien-baudet commented 1 year ago

@amirbec86 Did you test the fix ?

amirbec86 commented 1 year ago

Hello @aurelien-baudet, I'm sorry for the delay, I didn't see your previous message, if I delete the bean from the configuration class, and I set the version of ogham to 4.0.0-SNAPSHOT and the repository you indicated, it doesn't work, I get the same error as before: "Error creating bean with name 'mailingService'".

aurelien-baudet commented 1 year ago

This is really strange. I have automatic tests that creates Spring Boot projects on the fly. There are 14000 tested combinations. All are passing.

Could you create a sample project to reproduce the issue ?

hafsaelm30 commented 9 months ago

Hello @aurelien-baudet i'm taking over for this issue.

With the 3.0.0 version we're facing an issue with the processing of thymleaf templates. The messages are not being translated properly so when we receive the emails they just contain the message keys looking like :

??account.deletion.confirmation.email.body.p3_en??

With the 4.0.0-SNAPSHOT version, the project does not compile due to this error :

Unsatisfied dependency expressed through constructor parameter 1: Error creating bean with name 'messagingService' defined in class path resource [com/messaging/configuration/SpringMvcConfiguration.class]: 
Failed to instantiate [fr.sii.ogham.core.service.MessagingService]: Factory method 'messagingService' threw exception with message: javax.mail.Provider: com.sun.mail.imap.IMAPProvider not a subtype","severity":"WARN","logging.googleapis.com/labels":{"logger":"org.springframework.boot.web.servlet.context.AnnotationConfigServletWebServerApplicationContext","context":"default","thread":"restartedMain"}}

Could you help me fix these issues please ?

Thanks

aurelien-baudet commented 9 months ago

Are you using Spring Boot or just Spring with your own configuration ?

With version 3.0.0, are you using thymeleaf with Spring correctly ? Do you already use thymeleaf with internationalization without Ogham ? Have you followed Ogham documentation and examples regarding internationalization with thymeleaf ?

With 4.0.0-SNAPSHOT, it seems that you have a classpath incompatibility (javax.mail package has been replaced by jakarta.mail). This is due to a stupid design in the renaming from javax to jakarta... They renamed the pacakges but not the dependencies. So this can lead to the sun library using javax package while the api dependecy is defined in jakarta package. However, I send some time to detect those classpath incompatibilities and it should log a diagnostic with resolution message... Which version of Spring Boot are you using ? Could you provide the list of dependencies with their version ? Could you create a reduced exemple project so that I can debug quickly ?

I need more information if you want me to help you. I do that on my own time so please help me by giving me the maximum of useful information

hafsaelm30 commented 8 months ago

Hello, I'm using Spring boot in the version 3.0.6 and the spring-boot-starter-thymeleaf.

We've been using Ogham (& Thymleaf templates with internalization) with the 2.5.7 verison of Spring Boot for a year now without issues. The issue happened when we migrated the project to Spring Boot 3 and had to add this dependency :

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

The full dependency tree :

dependency tree.txt

Please let me know if you need more information.

aurelien-baudet commented 8 months ago

Ok this seems to be a classpath issue. Are you using Maven or Gradle ? It seems that you are using Maven but I need to be sure because behaviors are different.

Could you provide me a sample projet (maybe a github private project with the dependencies, your Spring configuration, with the code extract that fails) because I can't reproduce it ? Or at least your whole maven/gradle file and Thymeleaf template example ?