Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
157 commits
Select commit Hold shift + click to select a range
77da14d
Make the clean target a usable program runtime, and let casts fail
shai-almog Aug 27, 2026
01b366d
Measure what a thread costs, and make the per-thread sizes tunable
shai-almog Aug 27, 2026
3d4b378
Stop discarding uncaught exceptions on the clean target
shai-almog Aug 28, 2026
2ed10e5
Fix two ParparVM portability bugs the backend build hit
shai-almog Aug 29, 2026
8d8e894
Add virtual threads to the VM
shai-almog Sep 1, 2026
7f85de9
Yield the virtual thread instead of sleeping its carrier
shai-almog Aug 31, 2026
7cfea66
Keep the virtual-thread API out of the conservative-roots block
shai-almog Sep 1, 2026
67a61b0
Capture errno before the GC safepoint in the Linux socket read
shai-almog Sep 1, 2026
15bd697
Stop waiting on a thread the GC cannot stop
shai-almog Sep 1, 2026
6e6a18a
Turn virtual threads on wherever the switch exists, and file .S as as…
shai-almog Sep 1, 2026
fe581d5
Assemble the .S the generated projects have been shipping unassembled
shai-almog Sep 1, 2026
be886b6
Close five review findings on the VM half
shai-almog Sep 2, 2026
03d2bf2
Make the direct JSON writer agree with the map path, and test that it…
shai-almog Sep 2, 2026
0119acd
Give java.io.File a Windows implementation, and stage the header it n…
shai-almog Sep 2, 2026
9b4b1ca
An archive must not write outside the directory it is unpacked into
shai-almog Sep 2, 2026
cea27a2
Finish the Windows java.io.File arm: the four gaps behind the first one
shai-almog Sep 2, 2026
ba22565
Zero a pthread_t portably, and stop declaring a local Windows cannot use
shai-almog Sep 2, 2026
80da86d
Close the VM-half review findings, and record the two that stay open
shai-almog Sep 2, 2026
764587f
Four more ways the direct JSON writer disagreed with the map path
shai-almog Sep 2, 2026
6155b5f
Enumerate a directory once, and clamp skip without overflowing first
shai-almog Sep 2, 2026
a112185
Resolve drive-relative Windows paths, and create files in one syscall
shai-almog Sep 2, 2026
eaec4ed
Decode argv and the environment as UTF-8 instead of widening bytes
shai-almog Sep 2, 2026
3451ef0
Decode argv and the environment in the PLATFORM's encoding, not alway…
shai-almog Sep 2, 2026
ea35b3b
Validate an array store's index before checking its element type
shai-almog Sep 2, 2026
2b9d12a
Revert marking a running virtual thread's state active -- it hangs th…
shai-almog Sep 2, 2026
48e84bb
Stop the array store check rejecting valid multidimensional stores
shai-almog Sep 2, 2026
287ab9d
Probe an unresponsive thread briefly instead of skipping its roots
shai-almog Sep 2, 2026
bb98371
Emit JSON null for an unset boxed Boolean or Character
shai-almog Sep 2, 2026
9f27f80
Report thread-table exhaustion instead of writing before the table
shai-almog Sep 2, 2026
99f9263
Mark active only what the collector can stop, and unbind TLS before f…
shai-almog Sep 2, 2026
e1ea719
Keep an unmapped reference field's wire type a string
shai-almog Sep 2, 2026
f13a53c
Honour close() on System.in
shai-almog Sep 2, 2026
fbc8ca8
Mark the unfinished VM surfaces EXPERIMENTAL, and keep checked casts …
shai-almog Sep 2, 2026
9896b1f
Record the registry-snapshot scope as an experimental gap, not a fix
shai-almog Sep 2, 2026
de54965
Make the uncaught-exception test's timeout reachable
shai-almog Sep 2, 2026
5694e15
File.renameTo renamed the destination onto itself
shai-almog Sep 2, 2026
2907915
Keep unmapped list elements raw -- a regression from the reference fix
shai-almog Sep 2, 2026
30d7662
Release a file stream's native handle if it is never closed
shai-almog Sep 2, 2026
bd2057f
Qualify rooted Windows paths, make close idempotent, list the snapsho…
shai-almog Sep 2, 2026
0c96b7b
Park the mutator around every blocking stdio call, not just read and …
shai-almog Sep 2, 2026
9f7d96b
Answer null for an environment name holding a NUL; decline the rest
shai-almog Sep 2, 2026
4729dea
Park the seeks too, and let the thread benchmark exit
shai-almog Sep 2, 2026
474ca03
Check point the backend throughput work in progress
shai-almog Sep 6, 2026
3a4de13
Bring the exactly-once allocation profile into the backend branch
shai-almog Sep 6, 2026
ae06800
Stop copying the borrowed read buffer on every keep-alive request
shai-almog Sep 6, 2026
9b26594
Sync the allocation-size histogram's bucket claim with the PR branch
shai-almog Sep 6, 2026
13f2758
Reuse one Request per connection instead of allocating one per request
shai-almog Sep 6, 2026
7b7f5dc
Set the backend's 4MB collection floor at build time
shai-almog Sep 7, 2026
c58e9d5
Merge remote-tracking branch 'origin/master' into backend-throughput
shai-almog Sep 7, 2026
b2ccd94
Encode the response head's fixed bytes once, not per request
shai-almog Sep 7, 2026
78a3659
Free a virtual thread's VM state, and let a handler answer without al…
shai-almog Sep 7, 2026
381ff91
Stripe the served-requests counter instead of contending one atomic
shai-almog Sep 7, 2026
0bb663c
Keep a connection armed instead of re-arming it on every park
shaiblah Sep 7, 2026
76b67c6
Compare the request line against bytes, not against Strings
shaiblah Sep 7, 2026
aa28dee
Record which half of the /json gap was real
shaiblah Sep 7, 2026
b73bfe8
Give back the SATB log once the burst that sized it is over
shaiblah Sep 8, 2026
6e71282
Answer a JSON request off the pooled Response too
shaiblah Sep 8, 2026
ed52aaf
Give MapBench the copyright header the gate requires
shaiblah Sep 8, 2026
3788f55
Build the backend runtime as part of the reactor
shaiblah Sep 8, 2026
897bcfa
Merge remote-tracking branch 'origin/master' into backend-throughput
shaiblah Sep 8, 2026
0c8ee7e
Document the backend, and what it is not for
shaiblah Sep 8, 2026
3f6b082
Generate a backend module with the app
shaiblah Sep 8, 2026
ca81184
Ship a backend module in initializr downloads
shaiblah Sep 8, 2026
751b6c2
Give the archetype's backend handler the copyright header
shaiblah Sep 8, 2026
872f89b
Validate the backend module in the initializr artifact too
shaiblah Sep 8, 2026
afb9127
Make the backend chapter a chapter rather than a pitch
shaiblah Sep 8, 2026
d943d5e
Refuse an archive entry that unpacks outside its target directory
shaiblah Sep 8, 2026
812a43d
Close the framing, decoding and binding holes review found
shaiblah Sep 8, 2026
a5e778e
Give each HTTP/2 stream its own response body, and cap it
shaiblah Sep 8, 2026
762bbbd
Open static files beneath the root instead of checking afterwards
shaiblah Sep 8, 2026
99230cd
Backend: address the second codex review round
shai-almog Sep 8, 2026
0e0b139
Backend: decode chunked replies, and fail packaging with the real reason
shai-almog Sep 8, 2026
aa3436d
Backend: address the third codex review round
shai-almog Sep 8, 2026
e19f7b7
Backend: address the fourth codex review round
shai-almog Sep 8, 2026
089bb79
Backend: stream static files over HTTP/2 instead of buffering them
shai-almog Sep 8, 2026
516ea0b
Backend: address the fifth codex review round
shai-almog Sep 8, 2026
6d5125b
Backend: address the sixth codex review round
shai-almog Sep 8, 2026
87bc8f4
Backend: address the seventh codex review round
shai-almog Sep 8, 2026
24e3188
Backend: address the eighth codex review round
shai-almog Sep 8, 2026
94367c1
Backend: address the ninth codex review round
shai-almog Sep 8, 2026
a6825b7
Backend: address the tenth codex review round
shai-almog Sep 8, 2026
720e6f7
Backend: address the eleventh codex review round
shai-almog Sep 8, 2026
fc62823
Backend: address the twelfth codex review round
shai-almog Sep 8, 2026
4685a04
Backend: repair the archetype XML, and guard the second head path
shai-almog Sep 8, 2026
06d0d27
Backend: put TLS on the pool, and stop claiming what the mode does no…
shai-almog Sep 8, 2026
61a6d79
Backend: reflow the command correction in the generated server
shai-almog Sep 8, 2026
b4f3a6a
Backend: repair the write path my non-blocking change broke
shai-almog Sep 8, 2026
dc4cdd4
Backend: routes are annotated methods, and the build writes the main
shai-almog Sep 8, 2026
654651e
Backend: test what a slow client does, and fix what that found
shai-almog Sep 8, 2026
85c043b
Backend: run the self-test on the arm that ships
shai-almog Sep 8, 2026
84e72b6
Backend: bound every native buffer slice, not just the one that was r…
shai-almog Sep 8, 2026
189f23e
Backend: stop trusting a bucket name, and stop freeing sessions still…
shai-almog Sep 8, 2026
c166cf0
Backend: a status can forbid a body, and a refused result is not a de…
shai-almog Sep 8, 2026
0d41c39
Backend: matched rows are not changed rows, and a dotted bucket needs…
shai-almog Sep 8, 2026
f0e81c0
Backend: SIGPIPE must not kill a runtime that never bound a listener
shai-almog Sep 8, 2026
b8cad00
Backend: a slow head, a short secret, and a second virtual-thread server
shai-almog Sep 8, 2026
7bad982
Backend: hold the HTTP/2 session for the whole turn, and bound what i…
shai-almog Sep 8, 2026
08d7ef5
Backend: cn1:backend-package could not link, and three narrower refusals
shai-almog Sep 8, 2026
2fdb7b4
Backend: yield across DNS, and stop the dev loop diverging from the t…
shai-almog Sep 8, 2026
6b0989f
Backend: the Date fix did not work, and now a test says so
shai-almog Sep 8, 2026
f76114f
Backend: a port the packaged server accepted and the dev loop refused
shai-almog Sep 9, 2026
06b1bcd
Backend: the outbound port had the same hole I had just reasoned away
shai-almog Sep 9, 2026
59094a8
Backend: a Connection option is a token, not a substring
shai-almog Sep 9, 2026
23131d8
Backend: bound the body by RATE, and stop losing inherited DTO fields
shai-almog Sep 9, 2026
b62f253
Backend: cover the three generator fixes I shipped without tests
shai-almog Sep 9, 2026
6f53451
Backend: overlap is not equality, and a narrowed integer is not the o…
shai-almog Sep 9, 2026
5b845aa
Merge master into backend-throughput
shai-almog Sep 9, 2026
a406bf3
Backend: the chunked path had the hole the fixed-length one just lost
shai-almog Sep 9, 2026
6af414c
Backend: make the two generators agree, and refuse a return they cann…
shai-almog Sep 9, 2026
fee09b2
Backend: a stored hash of "pbkdf2$1$$" accepted every password
shai-almog Sep 9, 2026
bc42e2f
Backend: a fresh clone could not build at all
shai-almog Sep 9, 2026
e0dcfd1
Backend: nothing shed a pooled connection once the reactor had it back
shai-almog Sep 9, 2026
3c65956
GC probe: the release wait was sized for four markers, not one
shai-almog Sep 9, 2026
7d7cb54
Backend: exact decimals, matching transaction modes, real field names
shai-almog Sep 9, 2026
943a2d1
Backend: bound what is outstanding, not what was just handed over
shai-almog Sep 9, 2026
e1f4fe8
GC probe: correct the rationale -- the wait was not the problem
shai-almog Sep 9, 2026
aa5da6c
GC: say when a host cannot release pages at all, and read it in the test
shai-almog Sep 9, 2026
b37c044
Backend: redirects, unresolved invocations, and encoded parameter names
shai-almog Sep 9, 2026
6abaaee
Backend: bound h2 headers and descriptors, and two silent value changes
shai-almog Sep 9, 2026
2a1dc0f
Backend: stop refusing the most ordinary route pair, and two exactnes…
shai-almog Sep 9, 2026
eb32944
GC: a standing dead-thread demand must not wait out the long idle
shai-almog Sep 9, 2026
a81834e
Backend: finish four fixes that were only done on one side
shai-almog Sep 9, 2026
76b8350
Backend: make the annotations honest, and stop trusting "java."
shai-almog Sep 9, 2026
0b22afd
Backend: 205 and 304 framing, body element types, and interim statuses
shai-almog Sep 9, 2026
99a14f4
Backend: check the file cap before spending one, and two narrowing fixes
shai-almog Sep 9, 2026
2b45ff6
Backend: the two JSON writers disagreed about Float, and a relative p…
shai-almog Sep 9, 2026
583e992
Contracts: the same route rules the controller half already had
shai-almog Sep 9, 2026
e7d35f4
Merge remote-tracking branch 'origin/master' into backend-throughput
shai-almog Sep 9, 2026
1ca4b72
Android: the ComponentName guard stands on its own after the gate was…
shai-almog Sep 9, 2026
ca43dca
Android: restore the file's CRLF endings, which my edit had stripped
shai-almog Sep 9, 2026
44603eb
Gates: a native check that could pass over nothing, and two decode fixes
shai-almog Sep 9, 2026
0c18458
Backend: a float that does not fit, and a resource that is staged but…
shai-almog Sep 9, 2026
19ec6ba
Backend: an empty PUT, a deadline on progress, and a 416 that was not…
shai-almog Sep 9, 2026
d8abc37
Backend: bound response bodies process-wide, and stop inventing dates
shai-almog Sep 9, 2026
8141d2d
Backend: sweep the locale-sensitive folds, not just the reported one
shai-almog Sep 9, 2026
1cdb850
Backend: bound inbound bytes process-wide, and let sqlite=false build
shai-almog Sep 9, 2026
e954b46
Backend: stop believing Content-Length before the body exists
shai-almog Sep 9, 2026
ecfc128
Controllers: an empty numeric value is not an omission
shai-almog Sep 9, 2026
95ea0de
HTTP/2: charge header bytes before the rejections, not after them
shai-almog Sep 9, 2026
a522d42
HTTP/2: the request structure is memory too; and run what the generat…
shai-almog Sep 9, 2026
9a6dc4a
Web: CURLOPT_PATH_AS_IS was guarded by an #ifdef that never fires
shai-almog Sep 9, 2026
7308074
Backend: the locale sweep that 8141d2d70d claimed but did not contain
shai-almog Sep 9, 2026
a9e6948
Backend: a download bigger than byte[], nested elements, and h2 HEAD
shai-almog Sep 9, 2026
5328e4b
Backend: bound uploads in flight, and check what a map body really holds
shai-almog Sep 9, 2026
68b7952
Controllers: returning a Response never worked, and nesting one is no…
shai-almog Sep 9, 2026
2b615ed
Backend: three holes left by the last three fixes
shai-almog Sep 9, 2026
f8dabf2
Backend: an empty value is not a false, and a 204 has no length to re…
shai-almog Sep 9, 2026
3e368f2
Backend: stop coercing what the client got wrong, and refuse a dead r…
shai-almog Sep 9, 2026
957432d
HTTP: sweep deadlines on a busy host, and grow the tables at accept
shai-almog Sep 9, 2026
b8ec94c
Backend: test the server with ParparVM as the client
shai-almog Sep 9, 2026
d82f76a
Backend: seven review findings, each with the test that shows it
shai-almog Sep 9, 2026
e09d000
CI: prune apt sources by origin, and do it before Playwright's apt
shai-almog Sep 9, 2026
6947d28
CI: the apt prune deleted the distribution; keep it, and check that i…
shai-almog Sep 9, 2026
6af8168
Controllers: the HEAD fallback's own clash, map keys, and infinite de…
shai-almog Sep 9, 2026
5731889
Backend: reserve upload memory before taking it, and two more overflows
shai-almog Sep 9, 2026
34cf878
Backend: the h2 body ceiling is a reservation, and wildcards are read…
shai-almog Sep 9, 2026
342b4dc
Processors: two false refusals and one that was missing
shai-almog Sep 9, 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
5 changes: 5 additions & 0 deletions .github/workflows/blog-prose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,11 @@ jobs:
cd scripts
npm init -y 2>/dev/null || true
npm install playwright
# Playwright shells out to apt for the OS-level deps, so the runner
# image's third-party sources have to be pruned FIRST -- a broken
# vendor mirror makes its apt-get fail as a whole and it reports
# only "Failed to install browser dependencies".
bash "$GITHUB_WORKSPACE/scripts/ci/apt-get-update.sh"
npx playwright install-deps chromium
npx playwright install chromium

Expand Down
5 changes: 5 additions & 0 deletions .github/workflows/blog-syndication.yml
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,11 @@ jobs:
if: ${{ steps.browser_creds.outputs.any_configured == 'true' }}
run: |
set -euo pipefail
# Playwright shells out to apt for the OS-level deps, so the runner
# image's third-party sources have to be pruned FIRST -- a broken
# vendor mirror makes its apt-get fail as a whole and it reports
# only "Failed to install browser dependencies".
bash "$GITHUB_WORKSPACE/scripts/ci/apt-get-update.sh"
pip install playwright
playwright install --with-deps chromium

Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/developer-guide-docs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -133,7 +133,7 @@ jobs:
run: |
set -euo pipefail
xvfb-run -a mvn -B -ntp -f maven/pom.xml \
-pl core,javase,android,css-compiler,codenameone-maven-plugin \
-pl core,javase,android,css-compiler,codenameone-maven-plugin,backend \
-am install \
-Plocal-dev-javase \
-DskipTests \
Expand Down
5 changes: 5 additions & 0 deletions .github/workflows/port-status-nightly.yml
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,11 @@ jobs:
run: |
npm init -y 2>/dev/null || true
npm install playwright
# Playwright shells out to apt for the OS-level deps, so the runner
# image's third-party sources have to be pruned FIRST -- a broken
# vendor mirror makes its apt-get fail as a whole and it reports
# only "Failed to install browser dependencies".
bash "$GITHUB_WORKSPACE/scripts/ci/apt-get-update.sh"
npx playwright install --with-deps "${{ matrix.browser }}"
- name: Run lifecycle validation
env:
Expand Down
8 changes: 8 additions & 0 deletions .github/workflows/pr.yml
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ on:
- 'scripts/ci/retry.sh'
- 'scripts/ci/apt-get-update.sh'
- 'scripts/ci/apt-get-install.sh'
- 'scripts/ci/tests/apt-get-update-test.sh'
# The build hint gates are run from this workflow and nowhere else, and one
# of them holds an empty baseline. Ignoring the whole directory meant a
# change that breaks a gate, or that adds a line to the baseline, could
Expand Down Expand Up @@ -78,6 +79,7 @@ on:
- 'scripts/ci/retry.sh'
- 'scripts/ci/apt-get-update.sh'
- 'scripts/ci/apt-get-install.sh'
- 'scripts/ci/tests/apt-get-update-test.sh'
# The build hint gates are run from this workflow and nowhere else, and one
# of them holds an empty baseline. Ignoring the whole directory meant a
# change that breaks a gate, or that adds a line to the baseline, could
Expand Down Expand Up @@ -469,6 +471,12 @@ jobs:
- name: Check build hint catalog
if: ${{ matrix.java-version == 8 }}
run: scripts/check-build-hint-catalog.sh
- name: Check the apt source prune keeps Ubuntu's own sources
if: ${{ matrix.java-version == 8 }}
# Cheap, and the rule it covers is only ever exercised on a runner whose
# apt is already broken -- so without this it would be tested by a red
# build and nothing else.
run: bash scripts/ci/tests/apt-get-update-test.sh
- name: Check the build hint data file can be rendered
if: ${{ matrix.java-version == 8 }}
# Not a drift check: nothing is committed to drift from, because every
Expand Down
5 changes: 5 additions & 0 deletions .github/workflows/scripts-javascript.yml
Original file line number Diff line number Diff line change
Expand Up @@ -210,6 +210,11 @@ jobs:
npm init -y 2>/dev/null || true
npm install playwright
# OS-level deps (apt packages) aren't cached so always install them.
# Playwright shells out to apt for the OS-level deps, so the runner
# image's third-party sources have to be pruned FIRST -- a broken
# vendor mirror makes its apt-get fail as a whole and it reports
# only "Failed to install browser dependencies".
bash "$GITHUB_WORKSPACE/scripts/ci/apt-get-update.sh"
npx playwright install-deps chromium
# `npm install playwright` resolves the floating version, so the
# cached browser binary can drift away from what the freshly
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9912,8 +9912,18 @@ public void onReceive(Context ctx, Intent intent) {
try { appCtx.unregisterReceiver(this); } catch (Throwable ignore) {}
String pkg = null;
try {
android.content.ComponentName cn = intent.getParcelableExtra(Intent.EXTRA_CHOSEN_COMPONENT);
if (cn != null) pkg = cn.getPackageName();
// Taken as a Parcelable and tested, rather than assigned straight
// to ComponentName: that assignment compiles to a CHECKCAST whose
// failure this catch would have to handle, and the extra is
// whatever the SENDING application chose to put there, so the
// failure is not hypothetical. (The cast-semantics gate no longer
// scans this port, since ParparVM does not translate it -- this
// stands on its own terms.)
android.os.Parcelable chosen =
intent.getParcelableExtra(Intent.EXTRA_CHOSEN_COMPONENT);
if (chosen instanceof android.content.ComponentName) {
pkg = ((android.content.ComponentName) chosen).getPackageName();
}
} catch (Throwable ignore) {}
listener.onResult(com.codename1.share.ShareResult.sharedTo(pkg));
}
Expand Down
36 changes: 36 additions & 0 deletions docs/demos/backend/pom.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.codenameone.developerguide</groupId>
<artifactId>democode</artifactId>
<version>1.0-SNAPSHOT</version>
</parent>
<artifactId>backendsnippets</artifactId>
<name>backendsnippets</name>
<!--
Compiles the Backend chapter's snippets. The guide includes them from here by
tag rather than quoting them inline, so a snippet that stops matching the API
fails this build instead of sitting wrong in the docs until someone tries it.

Separate from the common module because that one is the CLIENT: it builds for
iOS, Android and the browser, and codenameone-backend is a server library that
has no business on those classpaths.
-->
<dependencies>
<dependency>
<groupId>com.codenameone</groupId>
<artifactId>codenameone-backend</artifactId>
<version>${cn1.version}</version>
</dependency>
<!-- For the REST contract annotations, which the client half of the guide's
shared-contract example uses. -->
<dependency>
<groupId>com.codenameone</groupId>
<artifactId>codenameone-core</artifactId>
<version>${cn1.version}</version>
</dependency>
</dependencies>
</project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
/*
* 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.codenameone.developerguide.backend;

import com.codename1.backend.Database;
import java.io.IOException;
import java.util.List;

/** The Backend chapter's database examples, compiled so they cannot drift. */
public final class DatabaseSnippets {

private DatabaseSnippets() {
}

public static List open() throws IOException {
// tag::backend-database[]
Database db = Database.open(System.getenv("DATABASE_URL")); // or ":memory:"
db.execute("CREATE TABLE IF NOT EXISTS note (id INTEGER PRIMARY KEY, body TEXT)",
null);

List rows = db.query("SELECT id, body FROM note WHERE id > ?",
new Object[] { Integer.valueOf(10) });
// end::backend-database[]
return rows;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
/*
* 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.codenameone.developerguide.backend;

/** The data transfer object both ends of {@link NotesApi} share. */
public class Note {
public long id;
public String body;

public Note() {
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
/*
* 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.codenameone.developerguide.backend;

import com.codename1.backend.annotations.DeleteMapping;
import com.codename1.backend.annotations.GetMapping;
import com.codename1.backend.annotations.PathVariable;
import com.codename1.backend.annotations.PostMapping;
import com.codename1.backend.annotations.RequestBody;
import com.codename1.backend.annotations.RequestMapping;
import com.codename1.backend.annotations.RequestParam;
import com.codename1.backend.annotations.ResponseStatus;
import com.codename1.backend.annotations.RestController;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicLong;

// tag::backend-first-server[]
@RestController
@RequestMapping("/notes")
public class Notes {
private final Map<Long, Map> store = new ConcurrentHashMap<Long, Map>();
private final AtomicLong nextId = new AtomicLong(1);

@GetMapping("/healthz")
public String health() {
return "ok";
}

@GetMapping("/{id}")
public Map read(@PathVariable("id") long id) {
return store.get(Long.valueOf(id)); // null becomes a 404
}

@GetMapping
public List list(@RequestParam(value = "limit", defaultValue = "20") int limit) {
List page = new ArrayList();
for (Map note : store.values()) {
if (page.size() >= limit) {
break;
}
page.add(note);
}
return page;
}

@PostMapping
@ResponseStatus(201)
public Map create(@RequestBody Map note) {
long id = nextId.getAndIncrement();
Map stored = new LinkedHashMap(note);
stored.put("id", Long.valueOf(id));
store.put(Long.valueOf(id), stored);
return stored;
}

@DeleteMapping("/{id}")
@ResponseStatus(204)
public void delete(@PathVariable("id") long id) {
store.remove(Long.valueOf(id));
}
}
// end::backend-first-server[]
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
/*
* 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.codenameone.developerguide.backend;

import com.codename1.annotations.rest.Body;
import com.codename1.annotations.rest.GET;
import com.codename1.annotations.rest.POST;
import com.codename1.annotations.rest.Path;
import com.codename1.annotations.rest.RestClient;
import com.codename1.io.rest.Response;
import com.codename1.util.OnComplete;

// tag::backend-contract[]
@RestClient
public interface NotesApi {
@GET("/notes/{id}")
void note(@Path("id") String id, OnComplete<Response<Note>> callback);

@POST("/notes")
void create(@Body Note note, OnComplete<Response<Note>> callback);
}
// end::backend-contract[]
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
/*
* 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.codenameone.developerguide.backend;

/**
* What the build emits from {@link NotesApi} for the server side.
*
* Reproduced here rather than generated: the generator runs after this module
* compiles, and the point of these files is that the guide's examples compile at
* all. A real project never writes this -- it comes out of the same annotated
* contract the app's client comes out of, method for method.
*/
interface NotesApiServer {
Note note(String id) throws Exception;

Note create(Note note) throws Exception;
}
Loading
Loading