<dependencies>
<dependency>
<groupId>org.faktorips.productdesigner</groupId>
<artifactId>productdesigner-web</artifactId>
<version>24.7.0</version>
</dependency>
</dependencies>
English Documentation
Setup
Setting up the Faktor-IPS Product Designer with custom product projects
The following describes the process for manually setting up the Product Designer as a local Spring Boot application with custom product projects, as well as subsequent deployment via Docker.
Updating Faktor-IPS Dependencies:
The Product Designer requires the latest Faktor-IPS version (currently 24.7) and Java 21. In the first step, the Faktor-IPS dependencies must be updated, and the current Faktor-IPS version must be installed in a suitable Eclipse via the update site. Subsequently, the model projects need to be rebuilt once. For more information on compatibilities between Faktor-IPS and Eclipse, please refer to this overview.
Creating a Maven project:
Next, a new Maven project is created with dependencies for the Product Designer, model projects, and Spring Boot starter.
Please note: In addition to the manual setup described below, there is also the option to generate a Maven Product Designer project using an archetype. More information on this can be found in the chapter 'Product Designer Archetype'.
Dependencies:
Productdesigner-Web:
Add required model dependencies – for example:
<dependencies>
<dependency>
<groupId>de.faktorzehn.muster.shu-gewerbe</groupId>
<artifactId>vm-gewerbe-gruppenunfall-produktmodellerw</artifactId>
<version>24.7.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>de.faktorzehn.muster.shu-gewerbe</groupId>
<artifactId>vm-gewerbe-basis-produkte</artifactId>
<version>24.7.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-validation</artifactId>
</dependency>
</dependencies>
In the Spring Boot plugin configuration, the Product Designer application created in the following step is registered:
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<wait>500</wait>
<maxAttempts>240</maxAttempts>
<!-- Insert the Product Designer Application here (see below) -->
<mainClass>org.faktorips.productdesigner.demo.SampleProductDesignerApplication</mainClass>
<layout>JAR</layout>
</configuration>
<executions>
<execution>
<goals>
<goal>repackage</goal>
</goals>
</execution>
</executions>
</plugin>
Below is an example pom.xml
of a Product Designer Maven project:
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>de.faktorzehn.commons</groupId>
<artifactId>f10-suite-starter-spring</artifactId>
<version>24.7.0</version>
</parent>
<groupId>org.faktorips.productdesigner</groupId>
<artifactId>demo</artifactId>
<version>0.0.1-SNAPSHOT</version>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<java.version>21</java.version>
<maven.compiler.release>${java.version}</maven.compiler.release>
<maven.compiler.source>${java.version}</maven.compiler.source>
<maven.compiler.target>${java.version}</maven.compiler.target>
<faktorips.version>24.7.0</faktorips.version>
</properties>
<dependencies>
<dependency>
<groupId>org.faktorips.productdesigner</groupId>
<artifactId>productdesigner-web</artifactId>
<version>24.7.0</version>
</dependency>
<!-- INSERT the model dependencies here -->
<dependency>
<groupId>de.faktorzehn.muster.shu-gewerbe</groupId>
<artifactId>vm-gewerbe-gruppenunfall-produktmodellerw</artifactId>
<version>24.7.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>de.faktorzehn.muster.shu-gewerbe</groupId>
<artifactId>vm-gewerbe-basis-produkte</artifactId>
<version>24.7.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-validation</artifactId>
</dependency>
</dependencies>
<build>
<defaultGoal>spring-boot:run</defaultGoal>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>${java.version}</source>
<target>${java.version}</target>
<showWarnings>true</showWarnings>
<showDeprecation>true</showDeprecation>
</configuration>
</plugin>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<wait>500</wait>
<maxAttempts>240</maxAttempts>
<!-- Insert the Product Designer Application here -->
<mainClass>org.faktorips.productdesigner.demo.SampleProductDesignerApplication</mainClass>
<layout>JAR</layout>
</configuration>
<executions>
<execution>
<goals>
<goal>repackage</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>com.vaadin</groupId>
<artifactId>vaadin-maven-plugin</artifactId>
<executions>
<execution>
<goals>
<goal>prepare-frontend</goal>
</goals>
<phase>compile</phase>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
Creating a Spring Boot Application Class
Next, create an application class, which will be registered in the pom.xml
under the configuration of the spring-boot-maven-plugin.
Example: SampleProductDesignerApplication.java
:
import com.vaadin.flow.component.page.AppShellConfigurator;
import com.vaadin.flow.server.AppShellSettings;
import com.vaadin.flow.spring.annotation.EnableVaadin
import com.vaadin.flow.theme.Theme;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.faktorips.productdesigner.core.ProductDesigner;
import org.faktorips.productdesigner.core.ProductDesignerConfigurationProperties;
@Theme(value = "productdesigner", variant = "card-section-pages")
@SpringBootApplication(scanBasePackages = ProductDesigner.BASE_PACKAGE)
@EnableConfigurationProperties(ProductDesignerConfigurationProperties.class)
@EnableVaadin(value = ProductDesigner.BASE_PACKAGE)
public class SampleProductDesignerApplication implements AppShellConfigurator {
private static final long serialVersionUID = 1L;
public static void main(String[] args) {
SpringApplication.run(SampleProductDesignerApplication.class, args);
}
@Override
public void configurePage(AppShellSettings settings) {
settings.addFavIcon("icon", "../favicon.ico", "48x48");
}
}
Creating the Configuration and Including Additional Repositories
Now, under src/main/resources/, create an application.yml:
logging:
level:
org.springframework: WARN
server:
port: 8080
vaadin:
urlMapping: '/ui/*'
launch-browser: true
ips-product-designer:
ips-project-path: ../../../git/mustercontent/vm/vm.shu.gewerbe/gruppenunfall/produkte/
additional-repos:
- de.faktorzehn.versicherungsmodell.gw.produkte.GwProduktClassloaderRuntimeRepository
- de.faktorzehn.versicherungsmodell.gw.produkte.GwAllgemeinClassloaderRuntimeRepository
read-only-mode: false
In the additional-repos section, repositories on which the product project depends are included by their class references.
To ensure they are correctly loaded at runtime, each repository should have a class with an INSTANCE field for an IRuntimeRepository
or IRuntimeRepositoryLookup
.
For example, the class GwProduktClassloaderRuntimeRepository
referenced in the .yml for providing and configuring the singleton repository looks like this:
import org.faktorips.runtime.ClassloaderRuntimeRepository;
import org.faktorips.runtime.formula.groovy.GroovyFormulaEvaluatorFactory;
public class GwProduktClassloaderRuntimeRepository {
public static final ClassloaderRuntimeRepository INSTANCE = ClassloaderRuntimeRepository
.create("de/faktorzehn/versicherungsmodell/gw/produkte/internal/faktorips-repository-toc.xml");
static {
INSTANCE.addDirectlyReferencedRepository(GwAllgemeinClassloaderRuntimeRepository.INSTANCE);
INSTANCE.setFormulaEvaluatorFactory(new GroovyFormulaEvaluatorFactory());
}
private GwProduktClassloaderRuntimeRepository() {
// Soll nicht instanziiert werden
}
}
First, a ClassloaderRuntimeRepository
INSTANCE is initialized based on the associated toc.xml
.
In the static initialization block, necessary referenced repositories are then incorporated via their respective instances (INSTANCE.addDirectlyReferencedRepository(GwAllgemeinClassloaderRuntimeRepository.INSTANCE)
), and additionally, configurations for the repository instance are defined (INSTANCE.setFormulaEvaluatorFactory(new GroovyFormulaEvaluatorFactory());
).
Adding a Favicon
Finally, to display application icons in the browser tab, a favicon can optionally be placed in src/main/resources/static
.
Docker Deployment
When providing and deploying the application in Docker containers, it should be noted that the application is deployed as a .jar file, but the product data is unpacked and copied into the container. For this, the vaadin.productionMode
must first be set to true
in the pom.xml
.
<profiles>
<profile>
<id>production</id>
<properties>
<vaadin.productionMode>true</vaadin.productionMode>
</properties>
<build>
<plugins>
<plugin>
<groupId>com.vaadin</groupId>
<artifactId>vaadin-maven-plugin</artifactId>
<version>${vaadin.version}</version>
<executions>
<execution>
<goals>
<goal>prepare-frontend</goal>
<goal>build-frontend</goal>
</goals>
<phase>compile</phase>
</execution>
</executions>
</plugin>
</plugins>
</build>
</profile>
</profiles>
Dockerfile
example:
FROM eclipse-temurin:21-jre-jammy
RUN apt-get update \
&& ln -sf /usr/share/zoneinfo/Europe/Berlin /etc/localtime \
&& dpkg-reconfigure -f noninteractive tzdata
ARG UID=999
ARG GID=999
ENV JAVA_TOOL_OPTIONS "-Xms480m -Xmx1024m"
RUN groupadd --gid $GID spring \
&& useradd -r -m -d /opt/spring -s /sbin/nologin --gid $GID --uid $UID -c "Spring user" spring \
&& chmod 755 /opt/spring \
&& mkdir -p /var/opt/spring \
&& chown spring: /var/opt/spring \
&& chmod 755 /var/opt/spring
WORKDIR /opt/spring
COPY ${PATH_TO_APPLICATION_JAR} application.jar
COPY ${PATH_TO_PRODUCT_FOLDER} /var/opt/spring/produkte
RUN chown -R spring: /var/opt/spring
USER $UID
EXPOSE 8080
CMD ["java", \
"-Dspring.profiles.active=production", \
"-jar", \
"application.jar", \
"--server.port=8080", \
"--server.forward-headers-strategy=FRAMEWORK"]
docker-compose.yml
example:
version: '2.4'
services:
productdesigner-sample:
container_name: ${CONTAINER_NAME}-sample
build:
context: ../
dockerfile: ./path/to/Dockerfile
args:
- PATH_TO_APPLICATION_JAR=${PATH_TO_APPLICATION_JAR}
- PATH_TO_PRODUCT_FOLDER=${PATH_TO_PRODUCT_FOLDER}
environment:
SPRING_PROFILES_ACTIVE: production
ips-product-designer.ips-project-path: /var/opt/spring/produkte
labels:
url: ${CONTAINER_NAME}-sample
entry-path: ui
networks:
default:
name: network-${CONTAINER_NAME}
labels:
retention: ${CONTAINER_RETENTION}