Skip to content

Commit 22d0d8e

Browse files
ludochgae-java-bot
authored andcommitted
This change introduces major updates to the App Engine Java SDK, including:
- Support for Jetty 12.1 and Jakarta EE 11 via a new `java25` runtime option. - A major version bump to `3.0.0` due to compilation target changes and API refactoring. - Refactoring of generic Jakarta EE API packages from `ee10` to `jakarta`. **Release 3.0.0** The project version is bumped to `3.0.0-SNAPSHOT`, and the base compilation target is raised from Java 8 to Java 17. This major version increment reflects breaking API package changes and the new baseline Java version. **Jetty 12.1 and Jakarta EE 11 Support** - Adds build configurations, SDK classes (`Jetty121EE8Sdk`, `Jetty121EE11Sdk`), and runtime handlers (`EE11AppVersionHandlerFactory`) to support Jetty 12.1 with both EE8 and EE11 applications. - Introduces a new `java25` runtime option in `appengine-web.xml`, which defaults to using Jetty 12.1 with EE11 support. - Jetty 12.0 continues to support EE8 and EE10 for `java17` and `java21` runtimes. **API Refactoring: `ee10` to `jakarta`** To better reflect that common servlet APIs are part of Jakarta EE rather than a specific version like EE10, packages named `ee10` have been refactored. The existing `ee10` classes are now deprecated with `@Deprecated(since = "3.0.0")` and point to their replacements in new `jakarta` packages via `{@link}` tags in Javadoc. This includes: - `com.google.appengine.api.blobstore.ee10.*` -> `c.g.a.api.blobstore.jakarta.*` - `com.google.appengine.api.mail.ee10.*` -> `c.g.a.api.mail.jakarta.*` - `com.google.appengine.api.taskqueue.ee10.*` -> `c.g.a.api.taskqueue.jakarta.*` - `com.google.appengine.api.utils.ee10.*` -> `c.g.a.api.utils.jakarta.*` - `c.g.apphosting.utils.remoteapi.EE10RemoteApiServlet` -> `c.g.apphosting.utils.remoteapi.JakartaRemoteApiServlet` - `c.g.apphosting.utils.servlet.ee10.*` -> `c.g.apphosting.utils.servlet.jakarta.*` **Breaking Change:** Applications using classes from the `ee10` packages listed above must update their imports to use the corresponding `jakarta` packages when upgrading to SDK 3.0.0. **Other Changes:** - Test infrastructure updated to handle new Jetty/EE versions. - Demo applications added/updated for Jakarta EE compatibility. PiperOrigin-RevId: 806498954 Change-Id: I894364e865eb6735b365563e956a3e043632766c
1 parent 0350b6d commit 22d0d8e

318 files changed

Lines changed: 26017 additions & 2028 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

api/pom.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@
2121
<parent>
2222
<groupId>com.google.appengine</groupId>
2323
<artifactId>parent</artifactId>
24-
<version>2.0.40-SNAPSHOT</version>
24+
<version>3.0.0-SNAPSHOT</version>
2525
</parent>
2626
<properties>
2727
<maven.deploy.skip>true</maven.deploy.skip>

api/src/main/java/com/google/appengine/api/blobstore/ee10/BlobstoreService.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -29,10 +29,10 @@
2929
import org.jspecify.annotations.Nullable;
3030

3131
/**
32-
* {@code BlobstoreService} allows you to manage the creation and
33-
* serving of large, immutable blobs to users.
34-
*
32+
* @deprecated as of version 3.0, use {@link
33+
* com.google.appengine.api.blobstore.jakarta.BlobstoreService} instead.
3534
*/
35+
@Deprecated(since = "3.0.0")
3636
public interface BlobstoreService {
3737
public static final int MAX_BLOB_FETCH_SIZE = (1 << 20) - (1 << 15); // 1MB - 16K;
3838

api/src/main/java/com/google/appengine/api/blobstore/ee10/BlobstoreServiceFactory.java

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,11 @@
1717
package com.google.appengine.api.blobstore.ee10;
1818

1919

20-
/** Creates {@link BlobstoreService} implementations for java EE 10. */
20+
/**
21+
* @deprecated as of version 3.0, use {@link
22+
* com.google.appengine.api.blobstore.jakarta.BlobstoreServiceFactory} instead.
23+
*/
24+
@Deprecated(since = "3.0.0")
2125
public final class BlobstoreServiceFactory {
2226

2327
/** Creates a {@code BlobstoreService} for java EE 10. */

api/src/main/java/com/google/appengine/api/blobstore/ee10/BlobstoreServiceImpl.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -50,10 +50,10 @@
5050
import org.jspecify.annotations.Nullable;
5151

5252
/**
53-
* {@code BlobstoreServiceImpl} is an implementation of {@link BlobstoreService} that makes API
54-
* calls to {@link ApiProxy}.
55-
*
53+
* @deprecated as of version 3.0, use {@link
54+
* com.google.appengine.api.blobstore.jakarta.BlobstoreServiceImpl} instead.
5655
*/
56+
@Deprecated(since = "3.0.0")
5757
class BlobstoreServiceImpl implements BlobstoreService {
5858
static final String PACKAGE = "blobstore";
5959
static final String SERVE_HEADER = "X-AppEngine-BlobKey";
Lines changed: 243 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,243 @@
1+
/*
2+
* Copyright 2021 Google LLC
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* https://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package com.google.appengine.api.blobstore.jakarta;
18+
19+
import com.google.appengine.api.blobstore.BlobInfo;
20+
import com.google.appengine.api.blobstore.BlobKey;
21+
import com.google.appengine.api.blobstore.ByteRange;
22+
import com.google.appengine.api.blobstore.FileInfo;
23+
import com.google.appengine.api.blobstore.UploadOptions;
24+
import jakarta.servlet.http.HttpServletRequest;
25+
import jakarta.servlet.http.HttpServletResponse;
26+
import java.io.IOException;
27+
import java.util.List;
28+
import java.util.Map;
29+
import org.jspecify.annotations.Nullable;
30+
31+
/**
32+
* {@code BlobstoreService} allows you to manage the creation and
33+
* serving of large, immutable blobs to users.
34+
*
35+
*/
36+
public interface BlobstoreService {
37+
public static final int MAX_BLOB_FETCH_SIZE = (1 << 20) - (1 << 15); // 1MB - 16K;
38+
39+
/**
40+
* Create an absolute URL that can be used by a user to
41+
* asynchronously upload a large blob. Upon completion of the
42+
* upload, a callback is made to the specified URL.
43+
*
44+
* @param successPath A relative URL which will be invoked
45+
* after the user successfully uploads a blob. Must start with a "/",
46+
* and must be URL-encoded.
47+
*
48+
* @throws IllegalArgumentException If successPath was not valid.
49+
* @throws BlobstoreFailureException If an error occurred while
50+
* communicating with the blobstore.
51+
*/
52+
String createUploadUrl(String successPath);
53+
54+
/**
55+
* Create an absolute URL that can be used by a user to
56+
* asynchronously upload a large blob. Upon completion of the
57+
* upload, a callback is made to the specified URL.
58+
*
59+
* @param successPath A relative URL which will be invoked
60+
* after the user successfully uploads a blob. Must start with a "/".
61+
* @param uploadOptions Specific options applicable only for this
62+
* upload URL.
63+
*
64+
* @throws IllegalArgumentException If successPath was not valid.
65+
* @throws BlobstoreFailureException If an error occurred while
66+
* communicating with the blobstore.
67+
*/
68+
String createUploadUrl(String successPath, UploadOptions uploadOptions);
69+
70+
/**
71+
* Arrange for the specified blob to be served as the response
72+
* content for the current request. {@code response} should be
73+
* uncommitted before invoking this method, and should be assumed to
74+
* be committed after invoking it. Any content written before
75+
* calling this method will be ignored. You may, however, append
76+
* custom headers before or after calling this method.
77+
*
78+
* <p>Range header will be automatically translated from the Content-Range
79+
* header in the response.
80+
*
81+
* @param blobKey Blob-key to serve in response.
82+
* @param response HTTP response object.
83+
*
84+
* @throws IOException If an I/O error occurred.
85+
* @throws IllegalStateException If {@code response} was already committed.
86+
*/
87+
void serve(BlobKey blobKey, HttpServletResponse response) throws IOException;
88+
89+
/**
90+
* Arrange for the specified blob to be served as the response
91+
* content for the current request. {@code response} should be
92+
* uncommitted before invoking this method, and should be assumed to
93+
* be committed after invoking it. Any content written before
94+
* calling this method will be ignored. You may, however, append
95+
* custom headers before or after calling this method.
96+
*
97+
* <p>This method will set the App Engine blob range header to serve a
98+
* byte range of that blob.
99+
*
100+
* @param blobKey Blob-key to serve in response.
101+
* @param byteRange Byte range to serve in response.
102+
* @param response HTTP response object.
103+
*
104+
* @throws IOException If an I/O error occurred.
105+
* @throws IllegalStateException If {@code response} was already committed.
106+
*/
107+
void serve(BlobKey blobKey, @Nullable ByteRange byteRange, HttpServletResponse response)
108+
throws IOException;
109+
110+
/**
111+
* Arrange for the specified blob to be served as the response
112+
* content for the current request. {@code response} should be
113+
* uncommitted before invoking this method, and should be assumed to
114+
* be committed after invoking it. Any content written before
115+
* calling this method will be ignored. You may, however, append
116+
* custom headers before or after calling this method.
117+
*
118+
* <p>This method will set the App Engine blob range header to the content
119+
* specified.
120+
*
121+
* @param blobKey Blob-key to serve in response.
122+
* @param rangeHeader Content for range header to serve.
123+
* @param response HTTP response object.
124+
*
125+
* @throws IOException If an I/O error occurred.
126+
* @throws IllegalStateException If {@code response} was already committed.
127+
*/
128+
void serve(BlobKey blobKey, String rangeHeader, HttpServletResponse response)
129+
throws IOException;
130+
131+
/**
132+
* Get byte range from the request.
133+
*
134+
* @param request HTTP request object.
135+
*
136+
* @return Byte range as parsed from the HTTP range header. null if there is no header.
137+
*
138+
* @throws RangeFormatException Unable to parse header because of invalid format.
139+
* @throws UnsupportedRangeFormatException Header is a valid HTTP range header, the specific
140+
* form is not supported by app engine. This includes unit types other than "bytes" and multiple
141+
* ranges.
142+
*/
143+
@Nullable ByteRange getByteRange(HttpServletRequest request);
144+
145+
/**
146+
* Permanently deletes the specified blobs. Deleting unknown blobs is a
147+
* no-op.
148+
*
149+
* @throws BlobstoreFailureException If an error occurred while
150+
* communicating with the blobstore.
151+
*/
152+
void delete(BlobKey... blobKeys);
153+
154+
/**
155+
* Returns the {@link BlobKey} for any files that were uploaded, keyed by the
156+
* upload form "name" field.
157+
* <p>This method should only be called from within a request served by
158+
* the destination of a {@code createUploadUrl} call.
159+
*
160+
* @throws IllegalStateException If not called from a blob upload
161+
* callback request.
162+
*
163+
* @deprecated Use {@link #getUploads} instead. Note that getUploadedBlobs
164+
* does not handle cases where blobs have been uploaded using the
165+
* multiple="true" attribute of the file input form element.
166+
*/
167+
@Deprecated Map<String, BlobKey> getUploadedBlobs(HttpServletRequest request);
168+
169+
/**
170+
* Returns the {@link BlobKey} for any files that were uploaded, keyed by the
171+
* upload form "name" field.
172+
* This method should only be called from within a request served by
173+
* the destination of a {@link #createUploadUrl} call.
174+
*
175+
* @throws IllegalStateException If not called from a blob upload
176+
* callback request.
177+
* @see #getBlobInfos
178+
* @see #getFileInfos
179+
*/
180+
Map<String, List<BlobKey>> getUploads(HttpServletRequest request);
181+
182+
/**
183+
* Returns the {@link BlobInfo} for any files that were uploaded, keyed by the
184+
* upload form "name" field.
185+
* This method should only be called from within a request served by
186+
* the destination of a {@link #createUploadUrl} call.
187+
*
188+
* @throws IllegalStateException If not called from a blob upload
189+
* callback request.
190+
* @see #getFileInfos
191+
* @see #getUploads
192+
* @since 1.7.5
193+
*/
194+
Map<String, List<BlobInfo>> getBlobInfos(HttpServletRequest request);
195+
196+
/**
197+
* Returns the {@link FileInfo} for any files that were uploaded, keyed by the
198+
* upload form "name" field.
199+
* This method should only be called from within a request served by
200+
* the destination of a {@link #createUploadUrl} call.
201+
*
202+
* Prefer this method over {@link #getBlobInfos} or {@link #getUploads} if
203+
* uploading files to Cloud Storage, as the FileInfo contains the name of the
204+
* created filename in Cloud Storage.
205+
*
206+
* @throws IllegalStateException If not called from a blob upload
207+
* callback request.
208+
* @see #getBlobInfos
209+
* @see #getUploads
210+
* @since 1.7.5
211+
*/
212+
Map<String, List<FileInfo>> getFileInfos(HttpServletRequest request);
213+
214+
/**
215+
* Get fragment from specified blob.
216+
*
217+
* @param blobKey Blob-key from which to fetch data.
218+
* @param startIndex Start index of data to fetch.
219+
* @param endIndex End index (inclusive) of data to fetch.
220+
* @throws IllegalArgumentException If blob not found, indexes are negative, indexes are inverted
221+
* or fetch size is too large.
222+
* @throws SecurityException If the application does not have access to the blob.
223+
* @throws BlobstoreFailureException If an error occurred while communicating with the blobstore.
224+
*/
225+
byte[] fetchData(BlobKey blobKey, long startIndex, long endIndex);
226+
227+
/**
228+
* Create a {@link BlobKey} for a Google Storage File.
229+
*
230+
* <p>The existence of the file represented by filename is not checked, hence a BlobKey can be
231+
* created for a file that does not currently exist.
232+
*
233+
* <p>You can safely persist the {@link BlobKey} generated by this function.
234+
*
235+
* <p>The created {@link BlobKey} can then be used as a parameter in API methods that can support
236+
* objects in Google Storage, for example {@link serve}.
237+
*
238+
* @param filename The Google Storage filename. The filename must be in the format
239+
* "/gs/bucket_name/object_name".
240+
* @throws IllegalArgumentException If the filename does not have the prefix "/gs/".
241+
*/
242+
BlobKey createGsBlobKey(String filename);
243+
}
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
/*
2+
* Copyright 2021 Google LLC
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* https://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package com.google.appengine.api.blobstore.jakarta;
18+
19+
20+
/** Creates {@link BlobstoreService} implementations for java EE 10. */
21+
public final class BlobstoreServiceFactory {
22+
23+
/** Creates a {@code BlobstoreService} for java EE 10. */
24+
public static BlobstoreService getBlobstoreService() {
25+
return new BlobstoreServiceImpl();
26+
}
27+
28+
}

0 commit comments

Comments
 (0)