Skip to content

Teamscale Java Profiler - Advanced Setup and API

This page serves to give some additional configuration options and insights into the Java Profiler. For options and conventional setup, please check out the parent page first.

Installation - Special Cases

In some cases, you need to follow additional steps so that the profiler can do its work. Here is an excerpt for a few technologies we previously encountered.

WebSphere

Register the profiler in WebSphere's startServer.bat or startServer.sh. Please also apply this additional JVM parameter:

-Xshareclasses:none

This option disables a WebSphere internal class cache that causes problems with the profiler.

Please set the profiler's includes parameter so that the WebSphere code is not being profiled. This ensures that the performance of your application does not degrade.

Also consider to use the config-file option as WebSphere 17 and probably other versions silently strip any option parameters exceeding 500 characters without any error message, which can lead to very subtle bugs when running the profiler.

JBoss

Register the profiler in the JAVA_OPTS environment variable in the bin/run.conf or bin/standalone.conf (version >= JBoss AS 7) file inside the JBoss installation directory.

Please set the profiler's includes parameter so that the JBoss code is not being profiled. This ensures that the performance of your application does not degrade.

Wildfly

Please set the profiler's includes parameter so that the Wildfly code is not being profiled. This ensures that the performance of your application does not degrade.

Using standalone mode

Register the profiler in the JAVA_OPTS environment variable in the standalone.conf file inside the Wildfly installation directory.

Using domain mode

Register the profiler in domain.xml under

xml
<server-group>
  <jvm>
    <jvm-options>
      <option value="-javaagent:..."/>
    </jvm-options>
  </jvm>
</server-group>

Tomcat/TomEE

Register the profiler in the CATALINA_OPTS environment variable inside the bin/setenv.sh or bin/setenv.bat script in the Tomcat installation directory. Create this file if it does not yet exist. Here is an example setenv.sh that attaches the profiler:

text
export CATALINA_OPTS="$CATALINA_OPTS -javaagent:path/to/teamscale-jacoco-agent.jar=config-id=Config_Name,teamscale-server-url=https://localhost:8080,teamscale-user=user,teamscale-access-token=123456token"

Please set the profiler's includes parameter so that the Tomcat code is not being profiled. This ensures that the performance of your application does not degrade.

To ensure the Tomcat process is properly shutdown you need to add export CATALINA_PID="$CATALINA_BASE/bin/catalina.pid" to the bin/setenv.sh script and stop Tomcat via catalina stop -force. This makes Tomcat store the process ID of the server in the specified file and uses it to kill the process when stopped.

Glassfish

You have two options to register the JVM option:

  1. Register the profiler via the asadmin tool.
  2. Register the profiler by manually editing domain.xml and adding a jvm-options element.

When using the asadmin tool, some characters need to be escaped with a backslash, see this StackOverflow answer.

Afterward, restart Glassfish. Please verify the setup with asadmin's list-jvm-options command.

Jetty

Register the profiler by setting a JAVA_OPTIONS variable such that the Jetty process can see it.

SAP NetWeaver Java

Please note that the Teamscale Java Profiler requires at least Java 8, which is part of NetWeaver Java 7.50. Prior versions of NetWeaver Java are not supported by the profiler.

In order to set the JVM profiler parameter, you need to use the NetWeaver Administrator to navigate to Configuration - Infrastructure - Java System Properties and add an additional JVM parameter. Use the search field to search for agent, and select the -javaagent:<jarpath>[=<options>] entry. In the Name field, enter the first part, until (including) the .jar, and provide all the options (without the leading =) in the Value field. We advise to only set the config-file option here, and provide all other options via the config file. Choose Add and then Save, and restart the Java server from the SAP Management Console.

Upload coverage to multiple Teamscale projects

To upload the full coverage to several Teamscale projects, give each profiled artifact (Jar/War/Ear...) a git.properties file with a different teamscale.project property. At runtime, the profiler collects the projects from all loaded artifacts and uploads the entire coverage of all profiled classes to each of these projects.

Do not set the project via the profiler config

Do not provide a project via the profiler CLI or the Teamscale-side profiler config for multi-project upload. A project provided this way takes precedence over every teamscale.project value in the git.properties files and therefore defeats the purpose of the multi-project setup. If you set a project via the CLI or the Teamscale-side profiler config, only a single upload to that project will be performed and the teamscale.project properties will be ignored.

The teamscale.project entry is added to git.properties via a build plugin. Here is how this can be done for Maven/Gradle.

Set up the git-commit-id maven plugin, but set generateGitPropertiesFile to false (or just leave it out):

xml
  <build>
      <plugins>
          <plugin>
              <groupId>io.github.git-commit-id</groupId>
              <artifactId>git-commit-id-maven-plugin</artifactId>
              <version>9.0.1</version>
              <executions>
                  <execution>
                      <id>get-the-git-infos</id>
                      <goals>
                          <goal>revision</goal>
                      </goals>
                      <phase>initialize</phase>
                  </execution>
              </executions>
              <configuration>
                  <generateGitPropertiesFile>false</generateGitPropertiesFile>
              </configuration>
          </plugin>
      </plugins>
  </build>

Add a file called git.properties in the resources folder (usually src/main/resources) of your application that acts as a template. This file will later be filled with the values provided from the git-commit-id plugin. Only the following two properties are required:

properties
git.commit.id=${git.commit.id}
teamscale.project=my-teamscale-project-id

The maven resource plugin will copy your template git.properties file from the resource folder to the build folder and populate the entries with the maven properties set by the git-commit-id plugin. Add the following to your pom file:

xml
<build>
    <resources>
        <resource>
            <directory>src/main/resources</directory>
            <filtering>true</filtering> <!-- The filtering is important, as this is what populates the entries. -->
            <includes>
                <include>**/*.properties</include>
            </includes>
        </resource>
    </resources>
</build>

In case the generated git.properties file still contains the placeholder values after the build, have a look at our troubleshooting section.

git.properties must be in each Jar file

Please note that each of the profiled Jar/War/Ear... files must contain such a git.properties file when specifying the teamscale.project this way. Otherwise, coverage uploads may not end up in all configured Teamscale projects consistently, as only git.properties files of the classes that were actually loaded at runtime are processed.

Overwrite the git commit coverage is uploaded to

In rare cases, you may need to set the target commit manually instead of letting the build plugin detect it. For most cases, automatic detection is recommended and correct!

Set teamscale.commit.branch and teamscale.commit.time in your git.properties file to control the branch and the point in time the coverage is attached to, instead of the commit the artifact was built from.

These entries are added to git.properties via a plugin. Here is how this can be done for Maven/Gradle.

Set up the git-commit-id maven plugin, but set generateGitPropertiesFile to false (or just leave it out):

xml
<build>
    <plugins>
        <plugin>
            <groupId>io.github.git-commit-id</groupId>
            <artifactId>git-commit-id-maven-plugin</artifactId>
            <version>9.0.1</version>
            <executions>
                <execution>
                    <id>get-the-git-infos</id>
                    <goals>
                        <goal>revision</goal>
                    </goals>
                    <phase>initialize</phase>
                </execution>
            </executions>
            <configuration>
                <generateGitPropertiesFile>false</generateGitPropertiesFile>
            </configuration>
        </plugin>
    </plugins>
</build>

Then, set up custom entries in the git.properties file (see also github docs). Add a file called git.properties in the resources folder (usually src/main/resources) of your application that acts as a template. This file will later be filled with the values provided from the git-commit-id plugin:

properties
teamscale.commit.branch=${git.branch}
teamscale.commit.time=${git.commit.time}

The maven resource plugin will move your template git.properties file from the resource folder to the build folder and populate the entries with the maven properties set by the git-commit-id plugin. Add the following to your pom file:

xml
<build>
    <resources>
        <resource>
            <directory>src/main/resources</directory>
            <filtering>true</filtering> <!-- The filtering is important, as this is what populates the entries. -->
            <includes>
                <include>**/*.properties</include>
            </includes>
        </resource>
    </resources>
</build>

In case the generated git.properties file still contains the placeholder values after the build, have a look at our troubleshooting section.

REST API

The profiler has an API interface that can be interacted with to do a variety of things like dumping coverage or changing the current git revision.

The REST API has the following endpoints:

  • [GET] /partition Returns the name of the currently configured partition.
  • [PUT] /partition Sets the name of the partition to the string delivered in the request body in plain text. This partition should be used for all followup report dumps (see teamscale-partition). For reports that are not directly sent to Teamscale the generated report will contain the partition name as session ID. Before changing the partition, performs a dump of all coverage collected so far under the previous partition.
  • [GET] /message Returns the name of the currently configured commit message.
  • [PUT] /message Sets the commit message to the string delivered in the request body in plain text. This message should be used for all followup report dumps (see teamscale-message). Before changing the message, performs a dump of all coverage collected so far under the previous message.
  • [POST] /dump Instructs the profiler to dump the collected coverage.
  • [POST] /reset Instructs the profiler to reset the collected coverage. This will discard all coverage collected in the current JVM session.
  • [GET] /revision Returns the current revision used for uploading to Teamscale. Before changing the revision, performs a dump of all coverage collected so far under the previous revision.
  • [PUT] /revision Sets the revision to use for uploading to Teamscale. The revision must be in the request body in plain text. Before changing the revision, performs a dump of all coverage collected so far under the previous revision.
  • [GET] /commit Returns the current commit used for uploading to Teamscale. Before changing the commit, performs a dump of all coverage collected so far under the previous commit.
  • [PUT] /commit Sets the commit to use for uploading to Teamscale. The commit must be in the request body in plain text in the format: branch:timestamp. Before changing the commit, performs a dump of all coverage collected so far under the previous commit.

Example curl command to set the partition: curl --fail -X PUT -d "Manual Tests" -H "Content-Type: text/plain" http://PROFILERURL:PORT/partition.

For more endpoints relevant when collecting testwise coverage, please have a look at our testwise coverage recording section.