Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Issue with generate task Jte Gradle Plugin in Multi-Module Spring Boot Project #278

Open
robertellam opened this issue Sep 26, 2023 · 7 comments · May be fixed by #279
Open

Issue with generate task Jte Gradle Plugin in Multi-Module Spring Boot Project #278

robertellam opened this issue Sep 26, 2023 · 7 comments · May be fixed by #279
Assignees
Labels
enhancement New feature or request

Comments

@robertellam
Copy link

robertellam commented Sep 26, 2023

Issue Description:

I am encountering an issue with the generate build task using the Jte Gradle Plugin in a multi-module Spring Boot project.

In our project structure, we have a root project called "demo" and two sub-projects named "Application" and "Core." The Application module relies on the Core module. Within the Application Module, we have a template that calls another template located in the Core Module, as demonstrated below:

@template.base(title = "App Template", content = @`<p>App Template extends base</p>`)

During development, this setup works as expected, utilising the ResourceResolver or the CompositeCodeResolver which we came across in another issue. However, issues arise during the build process, leading to the following error:

> base.jte not found (tried to load file at /Users/rob/dev/spring-boot/demo/app/src/main/resources/templates/base.jte), referenced at app.jte:2

base.jte is actually located in Users/rob/dev/spring-boot/demo/core/src/main/resources/templates/base.jte but the generate task only accepts once source directory as far as I am aware?

Question:

Is there a way to configure the Jte Gradle Plugin to function correctly within this multi-module project structure?

Additional Information:

Here is a simplified version of my build.gradle:

buildscript {

    repositories {
        mavenCentral()
        gradlePluginPortal()
    }

    dependencies {
        classpath(libs.spring.boot.gradle.plugin)
        classpath(libs.jte.gradle.plugin)
    }
}

subprojects {

    ...
    apply plugin: 'gg.jte.gradle'
    ...

    jte {
        sourceDirectory = file("${project.projectDir}/src/main/resources/templates").toPath()
        generate()
    }

    ...
}

project(':app') {

    ...

    dependencies {
        api project(':core')
    }
}

project(':core') {

    dependencies {
        api(libs.spring.boot.starter.web)
        api(libs.spring.boot.starter.validation)
        api(libs.spring.boot.starter.security)
        api(libs.spring.boot.starter.data.jpa)
        runtimeOnly(libs.postgresql)
        api(libs.liquibase)
        api(libs.jte)
        api(libs.jte.starter3)
    }
}

Question:

Is it possible for the generate task to resolve templates from multiple sources or modules? Is there anything I can change in my build.gradle to handle this? I think the issue is that the generate task is trying to resolve templates from the source directory of each module independently but it needs to look in multiple directories or modules like it does during development.

Your assistance in resolving this issue is greatly appreciated. Thank you!

@casid
Copy link
Owner

casid commented Sep 28, 2023

Hi @robertellam, welcome and sorry for the late reply.

Currently jte is expecting all templates to live in one root directory. This is expected by the build plugins (maven/gradle) and the IntelliJ plugin.

We had a similiar issue once, but that one could be resolved differently:
#191

@robertellam
Copy link
Author

@casid thanks for your reply. Are there any plans for the gradle plug-in to support multiple directories? I think this might block us from using jte in a multi module spring boot project 😭. Is there anyway we can override the gradle plug-in or use some sort of gradle task to copy all the templates into one location before the generate task?

@casid
Copy link
Owner

casid commented Sep 29, 2023

We already have a .jteroot file, which is used by the IntelliJ plugin to find out where the jte root directory is located.

Currently, this file is always empty, but we could use it to specify further template directories. In your project, this would look like this:

.jteroot located at jetset-demo/app/src/main/resources/templates/.jteroot

@import ../../../../../../core/src/main/resources/templates

I did some prototyping this morning with the IntelliJ plugin (which always is the hardest part when it comes to new features). This looked quite promising and I got highlighting and auto-completion working without too much effort or by complicating the plugin too much. Plugin Pull Request: casid/jte-intellij#35

In jte itself, we would need to teach the DirectoryCodeResolver about imports in .jteroot. Then, Gradle and Maven plugin should work out of the box. I'm not quite sure about the ResourceCodeResolver yet, because that one won't be able to follow those paths.

@edward3h I'm not sure if this change would have an impact on the jte-models project. Any objections/concerns about this from your side?

@casid
Copy link
Owner

casid commented Sep 29, 2023

Another thought I just had, maybe we don't want to make the same mistake as Java did and forbid split packages by default?

@casid casid self-assigned this Sep 29, 2023
@casid casid added the enhancement New feature or request label Sep 29, 2023
casid added a commit that referenced this issue Sep 29, 2023
casid added a commit that referenced this issue Sep 30, 2023
casid added a commit that referenced this issue Sep 30, 2023
@casid casid linked a pull request Sep 30, 2023 that will close this issue
@casid casid linked a pull request Sep 30, 2023 that will close this issue
casid added a commit that referenced this issue Oct 1, 2023
@casid
Copy link
Owner

casid commented Oct 7, 2023

@robertellam What I'd like to add to jte is a way to define modules, so that all template of a module still need be located in one root directory, but modules can import other modules from different locations. This way your issue would be solved, but we also could have in theory public component libraries that can be imported by other jte projects. However, this will take a while until it is finished. Currently there's a prototype running, but this needs a few more iterations and more thoughts to be releaseable. I don't expect it to be ready in the near future.

For your application, you could of course copy all templates into one directory and build from there. What you'll be missing though, is IDE support for your templates, for instance you won't get auto-complete when you use a template from your shared module in your app module.

@milgner
Copy link

milgner commented Nov 29, 2023

I wonder: could this mechanism also be used in scenarios where there are multiple class loaders? I'm currently working on an application that uses plugins to dynamically load new functionality and would like to enable plugins to bring their own templates.

Right now I'm at the point where I managed to have a separate src/main/jte directory in each plugin and have it generate and bundle class files via Gradle.

But then I got stuck with TemplateLoader not being able to find the class because it was ignoring the class loader that I passed in to createPrecompiled: because the template classes are spread among multiple plugins, I decided to leave the classDirectory argument null - at which point RuntimeTemplateLoader::createClassLoader used Thread.currentThread().getContextClassLoader() instead of the one I supplied.

There was a simple fix for that and things are working fine now - but of course I am aware that the original code must have been there for a reason, too 😅

@C0mbatwombat
Copy link

The module system would be a nice addition to the (already great) system!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants