{"record":{"id":"6717a81223880cc0","repo":"pentaho/pentaho-kettle","slug":"unable-to-find-properties-file-resourcename-e","errorCode":null,"errorMessage":"Unable to find properties file '${resourceName}': ${e}","messagePattern":"Unable to find properties file '(.+?)': (.+?)","errorType":"exception","errorClass":"MissingResourceException","httpStatus":null,"severity":"error","filePath":"core/src/main/java/org/pentaho/di/i18n/GlobalMessageUtil.java","lineNumber":334,"sourceCode":"   * @param packagePath\n   * @param resourceClass\n   * @param fallbackOnRoot if true, and a {@link ResourceBundle} cannot be found for the requested {@link Locale}, falls\n   *                       back on the ROOT {@link Locale}\n   * @return a {@link ResourceBundle} corresponding to the given {@link Locale} package and resource class\n   */\n  public static ResourceBundle getBundle( final Locale locale, final String packagePath, final Class<?> resourceClass,\n                                          final boolean fallbackOnRoot ) {\n    final GlobalMessageControl control = new GlobalMessageControl( fallbackOnRoot );\n    final String resourceName = control.toResourceName( control.toBundleName( packagePath, locale ), \"properties\" );\n\n    ResourceBundle bundle;\n    try {\n      bundle = ResourceBundle.getBundle( packagePath, locale, resourceClass.getClassLoader(),\n        new GlobalMessageControl( fallbackOnRoot ) );\n    } catch ( final MissingResourceException e ) {\n      final StringBuilder msg = new StringBuilder();\n      msg.append( \"Unable to find properties file '\" ).append( resourceName ).append( \"': \" ).append( e.toString() );\n      throw new MissingResourceException( msg.toString(), resourceClass.getName(), packagePath );\n    }\n    return bundle;\n  }\n\n  /**\n   * Returns a string corresponding to the locale (Example: \"en\", \"en_US\").\n   *\n   * @param locale The {@link Locale} whose string representation it being returned\n   * @return a string corresponding to the locale (Example: \"en\", \"en_US\").\n   */\n  protected static String getLocaleString( Locale locale ) {\n    final StringBuilder localeString = new StringBuilder();\n    if ( locale != null && !StringUtils.isBlank( locale.getLanguage() ) ) {\n      if ( !StringUtils.isBlank( locale.getCountry() ) ) {\n        // force language to be lower case and country to be upper case\n        localeString.append( locale.getLanguage().toLowerCase() ).append( '_' ).append(\n          locale.getCountry().toUpperCase() );\n      } else {","sourceCodeStart":316,"sourceCodeEnd":352,"githubUrl":"https://github.com/pentaho/pentaho-kettle/blob/f3058517a153da500bf4551f46d79b91bf8ec552/core/src/main/java/org/pentaho/di/i18n/GlobalMessageUtil.java#L316-L352","documentation":"GlobalMessageUtil.getBundle() wraps MissingResourceException thrown by ResourceBundle.getBundle() with a clearer message including the properties file name. The underlying cause is that the locale-specific resource bundle (a .properties file on the classpath for packagePath) could not be located by the GlobalResourceBundleControl. It is rethrown as a MissingResourceException with the original exception appended.","triggerScenarios":"Calling getBundle(resourceClass, packagePath, locale, fallbackOnRoot) when no .properties file matching the base name exists for the requested locale (including any fallback), or the resourceClass's classloader cannot see the properties file.","commonSituations":"A plugin jar is missing its messages_<locale>.properties files; a typo in the package path passed to getBundle; custom language packs not installed; classloader isolation (e.g. in a webapp or Karaf) hides the bundle from the plugin classloader.","solutions":["Verify the .properties file exists at the exact package path for the requested locale (or a default file) inside the jar/classpath","Log/inspect the wrapped cause (e.toString()) to see the original MissingResourceException baseName/locale","Correct the packagePath argument passed to getBundle","Ensure the resourceClass's classloader can load the resource (check plugin packaging/classloader setup)","Install the appropriate language pack or fall back to a default locale"],"exampleFix":"// before\nResourceBundle bundle = GlobalMessageUtil.getBundle( MyClass.class, \"org/wrong/path/messages\", locale, true );\n// after\nResourceBundle bundle = GlobalMessageUtil.getBundle( MyClass.class, \"org/correct/path/messages/messages\", locale, true );","handlingStrategy":"try-catch","validationCode":"ClassLoader cl = MyClass.class.getClassLoader();\nString path = packagePath + \"_\" + locale + \".properties\";\nif ( cl.getResource( path ) == null && cl.getResource( packagePath + \".properties\" ) == null ) {\n  throw new IllegalStateException( \"Bundle resource missing on classpath: \" + packagePath );\n}","typeGuard":"boolean bundleExists = MyClass.class.getClassLoader().getResource( packagePath + \".properties\" ) != null;","tryCatchPattern":"try {\n  bundle = GlobalMessageUtil.getBundle( cls, packagePath, locale, true );\n} catch ( MissingResourceException e ) {\n  log.warn( \"i18n bundle missing, using default locale\", e );\n  bundle = GlobalMessageUtil.getBundle( cls, packagePath, Locale.ENGLISH, true );\n}","preventionTips":["Verify properties files are packaged in the jar after build","Always ship a default locale-less properties file","Test getBundle for each supported locale in CI"],"tags":["i18n","resource-bundle","classpath","missing-resource"],"backgroundTag":"resource-not-found","analyzedSha":"f3058517a153da500bf4551f46d79b91bf8ec552","analyzedAt":"2026-09-13T14:04:16.340Z","contentChangedAt":"2026-09-13T14:04:16.340Z","schemaVersion":2},"datasetVersion":"2026-09-20T23:17:15.980Z"}