diff --git a/.blueprint/github-build-matrix/__snapshots__/generator.spec.ts.snap b/.blueprint/github-build-matrix/__snapshots__/generator.spec.ts.snap index adf6488c0058..ebfd54fef5b3 100644 --- a/.blueprint/github-build-matrix/__snapshots__/generator.spec.ts.snap +++ b/.blueprint/github-build-matrix/__snapshots__/generator.spec.ts.snap @@ -574,7 +574,6 @@ exports[`generator - github-build-matrix with graalvm should match matrix value "npm-version": "NPM-VERSION", "default-environment": "prod", "jwt-secret-key": "ZjY4MTM4YjI5YzMwZjhjYjI2OTNkNTRjMWQ5Y2Q0Y2YwOWNmZTE2NzRmYzU3NTMwM2NjOTE3MTllOTM3MWRkMzcyYTljMjVmNmQ0Y2MxOTUzODc0MDhhMTlkMDIxMzI2YzQzZDM2ZDE3MmQ3NjVkODk3OTVmYzljYTQyZDNmMTQ=", - "jdl-base": "application {\\n config {\\n testFrameworks [cypress]\\n buildTool maven\\n cacheProvider no\\n }\\n}", "jdl": "application {\\n config {\\n testFrameworks [cypress]\\n buildTool maven\\n graalvmSupport true\\n }\\n}" }, { @@ -586,7 +585,6 @@ exports[`generator - github-build-matrix with graalvm should match matrix value "npm-version": "NPM-VERSION", "default-environment": "prod", "jwt-secret-key": "ZjY4MTM4YjI5YzMwZjhjYjI2OTNkNTRjMWQ5Y2Q0Y2YwOWNmZTE2NzRmYzU3NTMwM2NjOTE3MTllOTM3MWRkMzcyYTljMjVmNmQ0Y2MxOTUzODc0MDhhMTlkMDIxMzI2YzQzZDM2ZDE3MmQ3NjVkODk3OTVmYzljYTQyZDNmMTQ=", - "jdl-base": "application {\\n config {\\n testFrameworks [cypress]\\n buildTool maven\\n reactive true\\n cacheProvider no\\n }\\n}", "jdl": "application {\\n config {\\n testFrameworks [cypress]\\n buildTool maven\\n reactive true\\n graalvmSupport true\\n }\\n}" }, { @@ -598,7 +596,6 @@ exports[`generator - github-build-matrix with graalvm should match matrix value "npm-version": "NPM-VERSION", "default-environment": "prod", "jwt-secret-key": "ZjY4MTM4YjI5YzMwZjhjYjI2OTNkNTRjMWQ5Y2Q0Y2YwOWNmZTE2NzRmYzU3NTMwM2NjOTE3MTllOTM3MWRkMzcyYTljMjVmNmQ0Y2MxOTUzODc0MDhhMTlkMDIxMzI2YzQzZDM2ZDE3MmQ3NjVkODk3OTVmYzljYTQyZDNmMTQ=", - "jdl-base": "application {\\n config {\\n testFrameworks [cypress]\\n buildTool gradle\\n cacheProvider no\\n }\\n}", "jdl": "application {\\n config {\\n testFrameworks [cypress]\\n buildTool gradle\\n graalvmSupport true\\n }\\n}" }, { @@ -610,7 +607,6 @@ exports[`generator - github-build-matrix with graalvm should match matrix value "npm-version": "NPM-VERSION", "default-environment": "prod", "jwt-secret-key": "ZjY4MTM4YjI5YzMwZjhjYjI2OTNkNTRjMWQ5Y2Q0Y2YwOWNmZTE2NzRmYzU3NTMwM2NjOTE3MTllOTM3MWRkMzcyYTljMjVmNmQ0Y2MxOTUzODc0MDhhMTlkMDIxMzI2YzQzZDM2ZDE3MmQ3NjVkODk3OTVmYzljYTQyZDNmMTQ=", - "jdl-base": "application {\\n config {\\n testFrameworks [cypress]\\n buildTool gradle\\n reactive true\\n cacheProvider no\\n }\\n}", "jdl": "application {\\n config {\\n testFrameworks [cypress]\\n buildTool gradle\\n reactive true\\n graalvmSupport true\\n }\\n}" } ] diff --git a/.blueprint/github-build-matrix/generator.ts b/.blueprint/github-build-matrix/generator.ts index 55569bb11f1b..9f0860a22fff 100644 --- a/.blueprint/github-build-matrix/generator.ts +++ b/.blueprint/github-build-matrix/generator.ts @@ -44,7 +44,7 @@ export default class extends BaseGenerator { // Push events requires a base commit for diff. Diff cannot be checked by @~1 if PR was merged with a rebase. const useChanges = this.eventName === 'pull_request'; const changes = await getGitChanges({ allTrue: !useChanges }); - const { base, common, devBlueprint, client, e2e, java, workspaces } = changes; + const { base, common, devBlueprint, client, e2e, graalvm, java, workspaces } = changes; const hasWorkflowChanges = changes[`${this.workflow}Workflow`]; let matrix: GitHubMatrixRecord = {}; @@ -52,7 +52,7 @@ export default class extends BaseGenerator { if (this.workflow === 'docker-compose-integration') { matrix = dockerComposeMatrix; } else if (this.workflow === 'graalvm') { - if (hasWorkflowChanges || java) { + if (hasWorkflowChanges || java || graalvm) { matrix = graalvmMatrix; } } else if (this.workflow === 'devserver') { diff --git a/.blueprint/github-build-matrix/samples/graalvm.ts b/.blueprint/github-build-matrix/samples/graalvm.ts index ff90eced2178..2e0a07aa09cd 100644 --- a/.blueprint/github-build-matrix/samples/graalvm.ts +++ b/.blueprint/github-build-matrix/samples/graalvm.ts @@ -16,7 +16,6 @@ export const graalvmMatrix = Object.fromEntries( key, { 'java-version': '21', - 'jdl-base': convertOptionsToJDL({ ...value, cacheProvider: 'no' }), jdl: convertOptionsToJDL({ ...value, graalvmSupport: true }), }, ]), diff --git a/.blueprint/github-build-matrix/support/git-changes.ts b/.blueprint/github-build-matrix/support/git-changes.ts index e121b29d844d..768afe62c3b6 100644 --- a/.blueprint/github-build-matrix/support/git-changes.ts +++ b/.blueprint/github-build-matrix/support/git-changes.ts @@ -10,7 +10,8 @@ export const getGitChanges = async (options: { allTrue?: boolean } = {}) => { const git = simpleGit({ baseDir: fileURLToPath(new URL('../../', import.meta.url).href) }); const summary = await git.diffSummary({ '@~1': null }); const files = summary.files.map(({ file }) => file); - hasPatternChanges = (pattern: string) => files.some(file => minimatch(file, pattern, { dot: true })); + hasPatternChanges = (pattern: string, ignore?: string) => + files.some(file => minimatch(file, pattern, { dot: true }) && (!ignore || !minimatch(file, ignore, { dot: true }))); } const hasClientWorkflowChanges = (client: 'angular' | 'react' | 'vue') => @@ -29,7 +30,11 @@ export const getGitChanges = async (options: { allTrue?: boolean } = {}) => { common: hasPatternChanges('generators/{app,common,docker,languages}/**'), client: hasPatternChanges('generators/{client,init,javascript}/**'), e2e: hasPatternChanges('generators/cypress/**'), - java: hasPatternChanges('generators/{cucumber,feign-client,gatling,gradle,java,liquibase,maven,server,spring*}/**'), + java: hasPatternChanges( + 'generators/{cucumber,feign-client,gatling,gradle,java,liquibase,maven,server,spring*}/**', + 'generators/java/generators/graalvm/**', + ), + graalvm: hasPatternChanges('generators/java/generators/graalvm/**'), react: hasPatternChanges('generators/react/**'), reactWorkflow: hasClientWorkflowChanges('react'), workspaces: hasPatternChanges('generators/{docker-compose,kubernetes*,workspaces}/**'), diff --git a/generators/base/shared-data.ts b/generators/base/shared-data.ts index 45a51205ae11..76c8b1781692 100644 --- a/generators/base/shared-data.ts +++ b/generators/base/shared-data.ts @@ -105,6 +105,7 @@ export default class SharedData) => { + if (!jhipsterOldVersion) return; await Promise.all( Object.entries(cleanup).map(async ([version, files]) => { const stringFiles: string[] = []; diff --git a/generators/java/generators/graalvm/__snapshots__/generator.spec.ts.snap b/generators/java/generators/graalvm/__snapshots__/generator.spec.ts.snap index d1f44455accf..f5985e082143 100644 --- a/generators/java/generators/graalvm/__snapshots__/generator.spec.ts.snap +++ b/generators/java/generators/graalvm/__snapshots__/generator.spec.ts.snap @@ -15,7 +15,12 @@ exports[`generator - java:graalvm with default options should call source snapsh \${native-image-name} true + + -Duser.language=en + -H:IncludeLocales= + + -Xms4g -Xmx10g ", @@ -131,6 +136,17 @@ exports[`generator - java:graalvm with default options should call source snapsh ], }, ], + "addNativeHint": [ + { + "advanced": [ + "hints.reflection().registerType(sun.misc.Unsafe.class, (hint) -> hint.withMembers(MemberCategory.INVOKE_PUBLIC_METHODS));", + "hints.reflection().registerType(java.util.Locale.class, (hint) -> hint.withMembers(MemberCategory.INVOKE_PUBLIC_METHODS));", + ], + "resources": [ + "i18n/*", + ], + }, + ], "editJavaFile": [ [ "src/main/java/com/mycompany/myapp/JhipsterApp.java", @@ -170,6 +186,17 @@ exports[`generator - java:graalvm with default options should call source snapsh "version": "'NATIVE-BUILD-TOOLS-VERSION'", }, ], + "addNativeHint": [ + { + "advanced": [ + "hints.reflection().registerType(sun.misc.Unsafe.class, (hint) -> hint.withMembers(MemberCategory.INVOKE_PUBLIC_METHODS));", + "hints.reflection().registerType(java.util.Locale.class, (hint) -> hint.withMembers(MemberCategory.INVOKE_PUBLIC_METHODS));", + ], + "resources": [ + "i18n/*", + ], + }, + ], "applyFromGradle": [ { "script": "gradle/native.gradle", diff --git a/generators/java/generators/graalvm/generator.ts b/generators/java/generators/graalvm/generator.ts index f5b7923c641f..bfbc78453524 100644 --- a/generators/java/generators/graalvm/generator.ts +++ b/generators/java/generators/graalvm/generator.ts @@ -179,11 +179,17 @@ export default class GraalvmGenerator extends BaseApplicationGenerator { }, async customizeMaven({ application, source }) { - const { buildToolMaven, reactive, databaseTypeSql, javaDependencies } = application; + const { buildToolMaven, reactive, databaseTypeSql, javaDependencies, nativeLanguageDefinition, languagesDefinition } = application; if (!buildToolMaven) return; source.addMavenDefinition!( - mavenDefinition({ reactive, nativeBuildToolsVersion: javaDependencies!.nativeBuildTools!, databaseTypeSql }), + mavenDefinition({ + reactive, + nativeBuildToolsVersion: javaDependencies!.nativeBuildTools!, + databaseTypeSql, + userLanguage: nativeLanguageDefinition.languageTag, + languages: languagesDefinition.map(def => def.languageTag), + }), ); }, @@ -237,6 +243,19 @@ export default class GraalvmGenerator extends BaseApplicationGenerator { ), ); }, + nativeHints({ source, application }) { + if (!application.backendTypeSpringBoot) return; + + source.addNativeHint!({ + advanced: [ + // Undertow + 'hints.reflection().registerType(sun.misc.Unsafe.class, (hint) -> hint.withMembers(MemberCategory.INVOKE_PUBLIC_METHODS));', + // Thymeleaf template + 'hints.reflection().registerType(java.util.Locale.class, (hint) -> hint.withMembers(MemberCategory.INVOKE_PUBLIC_METHODS));', + ], + resources: ['i18n/*'], + }); + }, }); } diff --git a/generators/java/generators/graalvm/internal/maven-definition.ts b/generators/java/generators/graalvm/internal/maven-definition.ts index acd4d9c0dea0..f6dcb2cfc0c1 100644 --- a/generators/java/generators/graalvm/internal/maven-definition.ts +++ b/generators/java/generators/graalvm/internal/maven-definition.ts @@ -5,10 +5,14 @@ export const mavenDefinition = ({ reactive, nativeBuildToolsVersion, databaseTypeSql, + userLanguage, + languages, }: { reactive?: boolean; nativeBuildToolsVersion?: string; databaseTypeSql?: boolean; + userLanguage: string; + languages: string[]; }): MavenDefinition => ({ properties: [ { property: 'repackage.classifier' }, @@ -29,7 +33,12 @@ export const mavenDefinition = ({ \${native-image-name} true + + -Duser.language=${userLanguage} + -H:IncludeLocales=${languages.join(',')} + + -Xms4g -Xmx10g `, diff --git a/generators/java/generators/graalvm/templates/gradle/native.gradle.ejs b/generators/java/generators/graalvm/templates/gradle/native.gradle.ejs index cd5fb15a731a..5e286ba13f42 100644 --- a/generators/java/generators/graalvm/templates/gradle/native.gradle.ejs +++ b/generators/java/generators/graalvm/templates/gradle/native.gradle.ejs @@ -8,12 +8,14 @@ graalvmNative { // languageVersion = JavaLanguageVersion.of(19) // vendor = JvmVendorSpec.matching("GraalVM Community") //} + buildArgs.add("-Duser.language=<%- nativeLanguageDefinition.languageTag %>") + buildArgs.add("-H:IncludeLocales=<%- languagesDefinition.map(def => def.languageTag).join(',') %>") } - binaries.all { - verbose = true - jvmArgs.add('-Xms4g') - jvmArgs.add('-Xmx10g') - } + } + binaries.all { + verbose = true + jvmArgs.add('-Xms4g') + jvmArgs.add('-Xmx10g') } } diff --git a/generators/liquibase/generator.ts b/generators/liquibase/generator.ts index f447b8e4b9bb..085d0f21b6e7 100644 --- a/generators/liquibase/generator.ts +++ b/generators/liquibase/generator.ts @@ -517,7 +517,6 @@ export default class LiquibaseGenerator extends BaseEntityChangesGenerator { // Hints may be dropped if newer version is supported // https://github.com/oracle/graalvm-reachability-metadata/blob/master/metadata/org.liquibase/liquibase-core/index.json source.addNativeHint!({ - advanced: ['hints.resources().registerPattern("");'], resources: ['config/liquibase/*'], declaredConstructors: [ 'liquibase.database.LiquibaseTableNamesFactory.class',