Resolving FontManagerFactory Errors in Ambience/Repertoire Server

This error below originates from the FontManagerFactory class while rendering reports using the Ambience/Repertoire report rendering engine. It occurs during font-related operations when the required environment or libraries are not fully configured.

18:28:18.006 ERROR com.elixirtech.report2.ReportEngine - doRenderReport RenderException: LogicalRenderer: java.lang.InternalError: java.lang.reflect.InvocationTargetException
java.lang.InternalError: java.lang.reflect.InvocationTargetException
                at java.desktop/sun.font.FontManagerFactory$1.run(FontManagerFactory.java:87)
                at java.base/java.security.AccessController.doPrivileged(AccessController.java:318)
                at java.desktop/sun.font.FontManagerFactory.getInstance(FontManagerFactory.java:75)
                at java.desktop/java.awt.Font.getFont2D(Font.java:526)
                at java.desktop/java.awt.Font.defaultLineMetrics(Font.java:2398)
 
com.elixirtech.report2.RenderException: LogicalRenderer: java.lang.InternalError: java.lang.reflect.InvocationTargetException
                at com.elixirtech.report2.logical.LogicalRenderer.process(LogicalRenderer.java:142)
                at com.elixirtech.report2.engine.PagedLogicalRendererEngine.process(PagedLogicalRendererEngine.java:21)
                at com.elixirtech.report2.engine.AbstractPipeline.process(AbstractPipeline.scala:28)
                at com.elixirtech.report2.ReportEngine$.renderRMLWithExternalJobLog(ReportEngine.scala:92)
                at com.elixirtech.report2.ReportEngine$.renderRMLWithExternalJobLog(ReportEngine.scala:70)
                at ambience.rmlengine.RMLEngineAPI.$anonfun$1$$anonfun$1$$anonfun$1$$anonfun$1(RMLEngineAPI.scala:54)
                at ambience.rmlengine.RMLEngineAPI.$anonfun$1$$anonfun$1$$anonfun$1$$anonfun$adapted$1(RMLEngineAPI.scala:55)
                at ambience.rml.AuthWrapper$.withUser$$anonfun$1$$anonfun$1(AuthWrapper.scala:18)
                at ambience.module.CurrentUser$.withUser$$anonfun$1(CurrentUser.scala:9)
                at scala.util.DynamicVariable.withValue(DynamicVariable.scala:59)
                at ambience.module.CurrentUser$.withUser(CurrentUser.scala:9)
                at ambience.rml.AuthWrapper$.withUser$$anonfun$1(AuthWrapper.scala:19)
                at com.elixirtech.arch.security.Authentication$.setCredentials$$anonfun$1(Authentication.scala:148)
                at scala.util.DynamicVariable.withValue(DynamicVariable.scala:59)
                at com.elixirtech.arch.security.Authentication$.setCredentials(Authentication.scala:148)
                at com.elixirtech.arch.security.Authentication$.withCredentials(Authentication.scala:40)
                at ambience.rml.AuthWrapper$.withUser(AuthWrapper.scala:20)
                at ambience.rmlengine.RMLEngineAPI.$anonfun$1$$anonfun$1$$anonfun$1(RMLEngineAPI.scala:55)
                at ambience.rmlengine.RMLEngineAPI.$anonfun$1$$anonfun$1$$anonfun$adapted$1(RMLEngineAPI.scala:56)
                at com.elixirtech.arch.job.JobLogging$.run$$anonfun$2(JobLogging.scala:229)
                at com.elixirtech.arch.job.JobLogging$.run$$anonfun$adapted$2(JobLogging.scala:239)
                at scala.util.DynamicVariable.withValue(DynamicVariable.scala:59)
                at com.elixirtech.arch.job.JobLogging$.run(JobLogging.scala:239)
                at ambience.rmlengine.RMLEngineAPI.$anonfun$1$$anonfun$1(RMLEngineAPI.scala:56)
                at ambience.rmlengine.RMLEngineAPI.$anonfun$1$$anonfun$adapted$1(RMLEngineAPI.scala:58)
                at monix.eval.internal.TaskRunLoop$.startFull(TaskRunLoop.scala:88)
                at monix.eval.internal.TaskRunLoop$.restartAsync$$anonfun$1(TaskRunLoop.scala:241)
                at monix.execution.internal.InterceptRunnable.run(InterceptRunnable.scala:27)
                at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1136)
                at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:635)
                at java.base/java.lang.Thread.run(Thread.java:840)

The issue is caused because OpenJDK does not have the fontconfig package by default. This package is necessary for Java to manage font configuration and rendering properly. Without it, the Java Runtime Environment (JRE) fails to initialize the font management system.

To resolve this issue:

  1. Install the fontconfig package:
  • For Red Hat-based Linux distributions:
    sudo yum install fontconfig
    
  • For Debian-based Linux distributions:
    sudo apt-get install fontconfig
    
  1. Run the following command to check if fontconfig is installed and functional:
    fc-list

    This command should list the available fonts, confirming that the package is properly installed.

  2. Execute the following command to reload font configurations:

    fc-cache -fv
    
  3. After installing the fontconfig package, restart the Elixir Server to ensure the changes take effect.

Additional Notes:

  • Add Extra Fonts if Necessary: If additional TTF fonts are required, copy them to the /usr/share/fonts/TTF directory and repeat the fc-cache -fv command to load the new fonts.

  • Ensure the Java version used by the server is compatible with the installed font configuration libraries.

  • If the issue persists, verify the environment variables (e.g., JAVA_HOME and PATH) and ensure they point to the correct Java installation.