Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
37 commits
Select commit Hold shift + click to select a range
b0a8c6c
Add optional OpenTelemetry tracing to the backend and the app
shai-almog Sep 23, 2026
9944b70
Address review: pre-init install, per-thread spans, redirects, header…
shai-almog Sep 23, 2026
de97d4f
Address the second review round, and fix the touch-device leak failin…
shai-almog Sep 23, 2026
dc09158
Address the third review round
shai-almog Sep 23, 2026
7c4c09e
Address the fourth review round
shai-almog Sep 23, 2026
c8af9ba
Address the fifth review round
shai-almog Sep 23, 2026
e9ef57f
Address the sixth review round
shai-almog Sep 23, 2026
04086e5
Address the seventh review round
shai-almog Sep 23, 2026
b5d9ada
Address the eighth review round
shai-almog Sep 23, 2026
19b8a41
Address the ninth review round
shai-almog Sep 23, 2026
daa9a0a
Address the tenth review round, and retry the cn1-binaries clone
shai-almog Sep 24, 2026
4aee6ba
Address the eleventh review round, and stop CI retries replaying a ca…
shai-almog Sep 24, 2026
cd10e24
Address the twelfth review round
shai-almog Sep 24, 2026
2b7dfa9
Address the thirteenth review round
shai-almog Sep 24, 2026
79dd03d
Address the fourteenth review round
shai-almog Sep 24, 2026
8a36657
Address the fifteenth review round, and fix two CI retries that could…
shai-almog Sep 24, 2026
374f284
Trace websocket handshakes
shai-almog Sep 24, 2026
b87d879
Address the sixteenth review round
shai-almog Sep 24, 2026
3dc71fe
Retry exports from the queue instead of sleeping; address the sevente…
shai-almog Sep 24, 2026
654a33f
Address the eighteenth review round, and fix a racy sheet repaint test
shai-almog Sep 24, 2026
15774be
Address the nineteenth review round
shai-almog Sep 24, 2026
7075f50
Address the twentieth review round
shai-almog Sep 24, 2026
06fff17
Address the twenty-first review round
shai-almog Sep 24, 2026
ec5aa2b
Address the twenty-second review round
shai-almog Sep 24, 2026
5b579aa
Address the twenty-third review round
shai-almog Sep 24, 2026
58c7fed
Address the twenty-fourth review round, and a slow-runner test deadline
shai-almog Sep 24, 2026
50d1d71
Address the twenty-fifth review round, and retry DNS failures in CI
shai-almog Sep 24, 2026
9ae657e
Address the twenty-sixth review round
shai-almog Sep 24, 2026
bd7b0d9
Address the twenty-seventh review round, and make the sheet repaint t…
shai-almog Sep 24, 2026
1781111
Fix three telemetry tests that failed only in the full suite, and the…
shai-almog Sep 25, 2026
e087ebe
Address the twenty-eighth review round
shai-almog Sep 25, 2026
70cbd7f
Address the twenty-ninth review round
shai-almog Sep 25, 2026
66d3b85
Fix the CLDC11 compile break, and address the thirtieth review round
shai-almog Sep 25, 2026
3b6c729
Address the thirty-first review round
shai-almog Sep 25, 2026
c6494b5
Address the thirty-second review round, and tidy the request's tracer…
shai-almog Sep 25, 2026
bc63db5
Address the thirty-third review round
shai-almog Sep 25, 2026
9482083
Write a status-only response in one write, so its span keeps the status
shai-almog Sep 25, 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
38 changes: 35 additions & 3 deletions .github/workflows/parparvm-tests-windows.yml
Original file line number Diff line number Diff line change
Expand Up @@ -243,6 +243,17 @@ jobs:
# time and cannot turn a failing test green.
$ok = $false
foreach ($delay in 0, 30, 90, 180, 300) {
# Maven records a download that failed as a *.lastUpdated marker and then
# answers later resolutions from it instead of the network -- the "(absent)"
# in "Could not transfer artifact ... (absent)". Left in place, every retry
# below replays the first 403 offline and cannot succeed: one Central refusal
# of org.junit:junit-bom took all five attempts and the job. And because
# setup-java's cache: 'maven' restores ~/.m2 between runs, a marker can also
# arrive from an earlier run, so this clears them before EVERY attempt, not
# just the retries. A marker records only a failure, never an artifact, so
# deleting one costs at most a repeated question to Central.
Get-ChildItem -Path "$env:USERPROFILE\.m2\repository" -Recurse -File -Filter '*.lastUpdated' -ErrorAction SilentlyContinue |
Remove-Item -Force -ErrorAction SilentlyContinue
if ($delay -gt 0) {
Write-Host "mvn failed; retrying in $delay s..."
Start-Sleep -Seconds $delay
Expand All @@ -255,9 +266,12 @@ jobs:
# exists for. A blanket loop lets an intermittent product regression pass on
# attempt two and turns a blocking gate green -- which is the opposite of what
# a gate is for, and worse than the flake it was hiding.
$resolutionFailure = 'status: (403|429|50[0-9])|Could not transfer artifact|Failed to read artifact descriptor|Unresolveable build extension|Non-resolvable import POM|Could not resolve dependencies'
$resolutionFailure = 'status: (403|429|50[0-9])|Could not transfer artifact|Failed to read artifact descriptor|Unresolveable build extension|Non-resolvable import POM|Could not resolve dependencies|UnknownHostException|Could not resolve host|Temporary failure in name resolution'
$ok = $false
foreach ($delay in 0, 30, 90, 180, 300) {
# Clear Maven's cached resolution failures first; see the first retry loop above.
Get-ChildItem -Path "$env:USERPROFILE\.m2\repository" -Recurse -File -Filter '*.lastUpdated' -ErrorAction SilentlyContinue |
Remove-Item -Force -ErrorAction SilentlyContinue
if ($delay -gt 0) {
Write-Host "mvn failed on a dependency-resolution error; retrying in $delay s..."
Start-Sleep -Seconds $delay
Expand Down Expand Up @@ -371,6 +385,9 @@ jobs:
run: |
$ok = $false
foreach ($delay in 0, 30, 90, 180, 300) {
# Clear Maven's cached resolution failures first; see the first retry loop above.
Get-ChildItem -Path "$env:USERPROFILE\.m2\repository" -Recurse -File -Filter '*.lastUpdated' -ErrorAction SilentlyContinue |
Remove-Item -Force -ErrorAction SilentlyContinue
if ($delay -gt 0) {
Write-Host "mvn failed; retrying in $delay s..."
Start-Sleep -Seconds $delay
Expand Down Expand Up @@ -404,6 +421,9 @@ jobs:
# Same retry as the port build above: this reaches Maven Central too.
$ok = $false
foreach ($delay in 0, 30, 90, 180, 300) {
# Clear Maven's cached resolution failures first; see the first retry loop above.
Get-ChildItem -Path "$env:USERPROFILE\.m2\repository" -Recurse -File -Filter '*.lastUpdated' -ErrorAction SilentlyContinue |
Remove-Item -Force -ErrorAction SilentlyContinue
if ($delay -gt 0) {
Write-Host "mvn failed; retrying in $delay s..."
Start-Sleep -Seconds $delay
Expand Down Expand Up @@ -481,6 +501,9 @@ jobs:
# blocking gate green.
$ok = $false
foreach ($delay in 0, 30, 90, 180, 300) {
# Clear Maven's cached resolution failures first; see the first retry loop above.
Get-ChildItem -Path "$env:USERPROFILE\.m2\repository" -Recurse -File -Filter '*.lastUpdated' -ErrorAction SilentlyContinue |
Remove-Item -Force -ErrorAction SilentlyContinue
if ($delay -gt 0) {
Write-Host "mvn failed; retrying in $delay s..."
Start-Sleep -Seconds $delay
Expand All @@ -489,9 +512,12 @@ jobs:
if ($LASTEXITCODE -eq 0) { $ok = $true; break }
}
if (-not $ok) { throw "mvn clean package failed after all retries" }
$resolutionFailure = 'status: (403|429|50[0-9])|Could not transfer artifact|Unresolveable build extension|Non-resolvable import POM|Could not resolve dependencies'
$resolutionFailure = 'status: (403|429|50[0-9])|Could not transfer artifact|Unresolveable build extension|Non-resolvable import POM|Could not resolve dependencies|UnknownHostException|Could not resolve host|Temporary failure in name resolution'
$ok = $false
foreach ($delay in 0, 30, 90, 180, 300) {
# Clear Maven's cached resolution failures first; see the first retry loop above.
Get-ChildItem -Path "$env:USERPROFILE\.m2\repository" -Recurse -File -Filter '*.lastUpdated' -ErrorAction SilentlyContinue |
Remove-Item -Force -ErrorAction SilentlyContinue
if ($delay -gt 0) {
Write-Host "mvn failed on a dependency-resolution error; retrying in $delay s..."
Start-Sleep -Seconds $delay
Expand Down Expand Up @@ -649,6 +675,9 @@ jobs:
# blocking gate green.
$ok = $false
foreach ($delay in 0, 30, 90, 180, 300) {
# Clear Maven's cached resolution failures first; see the first retry loop above.
Get-ChildItem -Path "$env:USERPROFILE\.m2\repository" -Recurse -File -Filter '*.lastUpdated' -ErrorAction SilentlyContinue |
Remove-Item -Force -ErrorAction SilentlyContinue
if ($delay -gt 0) {
Write-Host "mvn failed; retrying in $delay s..."
Start-Sleep -Seconds $delay
Expand All @@ -657,9 +686,12 @@ jobs:
if ($LASTEXITCODE -eq 0) { $ok = $true; break }
}
if (-not $ok) { throw "mvn clean package failed after all retries" }
$resolutionFailure = 'status: (403|429|50[0-9])|Could not transfer artifact|Unresolveable build extension|Non-resolvable import POM|Could not resolve dependencies'
$resolutionFailure = 'status: (403|429|50[0-9])|Could not transfer artifact|Unresolveable build extension|Non-resolvable import POM|Could not resolve dependencies|UnknownHostException|Could not resolve host|Temporary failure in name resolution'
$ok = $false
foreach ($delay in 0, 30, 90, 180, 300) {
# Clear Maven's cached resolution failures first; see the first retry loop above.
Get-ChildItem -Path "$env:USERPROFILE\.m2\repository" -Recurse -File -Filter '*.lastUpdated' -ErrorAction SilentlyContinue |
Remove-Item -Force -ErrorAction SilentlyContinue
if ($delay -gt 0) {
Write-Host "mvn failed on a dependency-resolution error; retrying in $delay s..."
Start-Sleep -Seconds $delay
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/windows-cross-compile.yml
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,7 @@ jobs:
# retries reuse the previous attempt's target directories, so a partial output
# can decide the result. Matching the output keeps a real failure terminal on
# its first occurrence, and the retry starts from clean.
resolution='status: (403|429|50[0-9])|Could not transfer artifact|Failed to read artifact descriptor|Unresolveable build extension|Non-resolvable import POM|Could not resolve dependencies'
resolution='status: (403|429|50[0-9])|Could not transfer artifact|Failed to read artifact descriptor|Unresolveable build extension|Non-resolvable import POM|Could not resolve dependencies|UnknownHostException|Could not resolve host|Temporary failure in name resolution'
goal=install
for delay in 30 120 300 0; do
# PIPESTATUS, not the pipeline's status: tee succeeds even when mvn does not,
Expand Down
87 changes: 87 additions & 0 deletions CodenameOne/src/com/codename1/annotations/OpenTelemetry.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
/*
* Copyright (c) 2012, Codename One and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Codename One designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Codename One through http://www.codenameone.com/ if you
* need additional information or have any questions.
*/
package com.codename1.annotations;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

/// Traces the app with OpenTelemetry: every network request becomes a span, and
/// carries the W3C trace context to the server it reaches, so a tap in the app and
/// the backend work it caused are one trace.
///
/// Put it on the main class. The build generates a bootstrap that installs
/// `com.codename1.telemetry.Telemetry` before the app starts, and nothing else in
/// the app changes.
///
/// ```java
/// // Through the app's own Codename One backend (cn1.otel.relay=true there),
/// // which holds the collector's credentials:
/// @OpenTelemetry(relay = "https://api.example.com", serviceName = "shop-app")
/// public class ShopApp extends Lifecycle { ... }
///
/// // Or straight to a collector. The header ships inside the app, so use a token
/// // that can write traces and nothing else:
/// @OpenTelemetry(endpoint = "https://collector.example.com:4318",
/// headers = "Authorization: Api-Token dt0c01.ingest-only")
/// public class ShopApp extends Lifecycle { ... }
/// ```
///
/// Exactly one of `relay` and `endpoint` is set. Without the annotation the
/// telemetry classes are never referenced, so the app does not carry them.
@Retention(RetentionPolicy.CLASS)
@Target(ElementType.TYPE)
public @interface OpenTelemetry {
/// The base URL of a Codename One backend that relays spans to the collector.
String relay() default "";

/// The base URL of an OTLP/HTTP collector to export to directly;
/// `/v1/traces` is appended.
String endpoint() default "";

/// The `service.name` the app reports as. Defaults to the app's name.
String serviceName() default "";

/// Headers for a direct export, each `"Name: value"`.
String[] headers() default {};

/// The token a relay configured with `cn1.otel.relay.token` expects.
String relayToken() default "";

/// The share of new traces recorded, from 0 to 1.
double sampleRatio() default 1.0;

/// Whether a direct export is binary protobuf (the default) or JSON.
boolean protobuf() default true;

/// Further hosts to send the trace context to. See
/// `TelemetryConfig.propagateTo`: on the web only the relay's host and these
/// receive it, because the header needs CORS permission.
String[] propagateTo() default {};

/// Traces only while the user has granted analytics consent through
/// `com.codename1.analytics.Analytics`. See
/// `TelemetryConfig.requireAnalyticsConsent`.
boolean requireAnalyticsConsent() default false;
}
Loading
Loading