# Moving a Java application to Upsun Fixed


p:last-child]:mb-0 [&>h3]:mt-0 rounded-lg" >

### Note
You can now use composable image to install runtimes and tools in your application container. To find out more, see the [Composable image](https://fixed.docs.upsun.com/create-apps/app-reference/composable-image.md) topic.

It is common to have a Java application that you want to migrate to Upsun Fixed.
Upsun Fixed supports several styles of Java application, such as monolith, microservices, stateful, and stateless.

## Minimum Requirement

To run a Java application at Upsun Fixed you need:

* [A supported Java version](https://fixed.docs.upsun.com/languages/java.md#supported-versions)
* [A build management tool](https://fixed.docs.upsun.com/languages/java.md#support-build-automation)
  * [Gradle](https://docs.gradle.org/current/userguide/gradle_wrapper.md)
  * [Maven](https://maven.apache.org/)
  * [Maven Wrapper](https://www.baeldung.com/maven-wrapper)
  * [Ant](https://ant.apache.org/)
* A Git Repository:
  * [GitHub](https://fixed.docs.upsun.com/integrations/source/github.md)
  * [BitBucket](https://fixed.docs.upsun.com/integrations/source/bitbucket.md)
  * [GitLab](https://fixed.docs.upsun.com/integrations/source/gitlab.md)
  * The default Git repository provided by Upsun Fixed

**Note**: 

A container application can’t be bigger than **8 GB** of memory.
For more details, see [tuning](https://fixed.docs.upsun.com/languages/java/tuning.md).

## Monolith/Single Application

To start a Java application, you need to understand the [Upsun Fixed structure](https://fixed.docs.upsun.com/learn/overview/structure.md).
You will need to configure your [application](https://fixed.docs.upsun.com/create-apps/_index.md), [routes](https://fixed.docs.upsun.com/define-routes.md),
and [services](https://fixed.docs.upsun.com/add-services.md).

### Application

```yaml  {location=".platform.app.yaml"}
name: myapp
type: 'java:<VERSION>' [1]
disk: 1024
hooks:
  build: [2]
web:
  commands:
    start: [3]
```
1. [A supported Java version](https://fixed.docs.upsun.com/languages/java.md#supported-versions). Example: `java:21`
2. [Hooks](https://fixed.docs.upsun.com/create-apps/hooks.md) define what occurs when building the application. This build process typically generates an executable file such as an uber-jar. Example: `mvn clean package`
3. The [`<APP_NAME>.web.commands`](https://fixed.docs.upsun.com/create-apps/image-properties/web.md) property defines the command to launch the application(/create-apps/image-properties/web.md). Example:  `java -jar file.jar`
4. The [`<APP_NAME>.web.commands.start`](https://fixed.docs.upsun.com/create-apps/image-properties/web.md#start) property indicates the port on which the application runs through the `PORT` environment. Consider including this when your app follows the port bind principle. Example: `java -jar jar --port=$PORT`

**Note**: 

Be aware that after the build, it creates a read-only system. Use the [mount](https://fixed.docs.upsun.com/create-apps/image-properties/mounts.md).

### Route

```yaml  {location=".platform/routes.yaml"}
"https://{default}/":
  type: upstream
  upstream: "myapp:http" [1]
"https://www.{default}/":
  type: redirect
  to: "https://{default}/"
```
1. It defines the application will link in the route, e.g.: `"myapp:http"`

**Note**: 

Application instances have a limited amount of memory at build time, which has a maximum of 8 GB.
At runtime that limit depends on your plan and configuration.
A stateless application can be scaled horizontally to multiple application instances using Varnish in a [load balancer](https://support.platform.sh/hc/en-us/community/posts/16439676899474) configuration.

## Microservices

You have the option to use several languages in microservices. If you're using Java there are several options to aggregate these services into a microservices:

* [Maven Modules](https://maven.apache.org/guides/mini/guide-multiple-modules.md)
* [Gradle Multi-project](https://guides.gradle.org/creating-multi-project-builds/)
* [Git submodules](https://fixed.docs.upsun.com/development/submodules.md)

[Upsun Fixed supports multiple applications](https://fixed.docs.upsun.com/create-apps/multi-app.md) and there are two options:

* One application YAML file to each application
* Aggregate all applications in a single file with an `.platform/applications.yaml` file

| Article                                                      | Content                                                      |
| ------------------------------------------------------------ | ------------------------------------------------------------ |
| [Microservices in the cloud, part two](https://devcenter.upsun.com/posts/microservices-in-the-cloud-part-two/) | [Source](https://github.com/EventosJEspanol/latin-america-micro-profile) |
| [Microservices in the cloud, part one](https://upsun.com/blog/) | [Source](https://github.com/EventosJEspanol/latin-america-micro-profile) |
| [Multiple Applications](https://support.platform.sh/hc/en-us/community/posts/16439649733010) | [Source](https://github.com/platformsh-examples/tomcat-multi-app) |
| [Configure multi-applications with `.platform/applications.yaml`](https://support.platform.sh/hc/en-us/community/posts/16439676928274) | [Source](https://github.com/platformsh-examples/tomcat-multi-app-applications) |

**Note**: 

You can load balance to some or [all applications in the project cluster](https://support.platform.sh/hc/en-us/community/posts/16439662235026).

## Access to managed services

Upsun Fixed provides [managed services](https://fixed.docs.upsun.com/add-services.md) such as databases, cache and search engines.
However, you can use an external database or other services during a transition process. To maintain security, you must ensure that your external service (e.g., your external database or a third-party API) is configured to accept connections from Upsun’s outbound IP addresses.

When applications need to access a _managed_ service, it is important to include the [`relationships` key](https://fixed.docs.upsun.com/create-apps/image-properties/relationships.md).
By default an application may not talk to any other container without a `relationship` explicitly allowing access.

To connect to a service from your deployed application, you need to pass the relationships information into your application's configuration.
The way to do so varies with the application.
The most common mechanisms for connecting a managed service are listed below.

### Overwrite

If you are using a framework that follows the [Twelve-Factor App](https://12factor.net/) methodology, particularly the [third point](https://12factor.net/config), you can configure the application directly from environment variables.
Examples of such frameworks include Spring, Eclipse MicroProfile Config, Quarkus, and Micronauts.

Service credentials are available within the [**PLATFORM_RELATIONSHIPS** environment variable](https://fixed.docs.upsun.com/development/variables/use-variables.md#use-provided-variables).
This variable is a base64-encoded JSON object with keys of the relationship name and values of arrays of relationship endpoint definitions.

Upsun Fixed supports the [`jq` tool](https://stedolan.github.io/jq/), which allows to extract information from this JSON.

```bash  {location=".environment"}
export DB_HOST="$(echo "$PLATFORM_RELATIONSHIPS" | base64 --decode | jq -r '.postgresql[0].host')"
```

| Article                                                      | Source                                                       |
| ------------------------------------------------------------ | ------------------------------------------------------------ |
| [Spring Data MongoDB](https://support.platform.sh/hc/en-us/community/posts/16439654854802) | [Source](https://github.com/platformsh-examples/java-overwrite-configuration/tree/master/spring-mongodb) |
| [Jakarta EE/MicroProfile Config](https://support.platform.sh/hc/en-us/community/posts/16439700735122) | [Source](https://github.com/platformsh-examples/java-overwrite-configuration/tree/master/jakarta-nosql) |
| [Spring Data JPA](https://support.platform.sh/hc/en-us/community/posts/16439669562130) | [Source](https://github.com/platformsh-examples/java-overwrite-configuration/tree/master/spring-jpa) |
| [Payara JPA](https://support.platform.sh/hc/en-us/community/posts/16439658290194) | [Source](https://github.com/platformsh-examples/java-overwrite-configuration/blob/master/payara/README.md) |

To reduce the number of lines in the application file and to make it cleaner,
you have the option to move the variable environment to another file: a [`.environment` file](https://fixed.docs.upsun.com/development/variables/set-variables.md#set-variables-via-script).

E.g.:

```bash  {location=".environment"}
export DB_HOST="$(echo "$PLATFORM_RELATIONSHIPS" | base64 --decode | jq -r '.postgresql[0].host')"
export DB_PASSWORD="$(echo "$PLATFORM_RELATIONSHIPS" | base64 --decode | jq -r '.postgresql[0].password')"
export DB_USER="$(echo "$PLATFORM_RELATIONSHIPS" | base64 --decode | jq -r '.postgresql[0].username')"
export DB_DATABASE="$(echo "$PLATFORM_RELATIONSHIPS" | base64 --decode | jq -r '.postgresql[0].path')"
export JDBC="jdbc:postgresql://${HOST}/${DATABASE}"
export JAVA_MEMORY="-Xmx$(jq .info.limits.memory /run/config.json)m"
export JAVA_OPTS="$JAVA_MEMORY -XX:+ExitOnOutOfMemoryError"
```

This `.environment` can interact to each application file. E.g.:

```yaml  {location=".platform.app.yaml"}
name: myapp
type: "java:11"
disk: 1024
hooks:
  build: ./mvnw package -DskipTests -Dquarkus.package.uber-jar=true
relationships:
  postgresql:
web:
  commands:
    start: java -jar $JAVA_OPTS $CREDENTIAL -Dquarkus.http.port=$PORT jarfile.jar
```
### Using Java Config Reader

If your framework doesn't support configuration via environment variables, use the [Config Reader](https://fixed.docs.upsun.com/development/variables/use-variables.md#access-variables-in-your-app).
This library provides a streamlined way to interact with an Upsun Fixed environment. It offers utility methods to access routes and relationships more cleanly than reading the raw environment variables yourself. [See the maven dependency](https://mvnrepository.com/artifact/sh.platform/config).

```java
import Config;

Config config = new Config();
MySQL database = config.getCredential("postgresql", MySQL::new);
DataSource dataSource = database.get();
```


