Customizing project templates (in terms of gradle)

Could it be possible to put e.g. repository configuration for dependency resolution and publishing into seperate files and make the use of the gradle wrapper optional?

This is why. We are developing in a network environment which is not connected to the internet. After creating projects with the Jmix wizards lots of errors encounter because we have to make a certain amount of changes.

The gradle wrapper script created by the wizard tries to download a gradle instance from the internet. We are using a local gradle installation (currently 7.3.3) and need to specify using that installation manually.

For build script resolution we have to add a section to the settings.gradle file:

pluginManagement {
  repositories {
    mavenLocal()
    maven {
      /* proxy gradle plugin repository */
      url 'https://nexus.company.com/content/repositories/gradle-plugins'
    }
  }
}

For code artifact dependency resolution we are using a repository proxy application for maven central and the jmix repository:

repositories {
  mavenLocal()
  maven {
    url 'https://maven.company.com'
  }
  maven {
    /* proxy maven central */
    url 'https://nexus.company.com/content/repositories/central'
    content {
      excludeGroupByRegex "com\\.company.*"
    }
  }
  maven {
    /* proxy jmix repositories */
    url 'https://nexus.company.com/content/repositories/jmix'
    content {
      excludeGroupByRegex "com\\.company.*"
    }
  }
}

Could it be possible to introduce something that saves us doing the for every single project.

This is also a task when downloading sample projects to reproduce issues or trying suggested example code.

You can create and use your own set of templates published on your own artifact repository.

Studio loads the list of templates from the first repository in the list which has the io.jmix.templates.studio:jmix-studio-templates artefact. Normally it’s a set of templates built by us from the https://github.com/Haulmont/jmix-templates repo for each Jmix release. But you can clone this repo, add your own templates and publish them to your private artefact repository.

For example:

cd jmix-templates
./gradlew publish -PjmixUploadUrl=http://localhost:8081/repository/maven-snapshots/ -PjmixUploadUser=admin -PjmixUploadPassword=admin

Then when creating a new project in Studio, select a custom configuration and add your repository to the start of the list, for example:
image

After that, you should see your templates on the next step of the wizard. If not, restart the IDE once (your repository will remain in the list).

Ok, I will think about that. Two considerations about that…

  1. Will still have to synchronize changes on your original templates on each release
  2. If we might commit and push some projects to a (more) public source code repository and want to invite developers who are developing in another (regular Internet environment), this approach does not work straight forward

Your concerns are absolutely valid.

We’ve recently filed an issue for improvement in this area: Ability to create custom project template : JST-2553. Will try to do it in the next feature release.

3 Likes

@krivopustov After some time, I tried to implement such studio custom templates.

I published the customized variant (based on release_2_7) to my local maven repository.

Then I tried to test it by creating a new Jmix project and checked Use local Maven repository.
jmix-studio-templates_local-maven

But it seems to be ignored for template lookup?
(How) can I debug the use of template lookups?

Edit: I tried it with IntelliJ IDEA 2025.3.4 with Jmix Plugin version 2.7.3-253

Hi Steffen,

After publishing templates into local Maven repo, exit the IDE, then remove the following folders:

See also Custom Project Templates :: Jmix Documentation

Regards,
Konstantin

1 Like

@krivopustov Thank you for linking the documentation I missed.

I tried to do so, but I am still not getting the custom built templates found.

To test the lookup, I opened the New Project dialog, switched to custom configuration, unchecked all network repositories and checked local repository only. After doing so, the available versions disappear and an error notification is shown.
The idea.log excerpt during these actions reads:

2026-03-24 13:22:25,718 [  25806]   INFO - #com.haulmont.jmixstudio.backend.template.JmixRemoteArtifactsManager - Start loading list of remote artifacts
2026-03-24 13:22:25,719 [  25807]   INFO - #com.haulmont.jmixstudio.backend.maven.RemoteMavenRepository - Loading artifacts list from https://global.repo.jmix.io/repository/public
2026-03-24 13:22:25,720 [  25808]   INFO - #com.haulmont.jmixstudio.backend.maven.RemoteMavenRepository - [external_req] Load file content https://global.repo.jmix.io/repository/public/com/layertec/lib/jmix/jmix-studio-templates/maven-m
etadata.xml
2026-03-24 13:22:25,880 [  25968]   INFO - #com.haulmont.jmixstudio.backend.template.JmixRemoteArtifactsManager - Start loading list of remote artifacts
2026-03-24 13:22:25,880 [  25968]   INFO - #com.haulmont.jmixstudio.backend.maven.RemoteMavenRepository - Loading artifacts list from https://global.repo.jmix.io/repository/public
2026-03-24 13:22:25,880 [  25968]   INFO - #com.haulmont.jmixstudio.backend.maven.RemoteMavenRepository - [external_req] Load file content https://global.repo.jmix.io/repository/public/io/jmix/templates/studio/jmix-studio-templates/mave
n-metadata.xml
2026-03-24 13:22:28,082 [  28170]   INFO - #com.haulmont.jmixstudio.backend.template.JmixRemoteArtifactsManager - Start loading list of remote artifacts
2026-03-24 13:22:28,082 [  28170]   INFO - #com.haulmont.jmixstudio.backend.maven.RemoteMavenRepository - Loading artifacts list from file:///home/bank/.m2/repository/
2026-03-24 13:22:28,082 [  28170]   INFO - #com.haulmont.jmixstudio.backend.maven.RemoteMavenRepository - [external_req] Load file content file:///home/bank/.m2/repository/com/layertec/lib/jmix/jmix-studio-templates/maven-metadata-local
.xml
2026-03-24 13:22:28,082 [  28170]   INFO - #com.haulmont.jmixstudio.backend.template.JmixRemoteArtifactsManager - Start loading list of remote artifacts
2026-03-24 13:22:28,083 [  28171]   INFO - #com.haulmont.jmixstudio.backend.maven.RemoteMavenRepository - Loading artifacts list from https://global.repo.jmix.io/repository/public
2026-03-24 13:22:28,083 [  28171]   INFO - #com.haulmont.jmixstudio.backend.maven.RemoteMavenRepository - [external_req] Load file content https://global.repo.jmix.io/repository/public/com/layertec/lib/jmix/jmix-studio-templates/maven-m
etadata.xml
2026-03-24 13:22:28,175 [  28263]   INFO - #com.haulmont.jmixstudio.backend.template.JmixRemoteArtifactsManager - Start loading list of remote artifacts
2026-03-24 13:22:28,175 [  28263]   INFO - #com.haulmont.jmixstudio.backend.maven.RemoteMavenRepository - Loading artifacts list from file:///home/bank/.m2/repository/
2026-03-24 13:22:28,175 [  28263]   INFO - #com.haulmont.jmixstudio.backend.maven.RemoteMavenRepository - [external_req] Load file content file:///home/bank/.m2/repository/io/jmix/templates/studio/jmix-studio-templates/maven-metadata-lo
cal.xml
2026-03-24 13:22:31,227 [  31315]   INFO - #com.haulmont.jmixstudio.backend.template.JmixRemoteArtifactsManager - Start loading list of remote artifacts
2026-03-24 13:22:31,227 [  31315]   INFO - #com.haulmont.jmixstudio.backend.maven.RemoteMavenRepository - Loading artifacts list from file:///home/bank/.m2/repository/
2026-03-24 13:22:31,227 [  31315]   INFO - #com.haulmont.jmixstudio.backend.template.JmixRemoteArtifactsManager - Start loading list of remote artifacts
2026-03-24 13:22:31,227 [  31315]   INFO - #com.haulmont.jmixstudio.backend.maven.RemoteMavenRepository - Loading artifacts list from https://global.repo.jmix.io/repository/public
2026-03-24 13:22:31,227 [  31315]   INFO - #com.haulmont.jmixstudio.backend.maven.RemoteMavenRepository - [external_req] Load file content https://global.repo.jmix.io/repository/public/com/layertec/lib/jmix/jmix-studio-templates/maven-metadata.xml
2026-03-24 13:22:31,324 [  31412]   INFO - #com.haulmont.jmixstudio.backend.template.JmixRemoteArtifactsManager - Start loading list of remote artifacts
2026-03-24 13:22:31,324 [  31412]   INFO - #com.haulmont.jmixstudio.backend.maven.RemoteMavenRepository - Loading artifacts list from file:///home/bank/.m2/repository/
2026-03-24 13:22:32,547 [  32635]   INFO - #com.haulmont.jmixstudio.backend.template.JmixRemoteArtifactsManager - Start loading list of remote artifacts
2026-03-24 13:22:32,547 [  32635]   INFO - #com.haulmont.jmixstudio.backend.maven.RemoteMavenRepository - Loading artifacts list from file:///home/bank/.m2/repository/
2026-03-24 13:22:32,555 [  32643]   INFO - #com.haulmont.jmixstudio.backend.template.JmixRemoteArtifactsManager - Start loading list of remote artifacts
2026-03-24 13:22:32,555 [  32643]   INFO - #com.haulmont.jmixstudio.backend.maven.RemoteMavenRepository - Loading artifacts list from file:///home/bank/.m2/repository/
2026-03-24 13:22:32,689 [  32777]   WARN - #com.haulmont.jmixstudio.backend.notifydialog.JmixNotificationsManager - Unable to find supported Jmix versions with provided conditions
java.lang.IllegalStateException: Unable to find supported Jmix versions with provided conditions
        at com.haulmont.jmixstudio.backend.notifydialog.JmixNotificationsManager.errorReport(JmixNotificationsManager.java:215)
        at com.haulmont.jmixstudio.backend.notifydialog.JmixNotificationsManager.errorReport(JmixNotificationsManager.java:206)
        at com.haulmont.jmixstudio.intellij.ui.pm.platformVersion.ui.impl.select.VersionSelectorComponents.update(VersionSelectorComponents.kt:183)
        at com.haulmont.jmixstudio.intellij.ui.pm.platformVersion.ui.impl.select.VersionSelectorComponents.updatePlatformVersionField$lambda$1$0(VersionSelectorComponents.kt:166)
        at com.intellij.openapi.application.TransactionGuardImpl.runWithWritingAllowed(TransactionGuardImpl.java:239)
...

I also tried to remove the custom project templates and keep the templates as similar as possible and changed the minimum for a “non-direct-internet-connection environment”:

  • on build.gradle files I replaced the still hard coded gradlePluginPortal() and mavenCentral() by nexus proxied ones
  • replace the distributionUrl on each gradle/wrapper/gradle-wrapper.properties
  • adding a nexus proxied gradle-plugin repository on settings.gradle.kts

I tried to compare the content of the jmix-studio-templates-2.7.6.jar files (the cached Jmix templates downloaded and the own built ones). The only difference are the files mentioned above.

Can I debug more into detail? What is the Jmix studio plugin looking for?

Hi

Did you set your custom template artifact coordinates in Jmix Studio plugin settings as it mentioned in documentation?

Hi @gaslov

Yes, I did.
idea_jmix-settings1

I had to re-check, because I had a little confusion with the Additional templates artifact placeholder value. The placeholder artifact name does not match the templates artifact name. The placeholder artifact name reads studio-templates but the maven publication artifact id reads jmix-studio-templates.
Fixing that still didn’t help.

So I had another closer look to the idea.log. I checked all paths being read and found out, for local maven the expected metadata filename is maven-metadata-local.xml but my generated one is maven-metadata.xml.

Is that the intended lookup - or did I miss something setting up the local maven repository?

Ok, thank you

I’ll check the case and come back

I’ve checked the case.

Indeed, Studio does not allow creating a project without selecting a repository, except for Maven Local. You need to have at least one repository containing Jmix artifacts selected.

Project template(s) defined in your custom templates artifact will take priority if they replace existing Jmix templates. Therefore, you don’t need to remove the Jmix repository.

@gaslov Thank you for rechecking.

After checking a non-local repository - and it should be a Jmix remote repository, the lookup is performed.

I still have issues with the generated maven-metadata.xml file since the studio expects the metadata file to be named maven-metadata-local.xml only for local repositories.

I think this is related to the local maven configuration and/or the Gradle publishing. I have a workaround and now can start developing/testing custom templates.

hello. i’m creating a template too. is it possible to have a different default value as a base package in New Project dialog instead of com.company ?
thank you

Hi,

Thank you for the feedback.
Unfortunately, this is not possible at the moment. We will consider adding the default base package as a template setting in the future.

@gaslov I spent some more hours to retry these days (also trying on a Windows machine). The custom templates are read now, but still no project is created.

Is there anything I can debug myself?

The idea.log contains an exception:

...
2026-04-08 10:12:49,560 [  70229]   WARN - #c.i.c.ComponentStoreImpl - Scheme file "Project_Default.xml" is not loaded because defines duplicated name "Project Default"
2026-04-08 10:12:49,562 [  70231]   INFO - STDERR - Exception in thread "DefaultDispatcher-worker-14" java.lang.RuntimeException: groovy.lang.GroovyRuntimeException: Failed to parse template script (your template may contain an error or be trying to use expressions not currently supported): startup failed:
2026-04-08 10:12:49,562 [  70231]   INFO - STDERR - SimpleTemplateScript65.groovy: 1: Unexpected character: '"' @ line 1, column 13.
2026-04-08 10:12:49,562 [  70231]   INFO - STDERR -    out.print("""distributionBase=GRADLE_USER_HOME
2026-04-08 10:12:49,562 [  70231]   INFO - STDERR -                ^
2026-04-08 10:12:49,562 [  70231]   INFO - STDERR - 
2026-04-08 10:12:49,562 [  70231]   INFO - STDERR - 1 error
2026-04-08 10:12:49,562 [  70231]   INFO - STDERR - 
2026-04-08 10:12:49,562 [  70231]   INFO - STDERR - 	at com.haulmont.jmixstudio.backend.pm.ProjectCreator.createProject(ProjectCreator.java:95)
2026-04-08 10:12:49,562 [  70231]   INFO - STDERR - 	at com.haulmont.jmixstudio.intellij.project.create.jmix.JmixModuleBuilder.commitModule$lambda$0(JmixModuleBuilder.kt:118)
2026-04-08 10:12:49,562 [  70231]   INFO - STDERR - 	at com.intellij.openapi.application.ActionsKt.runWriteAction$lambda$0(actions.kt:12)
2026-04-08 10:12:49,562 [  70231]   INFO - STDERR - 	at com.intellij.platform.locking.impl.NestedLocksThreadingSupport.runWriteActionBlocking(NestedLocksThreadingSupport.kt:997)
2026-04-08 10:12:49,562 [  70231]   INFO - STDERR - 	at com.intellij.openapi.application.impl.ApplicationImpl.runWriteAction(ApplicationImpl.java:1172)
2026-04-08 10:12:49,562 [  70231]   INFO - STDERR - 	at com.intellij.openapi.application.ActionsKt.runWriteAction(actions.kt:12)
2026-04-08 10:12:49,562 [  70231]   INFO - STDERR - 	at com.haulmont.jmixstudio.intellij.project.create.jmix.JmixModuleBuilder.commitModule(JmixModuleBuilder.kt:118)
2026-04-08 10:12:49,562 [  70231]   INFO - STDERR - 	at com.intellij.ide.util.projectWizard.ModuleBuilder.commit(ModuleBuilder.java:356)
2026-04-08 10:12:49,562 [  70231]   INFO - STDERR - 	at com.haulmont.jmixstudio.intellij.project.create.jmix.JmixModuleBuilder.commit(JmixModuleBuilder.kt:77)
2026-04-08 10:12:49,562 [  70231]   INFO - STDERR - 	at com.intellij.ide.impl.NewProjectUtilKt$createProjectFromWizardImpl$5.invokeSuspend(NewProjectUtil.kt:226)
...

Error occurred in the Groovy template engine while processing your template.

Please check the template containing out.print("""distributionBase=GRADLE_USER_HOME and fix it so that it is a valid Groovy template.

@gaslov I had a look for all files containing this and the only files containing them are gradle-wrapper.properties files - as the standard templates do as well, just with another URL (hostname).

What do the scripts do? I tend to skip using the templates and asking an AI tool reverse templating an existing projects. I am still doing black-box trial and error attempts.

The major things I need to adjust are:

  • the gradle-wrapper.properties downloading from a non-internet URL,
  • adding proxied gradle addon repositories in settings.gradle files
  • replacing hard coded mavenCentral() snippets by organization proxied maven central repository.

Because of these three items generating a Jmix application with standard templates is neither downloading the gradle wrapper nor resolving any dependency.

I want to make a trainee able to create an application without modifying dozens of files again and again. I wish the project templates would not assume direct internet access.

Studio simply walks the template’s file tree and processes each file using the Groovy template engine.
So if it fails to process your template, it likely contains invalid syntax.

Would it be possible for you to share your template with any sensitive data (URLs, etc.) removed? That way we can take a closer look.

1 Like