Java Projects

To create a new Java project, use projen new java:

$ projen new java --group-id org.acme --artifact-id hello-maven

This will synthesize a standard Maven project directory structure with a pom.xml file and some sample code:

├── pom.xml
└── src
    ├── main/java/org/acme
    │   └──
    └── test/java/org/acme

At this point, you should be able to now simply run projen build to build your project:

$ projen build

Since this is a standard Maven project, so you can also use mvn package, mvn test, etc. IDEs should also feel at home with this project.

The projen new command will also generate a .projenrc.js file which includes the definition of your project with any options you specified in the command line:

const { java } = require('projen');

const project = new java.JavaProject({
  artifactId: 'hello-maven',
  groupId: 'org.acme',
  name: 'hello-maven',
  version: '0.1.0',


It is possible to create your projenrc file in java. In the future, this will be the default, but at the moment you need to add some configuration. See the section for details.

To modify your project definitions, edit .projenrc.js and run projen again to re-synthesize your project. The following sections describe the various features of Java projects.


You can set the project version through the version options:

const project = new java.MavenProject({
  version: '1.2.3'

Project Metadata

You can specify additional metadata for your project by passing options to the constructor of MavenProject. For example, let’s add a description and a URL for your project:

const project = new java.JavaProject({
  // ...

  description: 'My first java projen project',
  url: ''

See the API reference for PomOptions for a detailed list of options.


Java projects have three types of supported dependencies:

  1. Runtime dependencies (or just “dependencies”).
  2. Test dependencies
  3. Maven plugins (modeled as build dependencies).

You can define dependencies when defining the project itself:

const project = new JavaProject({
  deps: [

Or using the APIs:


Notice the syntax for dependencies:


Where groupID and artifactId are the Maven coordinates and version is the semantic version requirement for the dependency. The semver syntax will be converted to POM syntax. For example, ^3.1.0 will be converted to [3.1.0,4.0.0).

It is possible to write your projenrc file in Java. In the future this will be the default for Java projects, but at the moment this needs to be enabled when the project is created:

$ projen new java --projenrc-java

Or set through:

new java.JavaProject({
  // ...
  projenrcJava: true

Then, create a file src/test/java/ that looks like this:


public class projenrc {
    public static void main(String[] args) {
        JavaProject project = new JavaProject(JavaProjectOptions.builder()

In order to synthesize, run: pj synth, which will compile your test code and execute this program.

By default, is placed under the test scope (and io.github.cdklabs/projen test dependency is added). This ensures that application code does not take a dependency on projen code. You can change this behavior by setting the testScope option to false.

Maven Plugins

You can add Maven build plugins to your project using project.addPlugin():

project.addPlugin('org.apache.maven.plugins/maven-compiler-plugin@3.8.1', {
  configuration: {
    source: '1.8',
    target: '1.8',

Unit Testing with JUnit

The JUnit component adds support for writing Java tests with JUnit. The component will add the required test dependencies to your POM file.

Test sources are placed under src/test and can be executed via mvn test or projen test (same).

To disable JUnit tests, set junit: false when you define the MavenProject.


Java projects include definitionds for producing an output that is ready-to-publish to Maven using tools like jsii-release. In future versions of projen we will also support auto-publishing through CI/CD.

The packaging component adds a package task which uses mvn deploy to create a local maven directory with artifacts that can be uploaded to a Maven repository such as Maven Central, CodeArtifact or GitHub Packages.

By default, packages includes javadocs and sources. Those can be disabled through packagingOptions.



Publishing to Maven is still not supported output of the box. Since the package output of JavaProject is compatible with jsii-release, and we already release to Maven from jsii projects, it should be possible to reuse quite a lot.