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 profilers 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 run.conf file inside the JBoss installation directory.

Please set the profilers 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 profilers 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 profilers 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.

Java Web Start

Please ask CQSE for special tooling that is available to instrument Java Web Start processes.

Add custom entries to git.properties file

There are two scenarios in which you want to add a custom entry to your git.properties file:

  • Uploading Coverage to multiple Teamscale projects
  • Overwriting the git commit id with teamscale.commit.branch and teamscale.commit.time

In both cases, you need to add custom entries to your git.properties file so that the profiler can upload the coverage to the right project or point in time. 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 java/main/ressources) of your application that acts as a template. This file will later be filled with the values provided from the git-commit-id plugin. The following one contains all default properties + the teamscale.project, teamscale.commit.branch and teamscale.commit.time properties:

properties
    git.tags=${git.tags}
    git.branch=${git.branch}
    git.local.branch.ahead=${git.local.branch.ahead}
    git.local.branch.behind=${git.local.branch.behind}
    git.dirty=${git.dirty}
    git.remote.origin.url=${git.remote.origin.url}
    git.commit.id=${git.commit.id.full}
    git.commit.id.abbrev=${git.commit.id.abbrev}
    git.commit.id.describe=${git.commit.id.describe}
    git.commit.id.describe-short=${git.commit.id.describe-short}
    git.commit.user.name=${git.commit.user.name}
    git.commit.user.email=${git.commit.user.email}
    git.commit.message.full=${git.commit.message.full}
    git.commit.message.short=${git.commit.message.short}
    git.commit.time=${git.commit.time}
    git.closest.tag.name=${git.closest.tag.name}
    git.closest.tag.commit.count=${git.closest.tag.commit.count}
    git.build.user.name=${git.build.user.name}
    git.build.user.email=${git.build.user.email}
    git.build.time=${git.build.time}
    git.build.host=${git.build.host}
    git.build.version=${git.build.version}
    git.build.number=${git.build.number}
    git.build.number.unique=${git.build.number.unique}
    teamscale.project=my-teamscale-project-id
    teamscale.commit.branch=${git.branch} # Set these values if you want the profiler to upload the coverage to this branch instead
    teamscale.commit.time=${git.build.time} # Set these values if you want the profiler to upload the coverage to this point in time instead
    # alternatively via environment variables
    # teamscale.commit.branch=${env.BRANCH}
    # teamscale.commit.time=${env.BUILD_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.

Dual Input

In case teamscale-project is provided via the profiler config, its value takes precedence over any teamscale.project value provided via the git.properties.

Please note that the commit must be provided via the git.properties in each of the profiled Jar/War/Ear... files when specifying the teamscale.project this way.

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 thext in the format: branch:timestmap. 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.