Spring Boot 2.7

As part of the LuciadFusion 2023.0 release, the Spring Boot dependencies were upgraded from version 2.1 to 2.7. Because the 2.7 version has many changes, you may run into one of these issues after upgrading from LuciadFusion 2022.1 or earlier to LuciadFusion 2023.0 or later.

Configuration file processing has changed

Spring Boot 2.4 has changed the way that YAML files are processed. Because of this, you can no longer use spring.profiles.include in profile-specific YAML files. If you only want to import other YAML files and aren’t interested in activating a profile, you can use spring.config.import as an alternative. If you do want other profiles activated, you can use the new Profile Groups feature.

For more information, see the Spring Boot Config Data Migration Guide .

Please note that the YAML files provided with LuciadFusion have already been migrated. This means that it is not possible to use the spring.config.use-legacy-processing property to revert to the legacy way of processing YAML files.

Circular references prohibited by default

Circular reference detection has become stricter. This means that, for example, self injection is no longer possible. If your application fails to start due to a BeanCurrentlyInCreationException, it strongly encouraged to update your configuration to break the dependency cycle.

For more information, see the Spring Boot 2.6 release notes.

Property server.use-forward-headers deprecated

The server.use-forward-headers property has been deprecated in favor of server.forward-headers-strategy. If you were using server.use-forward-headers: true, then you need to update it to server.forward-headers-strategy: native. For more information, see the Spring Boot 2.2 release notes.

YAML format

Do not use tabs, use spaces

A correct indentation in YAML files is really important. Tabs should never be used. A good format is to use 2 spaces for an indentation level. The following example shows 2 server properties server.servlet.context-path and server.port:

server:
  servlet.context-path: /path
  port: 8080

Error: Duplicate key

Property keys or parts of property keys cannot be used more than once in the same YAML file.

Wrong:

fusion.security:
    enabled: true
fusion.security.cors.origins: "*"
fusion.security:
    authenticationManager: ldap

The key fusion.security is encountered twice. The correct use is:

fusion.security:
    enabled: true
    cors.origins: "*"
    authenticationManager: ldap

Properties and Spring profiles

Overwriting properties and spring.config.import

When a property is defined two times in two separate profiles, the value of the property of the rightmost active profile is taken. For example, when you have -Dspring.profiles.active=fusion.single,custom.profile, the properties re-defined in custom.profile will overwrite the ones defined in fusion.single profile.

If a property occurs in a profile as well as in its imported configuration file, the property values in the imported configuration file takes precedence.

For example, file fusion.common.yml configuration file specifies:

fusion.security.enabled: true

File application-fusion.testing.yml specifies:

spring.config.import: classpath:fusion.common.yml
fusion.security.enabled: false

The resulting value of fusion.security.enabled is true. From the Spring Javadoc for spring.config.import: Imports are processed as they are discovered, and are treated as additional documents inserted immediately below the one that declares the import.

Disabling authentication

During development, you may not want to log into the LuciadFusion Studio application. Simply setting the fusion.security.enabled to false removes the login step. Every user will automatically be logged in as fusion_guest_user.

Spring Boot Actuator

LuciadFusion includes the Spring Boot Actuator module. It enables several handy features to monitor and debug your application through the endpoints it exposes. Those endpoints are secured by default.

A non-exhaustive list of Actuator endpoints:

  • env : exposes system properties and all properties from Spring’s ConfigurableEnvironment.

  • configprops : displays a collated list of all @ConfigurationProperties. It allows you to see the resolved property values.

  • beans : displays a complete list of all the Spring beans in your application.

  • mappings : displays a collated list of all exposed endpoints, meaning all @RequestMapping paths.

  • loggers : shows and modifies the configuration of loggers in the application.

  • shutdown : allows the application to be gracefully shut down. This is not enabled by default. Enable it by setting the property management.endpoints.shutdown.enabled: true and adding 'shutdown' to the list of endpoints listed in the property management.endpoints.web.exposure.include.

  • trace : displays trace information. By default, the last 100 HTTP requests are displayed.

Liquibase could not acquire change log lock

LuciadFusion Studio uses a tool called Liquibase to handle the migration of the database to the new database schema for every new release of LuciadFusion. This tool gets run automatically by Studio at startup.

Liquibase uses a distributed locking system to only allow one process to update the database at a time. The other processes will simply wait until the lock has been released. It is possible that this lock does not get released If the LuciadFusion Studio startup gets interrupted during a Liquibase migration. If this occurs, the next time Studio gets started, it will seem to hang for a long time, after which the following error will be printed on the console.

2018-12-18 18:08:25.675 ERROR 26079 --- [           main] o.s.boot.SpringApplication               : Application run failed
 org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'com.luciad.internal.fusion.platform.studio.service.configuration.InstallerConfiguration': Invocation of init method failed; nested exception is org.springframework.context.ApplicationContextException: Failed to create application context; nested exception is liquibase.exception.LockException: Could not acquire change log lock.  Currently locked by 148.53.163.85 (148.53.163.85) since 12/18/18 6:02 PM
  at org.springframework.beans.factory.annotation.InitDestroyAnnotationBeanPostProcessor.postProcessBeforeInitialization(InitDestroyAnnotationBeanPostProcessor.java:139)
  at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyBeanPostProcessorsBeforeInitialization(AbstractAutowireCapableBeanFactory.java:419)
  at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1737)
  at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:576)
  at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:498)
  at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:320)
  at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:222)
  at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:318)
  at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:199)
  at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:846)
  at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:863)
  at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:546)
  at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.refresh(ServletWebServerApplicationContext.java:140)
  at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:775)
  at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:397)
  at org.springframework.boot.SpringApplication.run(SpringApplication.java:316)
  at org.springframework.boot.SpringApplication.run(SpringApplication.java:1260)
  at org.springframework.boot.SpringApplication.run(SpringApplication.java:1248)
  at com.luciad.fusion.platform.TLfnFusionPlatformApplication.main(TLfnFusionPlatformApplication.java:53)
Caused by: org.springframework.context.ApplicationContextException: Failed to create application context; nested exception is liquibase.exception.LockException: Could not acquire change log lock.  Currently locked by 148.53.163.85 (148.53.163.85) since 12/18/18 6:02 PM
  at com.luciad.internal.fusion.platform.studio.service.configuration.InstallerConfiguration.runInstaller(InstallerConfiguration.java:58)
  at java.util.ArrayList.forEach(ArrayList.java:1257)
  at com.luciad.internal.fusion.platform.studio.service.configuration.InstallerConfiguration.runInstallers(InstallerConfiguration.java:42)
  at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
  at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
  at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
  at java.lang.reflect.Method.invoke(Method.java:498)
  at org.springframework.beans.factory.annotation.InitDestroyAnnotationBeanPostProcessor$LifecycleElement.invoke(InitDestroyAnnotationBeanPostProcessor.java:363)
  at org.springframework.beans.factory.annotation.InitDestroyAnnotationBeanPostProcessor$LifecycleMetadata.invokeInitMethods(InitDestroyAnnotationBeanPostProcessor.java:307)
  at org.springframework.beans.factory.annotation.InitDestroyAnnotationBeanPostProcessor.postProcessBeforeInitialization(InitDestroyAnnotationBeanPostProcessor.java:136)
  ... 18 common frames omitted
Caused by: liquibase.exception.LockException: Could not acquire change log lock.  Currently locked by 148.53.163.85 (148.53.163.85) since 12/18/18 6:02 PM
  at liquibase.lockservice.StandardLockService.waitForLock(StandardLockService.java:190)
  at liquibase.Liquibase.update(Liquibase.java:196)
  at liquibase.Liquibase.update(Liquibase.java:192)
  at liquibase.integration.spring.SpringLiquibase.performUpdate(SpringLiquibase.java:431)
  at liquibase.integration.spring.SpringLiquibase.afterPropertiesSet(SpringLiquibase.java:388)
  at com.luciad.internal.fusion.platform.studio.service.installers.LiquibaseInstaller.install(LiquibaseInstaller.java:70)
  at com.luciad.internal.fusion.platform.studio.service.configuration.InstallerConfiguration.runInstaller(InstallerConfiguration.java:53)
  ... 27 common frames omitted

To resolve this issue, you can release the lock manually by clearing the table fusion_studio_liquibase.databasechangeloglock in your database.