> ## Documentation Index
> Fetch the complete documentation index at: https://developer.upsun.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Java: Hello, World! at Platform.sh

> Discover how to deploy Java applications on Platform.sh. Learn about Spring Boot, MySQL integration, and continuous deployment for Java apps.

export const PostMeta = ({data = {}}) => {
  const {author, date} = data;
  const authors = Array.isArray(author) ? author : author ? [author] : [];
  const resolveAuthor = slug => {
    const entry = AUTHOR_MAP[slug] || ({});
    const name = entry.name || slug;
    const github = entry.github || null;
    const linkedin = entry.linkedin || null;
    const url = github ? `https://github.com/${github}` : linkedin || null;
    const avatarUrl = github ? `https://github.com/${github}.png?size=64` : null;
    return {
      name,
      url,
      avatarUrl
    };
  };
  const formattedDate = date ? new Date(date).toLocaleDateString('en-US', {
    year: 'numeric',
    month: 'long',
    day: 'numeric'
  }) : null;
  if (authors.length === 0 && !formattedDate) return null;
  const AUTHOR_MAP = {
    "aaron-collier": {
      "name": "Aaron Collier"
    },
    "aaron-dudenhofer": {
      "name": "Aaron Dudenhofer"
    },
    "aaron-porter": {
      "name": "Aaron Porter"
    },
    "adriaan-odendaal": {
      "name": "Adriaan Odendaal"
    },
    "ajmal": {
      "name": "Ajmal Siddiqui"
    },
    "akalipetis": {
      "name": "Antonis Kalipetis"
    },
    "alexander-varwijk": {
      "name": "Alexander Varwijk"
    },
    "alicia-bevilacqua": {
      "name": "Alicia Bevilacqua"
    },
    "amelie-deguerry": {
      "name": "Amelie Deguerry"
    },
    "anacidre": {
      "name": "Ana Cidre",
      "linkedin": "https://www.linkedin.com/in/ana-cidre"
    },
    "andoni": {
      "name": "Andoni Auzmendi"
    },
    "andrei-taranu": {
      "name": "Andrei (Alex) Taranu",
      "linkedin": "https://www.linkedin.com/in/andrei-alex-taranu/"
    },
    "andrew-baxter": {
      "name": "Andrew Baxter"
    },
    "andrew-melck": {
      "name": "Andrew Melck"
    },
    "antoine-crochet-damais": {
      "name": "Antoine Crochet Damais"
    },
    "augustin-delaporte": {
      "name": "Augustin Delaporte",
      "linkedin": "https://www.linkedin.com/in/augustindelaporte/"
    },
    "branislav-bujisic": {
      "name": "Branislav Bujisic"
    },
    "carl-smith": {
      "name": "Carl Smith"
    },
    "caroline-leroy": {
      "name": "Caroline Leroy"
    },
    "cati-mayer": {
      "name": "Cati Mayer"
    },
    "catplat": {
      "name": "C Trinkwon"
    },
    "ceelolulu": {
      "name": "Celeste van der Watt"
    },
    "chadwcarlson": {
      "name": "Chad Carlson",
      "github": "chadwcarlson",
      "linkedin": "https://www.linkedin.com/in/chadwcarlson"
    },
    "chris-ward": {
      "name": "Chris Ward"
    },
    "chris-yates": {
      "name": "Chris Yates"
    },
    "christian-sieber": {
      "name": "Christian Sieber"
    },
    "christopher-lockheardt": {
      "name": "Christopher Lockheardt"
    },
    "christopher-skene": {
      "name": "Christopher Skene"
    },
    "chuck-morgan": {
      "name": "Chuck Morgan"
    },
    "corey-dockendorf": {
      "name": "Corey Dockendorf"
    },
    "crell": {
      "name": "Crell"
    },
    "damz": {
      "name": "Damz"
    },
    "dan-morrison": {
      "name": "Dan Morrison"
    },
    "davidbonachera": {
      "name": "David Bonachera",
      "github": "davidbonachera",
      "linkedin": "https://www.linkedin.com/in/davidbonachera"
    },
    "dereliahmet1": {
      "name": "Ahmet Faruk Dereli"
    },
    "devicezero": {
      "name": "Jonas Kröger",
      "github": "devicezero",
      "linkedin": "https://www.linkedin.com/in/jonaskroeger/"
    },
    "doug-goldberg": {
      "name": "Doug Goldberg"
    },
    "duncan-naves": {
      "name": "Duncan Naves",
      "github": "duncannaves",
      "linkedin": "https://www.linkedin.com/in/duncan-naves-a94423aa"
    },
    "erika-bustamante": {
      "name": "Erika Bustamante"
    },
    "fabpot": {
      "name": "Fabien Potencier"
    },
    "flovntp": {
      "name": "Florent Huck",
      "github": "flovntp",
      "linkedin": "https://www.linkedin.com/in/florenthuck"
    },
    "fred-plais": {
      "name": "Fred Plais"
    },
    "gauthier-garnier": {
      "name": "Gauthier Garnier"
    },
    "gilzow": {
      "name": "Paul Gilzow"
    },
    "gmoigneu": {
      "name": "Guillaume Moigneu",
      "github": "gmoigneu",
      "linkedin": "https://www.linkedin.com/in/guillaumemoigneu/"
    },
    "gregqualls": {
      "name": "Greg Qualls"
    },
    "guguss": {
      "name": "Augustin Delaporte"
    },
    "haylee-millar": {
      "name": "Haylee Millar"
    },
    "ivana-kotur": {
      "name": "Ivana Kotur"
    },
    "jackrabbithanna": {
      "name": "Mark Hanna"
    },
    "jared-wright": {
      "name": "Jared Wright",
      "github": "jww-sh",
      "linkedin": "https://www.linkedin.com/in/jaredwaynewright"
    },
    "jessica-orozco": {
      "name": "Jessica Orozco"
    },
    "joey-stanford": {
      "name": "Joey Stanford"
    },
    "john-grubb": {
      "name": "John Grubb"
    },
    "jonas-kruger": {
      "name": "Jonas Kruger"
    },
    "kathryn-frazer": {
      "name": "Kathryn Frazer"
    },
    "kemiojo": {
      "name": "Kemi Elizabeth Ojogbede"
    },
    "kieronsambrook-smith": {
      "name": "Kieronsambrook Smith"
    },
    "laurent-arnoud": {
      "name": "Laurent Arnoud",
      "linkedin": "https://www.linkedin.com/in/laurent-arnoud-861b44121/"
    },
    "letoya-boyne": {
      "name": "Letoya Boyne"
    },
    "lolautruche": {
      "name": "Jérôme Vieilledent"
    },
    "lyly-lepinay": {
      "name": "Lyly Lepinay"
    },
    "manauwar-alam": {
      "name": "Manauwar Alam"
    },
    "marc-antoine-porri": {
      "name": "Marc Antoine Porri"
    },
    "maria-antinkaapo": {
      "name": "Maria Antinkaapo"
    },
    "maria-de-anton": {
      "name": "Maria De Anton"
    },
    "mark-dorison": {
      "name": "Mark Dorison"
    },
    "markus-hausammann": {
      "name": "Markus Hausammann"
    },
    "mary-thomas": {
      "name": "Mary Thomas"
    },
    "mathias-bolt-lesniak": {
      "name": "Mathias Bolt Lesniak"
    },
    "mathieu-strauch": {
      "name": "Mathieu Strauch"
    },
    "matthias-van-woensel": {
      "name": "Matthias Van Woensel",
      "linkedin": "https://www.linkedin.com/in/matthias-van-woensel-267a069"
    },
    "maz-mohammadi": {
      "name": "Maz Mohammadi"
    },
    "michael-sharp": {
      "name": "Michael Sharp"
    },
    "mupsi": {
      "name": "Marine Gandy"
    },
    "natalie-harper": {
      "name": "Natalie Harper"
    },
    "ngommenginger": {
      "name": "Nicolas Gommenginger",
      "linkedin": "https://www.linkedin.com/in/nicolas-gommenginger"
    },
    "nicholas-bennison": {
      "name": "Nicholas Bennison"
    },
    "nicholas-vahalik": {
      "name": "Nicholas Vahalik"
    },
    "nick-hardiman": {
      "name": "Nick Hardiman"
    },
    "nickanderegg": {
      "name": "Nickanderegg"
    },
    "nicolas-grekas": {
      "name": "Nicolas Grekas",
      "github": "nicolas-grekas",
      "linkedin": "https://www.linkedin.com/in/nicolasgrekas/"
    },
    "niti-malwade": {
      "name": "Niti Malwade"
    },
    "opensocialteam": {
      "name": "Opensocialteam"
    },
    "ori-pekelman": {
      "name": "Ori Pekelman"
    },
    "otavio-santana": {
      "name": "Otavio Santana"
    },
    "palwandi": {
      "name": "Pawan Alwandi",
      "github": "pawpy",
      "linkedin": "https://www.linkedin.com/in/pawanalwandi"
    },
    "patrick-boest": {
      "name": "Patrick Boest"
    },
    "patrick-dawkins": {
      "name": "Patrick Dawkins",
      "github": "pjcdawkins",
      "linkedin": "https://www.linkedin.com/in/patrickdawkins"
    },
    "patrick-klima": {
      "name": "Patrick Klima"
    },
    "pjcdawkins": {
      "name": "Pjcdawkins"
    },
    "prineet-kaurbhurji": {
      "name": "Prineet Kaurbhurji"
    },
    "quentin-sinig": {
      "name": "Quentin Sinig"
    },
    "ralt": {
      "name": "Florian Margaine",
      "github": "ralt",
      "linkedin": "https://www.linkedin.com/in/florian-margaine-43971136"
    },
    "ramanathanramakrishnamurthy": {
      "name": "Ramanathanramakrishnamurthy"
    },
    "remi-lejeune": {
      "name": "Rémi Lejeune"
    },
    "ribel": {
      "name": "Taras Kruts"
    },
    "robert-douglass": {
      "name": "Robert Douglass"
    },
    "rudy-weber": {
      "name": "Rudy Weber"
    },
    "ryan-hicks": {
      "name": "Ryan Hicks"
    },
    "sabri-helal": {
      "name": "Sabri Helal"
    },
    "savannah-bergeron": {
      "name": "Savannah Bergeron"
    },
    "shannon-vettes": {
      "name": "Shannon Vettes"
    },
    "shawn-ogasawara": {
      "name": "Shawn Ogasawara",
      "linkedin": "https://www.linkedin.com/in/shawn-ogasawara-83a9a0/"
    },
    "shawna-spoor": {
      "name": "Shawna Spoor"
    },
    "shedrack-akintayo": {
      "name": "Shedrack Akintayo"
    },
    "simon-ruggier": {
      "name": "Simon Ruggier"
    },
    "sophie-van-der-kindere": {
      "name": "Sophie Van Der Kindere"
    },
    "stefanos-thampis": {
      "name": "Stefanos Thampis"
    },
    "stephen-weinberg": {
      "name": "Stephen Weinberg"
    },
    "sukhman-virk": {
      "name": "Sukhman Virk"
    },
    "sumaira-nazir": {
      "name": "Sumaira Nazir"
    },
    "sumer": {
      "name": "Sümer Cip"
    },
    "syed-raza": {
      "name": "Syed Raza"
    },
    "tamara-bacchia": {
      "name": "Tamara Bacchia"
    },
    "tara-arnold": {
      "name": "Tara Arnold"
    },
    "theosakamg": {
      "name": "Mickael Gaillard",
      "github": "theosakamg"
    },
    "thomasdiluccio": {
      "name": "Thomas di Luccio"
    },
    "tim-anderson": {
      "name": "Tim Anderson"
    },
    "tom-helmer-hansen": {
      "name": "Tom Helmer Hansen"
    },
    "tylermills": {
      "name": "Tyler Mills"
    },
    "upsun": {
      "name": "Upsun"
    },
    "veronika-tolkachova": {
      "name": "Veronika Tolkachova",
      "linkedin": "https://www.linkedin.com/in/veronika-tolkachova-169167a2"
    },
    "vince-parker": {
      "name": "Vince Parker"
    },
    "vinnie-russo": {
      "name": "Vincenzo Russo"
    },
    "vrobert78": {
      "name": "Vincent Robert",
      "github": "vrobert78",
      "linkedin": "https://www.linkedin.com/in/vincent-robert-498a883"
    },
    "yuriy-babenko": {
      "name": "Yuriy Babenko"
    },
    "yuriy-gerasimov": {
      "name": "Yuriy Gerasimov"
    }
  };
  return <div className="post-meta">
      {(authors.length > 0 || formattedDate) && <div className="post-meta-info">
          {authors.length > 0 && <div className="post-meta-authors">
              {authors.map(slug => {
    const {name, url, avatarUrl} = resolveAuthor(slug);
    const inner = <>
                    {avatarUrl && <img src={avatarUrl} alt={name} className="post-meta-avatar" />}
                    <span className="post-meta-author-name">{name}</span>
                  </>;
    return url ? <a key={slug} href={url} target="_blank" rel="noopener noreferrer" className="post-meta-author">
                    {inner}
                  </a> : <span key={slug} className="post-meta-author">{inner}</span>;
  })}
            </div>}
          {authors.length > 0 && formattedDate && <span className="post-meta-separator" aria-hidden="true">·</span>}
          {formattedDate && <span className="post-meta-date">{formattedDate}</span>}
        </div>}
    </div>;
};

<PostMeta data={{ author: ["otavio-santana"], date: "2019-06-06", image: "/images/posts/unknown/java-hello-world-at-platform.sh/java-hello-world-at-platform.sh.webp" }} />

<Tip>
  This post was originally published on the Platform.sh blog and reflects information from the time of publication.
</Tip>

Today, Platform.sh is announcing support for Java technologies. And in this post, we'll cover how easy it is to either create or move your Java application to Platform.sh.

A quick refresher: a second-generation Platform-as-a-Service, Platform.sh is built especially for continuous deployment. With Platform.sh, you can host web applications in the cloud while making your development and testing workflows more productive. As the premier tool for developing and delivering applications in Drupal, WordPress, Symfony, Typo3, EZ, and Magento, Platform.sh also supports an array of languages, including PHP, Node.js, Python, Ruby, and Go.

Now, back to Java! We’ll show a Spring-Boot application connected to a MySQL database instance using Maven to automate the build and install. In the Java world, Spring Boot makes it easy to create stand-alone, production-grade, Spring-based applications that you can just run.

## Show me the code

Platform.sh supports common Java tools, and so we’ll use the [Spring Initializr](https://start.spring.io/) to create a Spring Maven Project with Java 8, and append the MySQL driver as a dependency. There’s also a [Platform.sh configuration library](https://github.com/platformsh/config-reader-java) that reads Platform.sh-specific details, like routes and environmental variables, and exposes them to the application. Here’s the pom.xml file:

```xml theme={null}
<?xml version="1.0" encoding="UTF-8"?>
<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>

	<groupId>com.mycompany</groupId>
	<artifactId>template-spring-boot-maven-mysql</artifactId>
	<version>0.0.1</version>

	<properties>
    	<java.version>1.8</java.version>
	</properties>

	<parent>
    	<groupId>org.springframework.boot</groupId>
    	<artifactId>spring-boot-starter-parent</artifactId>
    	<version>2.1.5.RELEASE</version>
	</parent>

	<dependencies>
    	<dependency>
        	<groupId>org.springframework.boot</groupId>
        	<artifactId>spring-boot-starter-web</artifactId>
    	</dependency>
    	<dependency>
        	<groupId>org.springframework.boot</groupId>
        	<artifactId>spring-boot-starter-data-jpa</artifactId>
    	</dependency>
    	<dependency>
        	<groupId>mysql</groupId>
        	<artifactId>mysql-connector-java</artifactId>
    	</dependency>
    	<dependency>
        	<groupId>sh.platform</groupId>
        	<artifactId>config</artifactId>
        	<version>2.2.0</version>
    	</dependency>
	</dependencies>

	<build>
    	<finalName>spring-boot-maven-mysql</finalName>
    	<plugins>
        	<plugin>
            	<groupId>org.springframework.boot</groupId>
            	<artifactId>spring-boot-maven-plugin</artifactId>
        	</plugin>
    	</plugins>
	</build>

	<repositories>
    	<repository>
        	<id>oss.sonatype.org-snapshot</id>
        	<url>http://oss.sonatype.org/content/repositories/snapshots</url>
    	</repository>
	</repositories>
</project>
```

[Spring Data JPA](https://spring.io/projects/spring-data-jpa), part of the larger Spring Data family, makes it easy to quickly implement JPA-based repositories. This module deals with enhanced support for JPA-based data access layers, making it easier to build Spring-powered applications that use data access technologies. In this example, you store Person objects annotated as a JPA entity.

```java theme={null}

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import java.util.Objects;

@Entity
public class Person {

	@Id
	@GeneratedValue(strategy = GenerationType.IDENTITY)
	private Long id;

	@Column
	private String name;

	@Column
	private Integer age;

 //getter and setter
}
```

Spring Data JPA focuses on using JPA to store data in a relational database. Its most compelling feature is the ability to create repository implementations automatically, at runtime, from a repository interface.

```java theme={null}
import org.springframework.data.repository.PagingAndSortingRepository;

public interface PersonRepository extends PagingAndSortingRepository<Person, Long> {
}

```

After creating the model and the repository, the last step in the Java application is the controller with a REST. The `@RequestMapping` annotation provides “routing” information. It tells Spring that any HTTP request with the / path should be mapped to the home method. The `@RestController` annotation tells Spring to render the resulting string directly back to the caller.

```java theme={null}
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseStatus;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RequestMapping("people")
public class PersonController {

	@Autowired
	private PersonRepository repository;

	@PostMapping
	@ResponseStatus(code = HttpStatus.CREATED)
	public String save(@RequestBody Person person) {
    	repository.save(person);
    	return "Saved- " + person.getName();
	}

	@GetMapping(value = "/{id}", produces = "application/json")
	public Person get(@PathVariable("id") long id) {
    	return repository.findById(id).orElseThrow(() -> new RuntimeException("Not found"));
	}

	@GetMapping(produces = "application/json")
	public Iterable<Person> get() {
    	return repository.findAll();
	}

	@PutMapping(value = "/{id}", produces = "application/json")
	public Person update(@PathVariable("id") long id, @RequestBody Person person) {
    	repository.save(person);
    	return person;
	}

	@DeleteMapping(value = "/{id}", produces = "application/json")
	public Person delete(@PathVariable("id") long id) {
    	Person person = repository.findById(id).orElseThrow(() -> new RuntimeException("Not found"));
    	repository.deleteById(id);
    	return person;
	}
}

```

```java theme={null}
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class App {
	public static void main(String[] args) {
    	SpringApplication.run(App.class, args);
	}

}
```

The final part of our application is a startup. It’s a standard method that follows the Java convention for an application entry point. SpringApplication bootstraps the app, starting Spring on a Tomcat web server.

## Platform.sh structure

The Java application is ready to go! The next step is to set the Platform.sh files required to manage and deploy the demo. Every <a href="https://upsun.com/blog/web-application-deployment-best-practices/">application you deploy</a> on Platform.sh is built as a virtual cluster, containing a set of containers. There are three types of containers within your cluster:

* One Router (.platform/routes.yaml). Platform.sh allows you to define the [routes](https://docs.platform.sh/configuration/routes.html).
* Zero or more service containers (.platform/services.yaml). Platform.sh allows you to completely define and configure the topology and services you want to use on your [project](https://docs.platform.sh/configuration/services.html).
* One or more application containers (.platform.app.yaml). You control your application and the way it will be built and deployed on Platform.sh [via a single configuration file](https://docs.platform.sh/configuration/app-containers.html).

The [services](https://docs.platform.sh/configuration/services.html) file allows you to define the services such as database, search engine, cache and so on; in this project demo, it will be a MySQL instance.

```yaml theme={null}
database:
  type: mysql:10.2
  disk: 1024
```

The routes file defines the environment’s routes; there are several options, such as cache and redirects, but we won't cover these in this post. For more information, [see the documentation](https://docs.platform.sh/configuration/routes.html).

```yaml theme={null}
https://{default}/:
  type: upstream
  upstream: "app:http"
```

The final configuration file, `.platform.app.yaml`, specifies a single application, and defines how to build and execute it. Here’s the structure:

* **name.** Sets the unique name of the application container.
* **type.** Sets the container base image to use, including application language. We're using Java version 8, but there are more Java versions that Platform.sh supports.
* **hooks.** Controls how the application gets compiled. This example uses a Maven command to compile, but there’s support for Gradle and Ant.
* **relationships.** Defines connections to other services, such as the MySQL database instance.
* **web.** Controls how the web application is served. As an uber-jar, the application will execute a Spring Jar file. Also, the application must use the port that’s provided from the container through a `$PORT` variable.

```yaml theme={null}
name: app
type: "java:8"

disk: 1024

hooks:
  build: mvn clean install

relationships:
  database: "database:mysql"
web:
  commands:
    start: java -jar target/spring-boot-maven-mysql.jar --server.port=$PORT
```

## Platform.sh and Java

For the database, we need to define where the connection comes from. Platform.sh provides connection credentials to services using the PLATFORM\_RELATIONSHIPS environmental variable.

```java theme={null}
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import sh.platform.config.Config;
import sh.platform.config.MySQL;

import javax.sql.DataSource;

@Configuration
public class DataSourceConfig {

	@Bean(name = "dataSource")
	public DataSource getDataSource() {
    	Config config = new Config();
    	MySQL database = config.getCredential("database", MySQL::new);
    	return database.get();
	}
}
```

The Java Config offers classes that will read the information from the variable and return an object that represents the services, like a DataSource for MySQL, PostgreSQL, MongoClient, Redis, or any other services you’ve defined in .platform/services.yaml!

The application is now ready, so it’s time to move it to the cloud with Platform.sh using the [following steps](https://docs.platform.sh/gettingstarted/first-project.html):

* Create a new [free trial account](https://auth.api.platform.sh/register?trial_type=general).
* Sign up with a new user and password, or login using a current GitHub, Bitbucket, or Google account. If you use a third-party login, you’ll be able to set a password for your Platform.sh account later.
* Select the region of the world where your site should live.
* Select the blank template.

After this wizard, Platform.sh will provision the whole infrastructure to you, and Platform.sh will offer a remote <a href="https://docs.platform.sh/development/private-repository.html">Git repository</a>. Before access, remember to set the SSH keys. The Platform.sh Git-driven infrastructure means it will automatically manage everything your application needs to push it to the master remote repository. You only need to write your code—including a few <a href="https://docs.platform.sh/overview/yaml/what-is-yaml.html">YAML files</a> that specify your desired infrastructure—then commit it to Git and push.

```sh theme={null}
git remote add platform <platform.sh@gitrepository>
git commit -m "Initial project"
git push -u platform master
```

Code pushed will create both the Java application, a MySQL instance, and, when it's done, will return an IP address to the service. Let's test the application. To test a REST application, any HTTP client is OK.

```sh theme={null}
curl -X POST -H "Content-Type: application/json"  -d '{"name": "Paulo", "age": 50}' https://<service.ip>/people
curl -X POST -H "Content-Type: application/json"  -d '{"name": "Otavio", "age": 30}' https://<service.ip>/people
curl -X POST -H "Content-Type: application/json"  -d '{"name": "Poliana", "age": 25}' https://<service.ip>/people
curl https://<service.ip>/people
#result output here
```

You’ve now seen how a native integration between Java and Platform.sh works, and the result code confirms it! As a Java developer, you can bring your application to the cloud quickly with Platform.sh once that application uses either Maven, Gradle, and Ant as build management.

There are templates for Java and other languages in our SaaS. We’re working to have even more facilities, templates models, and services to help grow the Java and Platform.sh community.
