What is the Correct Approach for Uploading Files to Google App Engine Blobstore Without a Browser?

I'm working on a file upload feature in a Java web application running on Google App Engine (GAE). The application uses the Blobstore API for handling file uploads. However, when trying to upload a file, I'm encountering a `NullPointerException` (NPE) that I'm unable to debug due to the lack of source code for the `com.google.appengine.api.blobstore.dev.UploadBlobServlet` class in the 'appengine-api-stubs' version 1.9.88.

**Error Message:**
```
java.lang.NullPointerException
at com.google.appengine.api.blobstore.dev.UploadBlobServlet.handleUpload(UploadBlobServlet.java:432)
```

The NPE points to line 432 in `UploadBlobServlet`, since I don't have access to the exact source code, I'm deducing this based on the overall structure of the servlet.

**Relevant Code Snippets:**

This line 432 from https://github.com/GoogleCloudPlatform/appengine-java-standard/blob/8380dd6b475a49b45112e6c4a20acbb9... suggest this code block:


*Upload Servlet Method Snippet:*
```java
public final class UploadBlobServlet extends HttpServlet {
@Override
public Enumeration<String> getParameterNames() {
List<String> allNames = new ArrayList<>();
Enumeration<String> names = super.getParameterNames();
while (names.hasMoreElements()) {
allNames.add(names.nextElement());
}
// Additional code for handling other parameters
return Collections.enumeration(allNames);
}
}
```

Although this seems counter-intuitive since the method that is throwing should be `handleUpload`

*File Upload Client Code:*
```java
public class FileUploader {
public String getUploadUrl(String callbackPath) throws URISyntaxException, IOException {
// Setup Remote API
BlobstoreService blobstoreService = BlobstoreServiceFactory.getBlobstoreService();
String uploadUrl = blobstoreService.createUploadUrl(callbackPath);
return uploadUrl;
}

public String uploadFile(String url, String partName, String filename, String mimeType, byte[] contents) throws IOException {
try (CloseableHttpClient httpClient = HttpClients.createDefault()) {
HttpPost post = new HttpPost(url);
MultipartEntityBuilder builder = MultipartEntityBuilder.create();
ByteArrayBody contentBody = new ByteArrayBody(contents, ContentType.create(mimeType), filename);
builder.addPart(partName, contentBody);
post.setEntity(builder.build());
HttpResponse response = httpClient.execute(post);
return EntityUtils.toString(response.getEntity());
}
}
}
```

*Test Method:*
```java
@Test
public void shouldBeAbleToUpload) throws Exception {
FileUploader fileUploader = new FileUploader();
String uploadUrl = fileUploader.getUploadUrl("path/to/some/blob");
InputStream sample = getClass().getResourceAsStream("/100mb.bin");
byte[] fileContent = readFileToByteArray(sample);
fileUploader.uploadFile(uploadUrl, "file", "sample.html", "application/octet-stream", fileContent);
}
```

**Main Issue:**
The main issue is the NPE during the file upload process. I suspect the issue might be related to how parameters are handled or possibly an incorrect setup in my upload logic. However, without access to the source code for `UploadBlobServlet`, I'm at a loss for how to proceed with debugging.

**Questions:**
1. Has anyone encountered a similar issue with file uploads to GAE Blobstore and can provide insight into what might be going wrong?
2. Are there known issues with the `UploadBlobServlet` handling multipart form data that could lead to an NPE?
3. Any suggestions on how to debug or workaround this problem, especially considering the lack of source code for the servlet?

I've confirmed that the upload URL generated is correct and accessible, and the application is running on the local development server provided by GAE.

Any help or guidance would be greatly appreciated. Thank you!

4 1 95
1 REPLY 1

Hi @kerbymart,

Welcome to Google Cloud Community!

It seems that this Stack Overflow link has the same question and you managed to resolved it.

Reposting your answer here in Google Cloud Community:

The NPE error is thrown by the UploadBlobServlet if the callback URL doesn't have a forward slash "/". To avoid this error, ensure that the callback URL has a forward slash.

This will throw:

String uploadUrl = fileUploader.getUploadUrl("callback");

And this will not:

String uploadUrl = fileUploader.getUploadUrl("/callback");

Hope other members will find this helpful.