Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
ffe7721
#40: Updated dependencies
redcatbear Jun 11, 2026
7e27f23
#40: Fixed JavaDoc warning about wrong order of @serial and main Java…
redcatbear Jun 11, 2026
a6e1875
#40: Updated changelog.
redcatbear Jun 11, 2026
07a2a22
#40: Fixed build for Java 17. Handled excluded Xerces because of CVE.
redcatbear Jun 11, 2026
8b2c14c
#40: Fixed changelog.
redcatbear Jun 11, 2026
9da359a
#40: Took dependency update list from CI.
redcatbear Jun 11, 2026
5466325
Merge remote-tracking branch 'origin/bugfix/40_fix-code-coverage-repo…
redcatbear Jun 11, 2026
ab78066
#40: Added missing issue mention.
redcatbear Jun 11, 2026
231de77
#40: Remove Maven JAR plugin.
redcatbear Jun 11, 2026
daf337f
Run PK fix
kaklakariada Jun 11, 2026
a3cd7ca
Merge remote-tracking branch 'origin/bugfix/40_fix-code-coverage-repo…
redcatbear Jun 12, 2026
ff39196
Refactored script creation to use database object factory.
redcatbear Jun 12, 2026
e57e688
#40: Moved XMLRPC exclusion one level up.
redcatbear Jun 15, 2026
f4210fc
#40: Ported back to Java 11.
redcatbear Jun 15, 2026
4916d7a
#40: Switched back to JUnit 5 to support Java 11.
redcatbear Jun 15, 2026
a2a1b8b
#40: Switched back to JUnit 5 to support Java 11.
redcatbear Jun 15, 2026
8890e94
Fix dependencies
kaklakariada Jun 15, 2026
3c574b0
Merge branch 'bugfix/40_fix-code-coverage-reporting' of https://githu…
kaklakariada Jun 15, 2026
eb9b263
#40: Removed attempt to get code coverage. Added test strategy.
redcatbear Jun 16, 2026
f81392f
Update doc/changes/changes_1.0.10.md
redcatbear Jun 16, 2026
8100e8a
#40: Added an explanation of the module include scope in the Readme.
redcatbear Jun 16, 2026
536124d
Merge remote-tracking branch 'origin/bugfix/40_fix-code-coverage-repo…
redcatbear Jun 16, 2026
3731278
Update doc/changes/changes_1.0.10.md
kaklakariada Jun 16, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 2 additions & 4 deletions .github/workflows/ci-build.yml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 1 addition & 3 deletions .project-keeper.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,7 @@ sources:
build:
runnerOs: ubuntu-24.04
exasolDbVersions:
- "2025.2.1"
- "2025.1.10"
- "7.1.30"
- "2026.1.0"
workflows:
- name: ci-build.yml
stepCustomizations:
Expand Down
30 changes: 29 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,12 +19,40 @@ This project contains the API required to build [User Defined Functions](https:/

User Defined Functions extend Exasol with functions and scripts that can be called from within SQL statements.



## Information for API Users

### Dependency

This library is already included in the Exasol database. Therefore, you should include it with the scope `provided` in Maven or `compileOnly` in Gradle. This ensures that the library is available during compilation but is not bundled with your UDF jar, avoiding conflicts with the version pre-installed in the database.

Replace the version numbers below with the latest version.

#### Maven

```xml
<dependency>
<groupId>com.exasol</groupId>
<artifactId>udf-api-java</artifactId>
<version>1.0.10</version>
<scope>provided</scope>
</dependency>
```

#### Gradle

```groovy
dependencies {
compileOnly 'com.exasol:udf-api-java:1.0.10'
}
```

* [API documentation as JavaDoc](https://exasol.github.io/udf-api-java)
* [Java tutorials](https://github.com/exasol/exasol-java-tutorial) with examples of how to build, test and run Java UDFs

## Additional Information

* [Changelog](doc/changes/changelog.md)
* [Dependencies](dependencies.md)
* [Dependencies](dependencies.md)
* [Test strategy](doc/test_strategy.md)
17 changes: 13 additions & 4 deletions doc/changes/changes_1.0.10.md
Original file line number Diff line number Diff line change
@@ -1,18 +1,27 @@
# Exasol UDF API for Java 1.0.10, released 2026-??-??
# Exasol UDF API for Java 1.0.10, released 2026-06-16

Code name:
Code name: Test Strategy Revisited

## Summary

## Features
In this release we experimented with injecting the JaCoCo code coverage agent into the UDF when running the integration test, so that we can measure the test coverage.

* ISSUE_NUMBER: description
In the end we decided against the approach, because however we turned it, the coverage we would measure would not represent the actual API coverage. But the good news is that our attempts resulted in cleaner test code. If you want to learn more, check out the [test strategy](../test_strategy.md).

We also updated a number of dependencies.

## Bugfixes

* #40: Report integration test coverage

## Dependency Updates

### Test Dependency Updates

* Updated `com.exasol:exasol-testcontainers:7.2.3` to `7.3.0`
* Updated `com.exasol:test-db-builder-java:4.0.0` to `4.0.1`
* Added `org.jacoco:org.jacoco.agent:0.8.14`
* Updated `org.slf4j:slf4j-jdk14:2.0.17` to `2.0.18`

### Plugin Dependency Updates

Expand Down
65 changes: 65 additions & 0 deletions doc/test_strategy.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
# Test Strategy

This document explains the test setup of the [Exasol UDF API for Java](../README.md), the options considered for
measuring integration test coverage, and the decision to not use code coverage as a quality metric for this project.

## Project Setup

This project publishes the Java API that UDF authors compile against when writing Java user defined functions for the Exasol database. In production, the UDF API JAR is provided by the Exasol installation and loaded by the script language container. UDF authors compile against this artifact, but they do not include it in their own UDF JARs.

The integration tests therefore deliberately mirror this deployment model:

* The Maven build creates a test JAR containing probe UDF classes from `src/test/java`.
* The test JAR is uploaded to BucketFS in an Exasol test container.
* The integration tests create Java UDF scripts that load this test JAR with a `%jar` directive.
* The probe UDF classes were compiled against this project, but at runtime they interact with the API classes and
implementation provided by Exasol.

This setup is primarily a compatibility test. It verifies that code compiled against this project can run in Exasol and call the relevant UDF API methods.

## Coverage Problem

The project is not a typical Java library with executable production logic. Most of the public surface is made of interfaces such as `ExaIterator` and `ExaMetadata`. Interface method declarations do not contain executable instructions that JaCoCo can cover. The executable classes in this repository are mostly exception classes and a small enum.

When the JaCoCo agent is injected into the UDF JVM, it can observe code executed inside the Exasol script language container. However, the code executed there is not this project's API artifact. It is Exasol's provided runtime API and implementation plus the test probe classes. A local JaCoCo report such as `target/site/jacoco/index.html` can therefore show execution data from the UDF JVM while still reporting no meaningful coverage for this project.

## Options Considered

### Inject JaCoCo Into the UDF JVM

This was implemented and verified to collect execution data from the UDF-side JVM.

Rejected as a coverage metric for this project because the executed API implementation belongs to the Exasol runtime, not to this repository. The report does not answer the question "Which code in this project was covered by the integration tests?"

### Include This Project's API JAR in the UDF

This would make JaCoCo observe this repository's classes in the UDF runtime.

Rejected because it would no longer test the real deployment model. The Exasol installation provides the UDF API at runtime, and forcing this project's API JAR into the UDF could hide incompatibilities with the database-provided API.

The resulting coverage would be easier to measure but less relevant.

### Generate Proxy or Wrapper Code Around the API

A proxy could wrap `ExaIterator`, `ExaMetadata`, and related interfaces, record which methods were called, and delegate
to Exasol's runtime objects.

Rejected as code coverage because it would measure the proxy and the probe UDFs, not this project's API. Such a proxy could be useful as an API exercise matrix, but it would be a custom compatibility metric rather than JaCoCo coverage.

It would also add test-only code that has to mirror the whole API surface.

### Add Unit Tests for the Executable Classes

Unit tests could cover exception constructors, message formatting, and enum initialization.

Rejected as a substitute for integration coverage because this would only cover incidental executable bytecode. It would not validate the important compatibility property: UDF code compiled against this API must run against Exasol's provided runtime API.

## Decision

We do not attempt to measure meaningful code coverage for this project with integration tests.

The integration tests remain valuable and should be kept as compatibility and smoke tests. They check the behavior that matters for this artifact: Java UDF code compiled against this project can be loaded and executed by Exasol.

Coverage reports for this project should not be used as a release quality gate. If a build or quality system requires a coverage value, this repository should be excluded from that requirement or the exception should point to this document.

If more insight is needed in the future, the preferred direction is an explicit API exercise matrix that reports which UDF API methods are invoked by smoke tests. That metric must be documented as compatibility coverage, not as JaCoCo code coverage.
26 changes: 23 additions & 3 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,16 @@
<name>Exasol UDF API for Java</name>
<description>Interface between User Defined Functions (UDFs) written in Java and the Exasol database.</description>
<url>https://github.com/exasol/udf-api-java/</url>
<properties>
<java.version>11</java.version>
<!-- Fix build with older Java versions -->
<maven.javadoc.disableNoFonts>true</maven.javadoc.disableNoFonts>
</properties>
<dependencies>
<dependency>
<groupId>com.exasol</groupId>
<artifactId>exasol-testcontainers</artifactId>
<version>7.2.3</version>
<version>7.3.0</version>
<scope>test</scope>
</dependency>
<dependency>
Expand All @@ -22,7 +27,7 @@
<dependency>
<groupId>com.exasol</groupId>
<artifactId>test-db-builder-java</artifactId>
<version>4.0.0</version>
<version>4.0.1</version>
<scope>test</scope>
</dependency>
<dependency>
Expand Down Expand Up @@ -58,12 +63,25 @@
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-jdk14</artifactId>
<version>2.0.17</version>
<version>2.0.18</version>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<!-- Overriding parent POM to avoid warning with JDK 11 -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<release>${java.version}</release>
<showWarnings>true</showWarnings>
<compilerArgs>
<arg>-Xlint:all,-path</arg>
<arg>-Werror</arg>
</compilerArgs>
</configuration>
</plugin>
<plugin>
<groupId>com.exasol</groupId>
<artifactId>project-keeper-maven-plugin</artifactId>
Expand All @@ -83,6 +101,8 @@
<executions>
<execution>
<goals>
<!-- Build JAR with UDFs for integration tests -->
<!-- Note: the test-jar is also published to Maven Central -->
<goal>test-jar</goal>
</goals>
<configuration>
Expand Down
5 changes: 4 additions & 1 deletion src/main/java/com/exasol/ExaConnectionAccessException.java
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,10 @@
*/
public class ExaConnectionAccessException extends Exception {
private static final long serialVersionUID = 1L;
/** @serial Message without connection exception prefix. */
/**
* Message without connection exception prefix.
* @serial
* */
private final String message;

/**
Expand Down
Loading
Loading