OscarRyz
OscarRyz

Reputation: 199215

Specify system property to Maven project

Is there a way ( I mean how do I ) set a system property in a maven project?

I want to access a property from my test and my webapp ( running locally ) and I know I can use a java system property.

Should I put that in ./settings.xml or something like that?

Context

I took an open source project and managed to change the db configuration to use JavaDB

Now, in the jdbc url for JavaDB, the location of the database could be specified as the full path ( see: this other question )

Or a system property: derby.system.home

I have the code working already, but currently it is all hardcoded to:

 jdbc:derby:/Users/oscarreyes/javadbs/mydb

And I want to remove the full path, to leave it like:

 jdbc:derby:mydb

To do that I need to specify the system property ( derby.system.home ) to maven, but I don't know how.

The test are performed using junit ( I don't see any plugin in pom.xml ) and the web app runs with the jetty plugin.

Specifying the system property in the command line seems to work for jetty, but I'm not sure if that's something practical ( granted some other users may run it from eclipse/idea/ whatever )

Upvotes: 77

Views: 231938

Answers (5)

Muhammad Usman
Muhammad Usman

Reputation: 31

Problem:

You want to replicate the passing of system properties while running mvn spring-boot:run in the same way as when running JAR files using java -DpropertyName=propertyValue -jar jarFileName.jar.

you can use the spring-boot-maven-plugin to pass system properties:

<plugin>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-maven-plugin</artifactId>
    <configuration>
        <systemPropertyVariables>
            <envFilePath>U:\Java\SpringBoot\AccessFuture\.env</envFilePath>
        </systemPropertyVariables>
    </configuration>
</plugin>

In this example, envFilePath is the property name, and U:\Java\SpringBoot\AccessFuture.env is the property value.

If you want to pass the property value from the command line, you can use a Maven property placeholder:

<envFilePath>${env.file.path}</envFilePath>

Then, run the following command, replacing U:/Java/SpringBoot/AccessFuture/.env with your desired value:

mvn spring-boot:run -Denv.file.path=U:/Java/SpringBoot/AccessFuture/.env

Note: Ensure that you use the correct path separator (backslash \ for Windows or forward slash / for Unix-based systems) when specifying file paths.

then I am reading them like this, in main class before SpringApplication.run();

var path  = System.getProperty("envFilePath");
Files.readAllLines(Paths.get(path)).stream()
     .filter(lines -> !lines.isBlank() && !lines.startsWith("#"))
     .map(entry -> entry.split("=", 2))
     .forEach(keyValue -> System.setProperty(keyValue[0], keyValue[1]));

For more information, refer to this specific section in Spring Boot documentation.

Upvotes: 0

yegor256
yegor256

Reputation: 105053

properties-maven-plugin plugin may help:

<plugin>
    <groupId>org.codehaus.mojo</groupId>
    <artifactId>properties-maven-plugin</artifactId>
    <version>1.0.0</version>
    <executions>
        <execution>
            <goals>
                <goal>set-system-properties</goal>
            </goals>
            <configuration>
                <properties>
                    <property>
                        <name>my.property.name</name>
                        <value>my property value</value>
                    </property>
                </properties>
            </configuration>
        </execution>
    </executions>
</plugin>

Upvotes: 82

amram99
amram99

Reputation: 709

If your test and webapp are in the same Maven project, you can use a property in the project POM. Then you can filter certain files which will allow Maven to set the property in those files. There are different ways to filter, but the most common is during the resources phase - http://books.sonatype.com/mvnref-book/reference/resource-filtering-sect-description.html

If the test and webapp are in different Maven projects, you can put the property in settings.xml, which is in your maven repository folder (C:\Documents and Settings\username.m2) on Windows. You will still need to use filtering or some other method to read the property into your test and webapp.

Upvotes: 2

bvesco
bvesco

Reputation: 361

I have learned it is also possible to do this with the exec-maven-plugin if you're doing a "standalone" java app.

            <plugin>
            <groupId>org.codehaus.mojo</groupId>
            <artifactId>exec-maven-plugin</artifactId>
            <version>${maven.exec.plugin.version}</version>
            <executions>
                <execution>
                    <goals>
                        <goal>java</goal>
                    </goals>
                </execution>
            </executions>
            <configuration>
                <mainClass>${exec.main-class}</mainClass>
                <systemProperties>
                    <systemProperty>
                        <key>myproperty</key>
                        <value>myvalue</value>
                    </systemProperty>
                </systemProperties>
            </configuration>
        </plugin>

Upvotes: 11

Pascal Thivent
Pascal Thivent

Reputation: 570325

Is there a way ( I mean how do I ) set a system property in a maven project? I want to access a property from my test [...]

You can set system properties in the Maven Surefire Plugin configuration (this makes sense since tests are forked by default). From Using System Properties:

<project>
  [...]
  <build>
    <plugins>
      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-surefire-plugin</artifactId>
        <version>2.5</version>
        <configuration>
          <systemPropertyVariables>
            <propertyName>propertyValue</propertyName>
            <buildDirectory>${project.build.directory}</buildDirectory>
            [...]
          </systemPropertyVariables>
        </configuration>
      </plugin>
    </plugins>
  </build>
  [...]
</project>

and my webapp ( running locally )

Not sure what you mean here but I'll assume the webapp container is started by Maven. You can pass system properties on the command line using:

mvn -DargLine="-DpropertyName=propertyValue"

Update: Ok, got it now. For Jetty, you should also be able to set system properties in the Maven Jetty Plugin configuration. From Setting System Properties:

<project>
  ...
  <plugins>
    ...
      <plugin>
        <groupId>org.mortbay.jetty</groupId>
        <artifactId>maven-jetty-plugin</artifactId>
        <configuration>
         ...
         <systemProperties>
            <systemProperty>
              <name>propertyName</name>
              <value>propertyValue</value>
            </systemProperty>
            ...
         </systemProperties>
        </configuration>
      </plugin>
  </plugins>
</project>

Upvotes: 91

Related Questions