Outdated Drivers Are Slowing You Down
One free scan finds every outdated or missing driver and matches the right update for your exact hardware.Free scan · exact hardware matchPC Slower Than It Used to Be?
A free scan shows the junk files, broken settings and background clutter dragging Windows down - then fixes them in one click.Free scan · Windows 10 & 11Generate the PDF first, then upload its bytes to an existing S3 bucket. With AWS SDK for Java 2.x, the simplest and most memory-efficient path when the document is on disk is S3Client.putObject with a Path. If your PDF library produces an InputStream, use RequestBody.fromInputStream with the exact byte length, or choose a transfer/multipart method when the length is unknown or the file is large.
The upload model: PDF generation and S3 storage are separate
A Java PDF library creates output as a file, byte array, InputStream or another stream. Amazon S3 stores that output as an object identified by a bucket and an object key. S3 does not generate the PDF for you, and the AWS SDK does not care which PDF library produced it.
The workflow is therefore:
- Generate the document with the PDF library already used by your application.
- Keep the result as a local
Path/Fileor a stream. - Configure AWS credentials and the bucket’s region through the normal SDK credential chain.
- Choose a bucket and object key, such as
reports/2026/invoice-123.pdf. - Upload and treat the call as successful only after it returns without an exception.
The bucket must already exist, and the caller needs permission to write the chosen key. An object key is an S3 name, not a local filesystem path. Uploading the same key replaces the current object unless your bucket/versioning policy provides another history.
Upload a generated PDF file with AWS SDK for Java 2.x
Use this approach when generation has already written a PDF to disk. The SDK can read the file as it uploads instead of forcing the entire document into a byte array.
The Tool Desk
Outbyte PC Repair FREERepair Windows errors before they cause bigger problemsFix Now →Outbyte Driver Updater FREEScan for outdated or missing drivers - takes under a minuteDriver Scan →Maven dependency
<dependency>
<groupId>software.amazon.awssdk</groupId>
<artifactId>s3</artifactId>
<version>YOUR_AWS_SDK_2_X_VERSION</version>
</dependency>
Keep the SDK version aligned with the rest of your project rather than copying an unrelated version number.
Complete file-upload example
import java.nio.file.Path;
import java.nio.file.Paths;
import software.amazon.awssdk.regions.Region;
import software.amazon.awssdk.services.s3.S3Client;
import software.amazon.awssdk.services.s3.model.PutObjectRequest;
public final class PdfToS3 {
public static void main(String[] args) {
String bucket = System.getenv("S3_BUCKET");
String objectKey = "reports/2026/invoice-123.pdf";
Path pdfPath = Paths.get("/tmp/invoice-123.pdf");
try (S3Client s3 = S3Client.builder()
.region(Region.US_EAST_1)
.build()) {
PutObjectRequest request = PutObjectRequest.builder()
.bucket(bucket)
.key(objectKey)
.contentType("application/pdf")
.build();
s3.putObject(request, pdfPath);
System.out.printf("Uploaded s3://%s/%s%n", bucket, objectKey);
}
}
}
Replace the region with the bucket’s region. The default credential provider chain can use environment variables, the shared AWS profile, workload identity, or an instance/task role. Do not put long-lived access keys in source code. contentType("application/pdf") is useful metadata for browsers and downstream consumers; it is an application choice, not a requirement for S3 to accept the object.
Upload directly from an InputStream
Some generators write to a ByteArrayOutputStream or expose an InputStream without creating a temporary file. SDK 2.x supports this with RequestBody.fromInputStream, but the length must be exact.
import java.io.InputStream;
import software.amazon.awssdk.core.sync.RequestBody;
import software.amazon.awssdk.services.s3.S3Client;
import software.amazon.awssdk.services.s3.model.PutObjectRequest;
public static void uploadPdfStream(
S3Client s3, String bucket, String key,
InputStream pdf, long contentLength) {
if (contentLength < 0) {
throw new IllegalArgumentException("contentLength must be known");
}
PutObjectRequest request = PutObjectRequest.builder()
.bucket(bucket)
.key(key)
.contentType("application/pdf")
.build();
s3.putObject(request,
RequestBody.fromInputStream(pdf, contentLength));
}
Do not guess the length. A value smaller than the real stream can truncate the object; a larger value can make the upload fail or wait for bytes that will never arrive. If your generator returns a byte array, RequestBody.fromBytes(bytes) is straightforward, but it holds the complete PDF in memory.
Free tools Windows power users keep installed
One-click scans. No signup required.
Rank #2
Unknown-length streams and large documents
When the exact length is unavailable, use an SDK-documented ContentStreamProvider strategy or a transfer/multipart approach rather than inventing a number. This is also preferable for very large PDFs because buffering a complete document increases heap pressure. S3 documents a 5 GB maximum for a single-operation SDK, REST API or CLI upload. Multipart upload is documented for objects from 5 MB through 50 TB, so select a multipart/transfer implementation when the file size or retry requirements justify it.
SDK for Java 1.x: different client and method
Do not mix v1 imports with v2 request classes. A v1 application commonly uploads a file as follows:
import com.amazonaws.services.s3.AmazonS3;
public static void uploadV1(AmazonS3 s3, String bucket,
String key, java.io.File pdfFile) {
s3.putObject(bucket, key, pdfFile);
}
SDK v1 uses AmazonS3 and the overloaded putObject methods; SDK 2.x uses S3Client, PutObjectRequest and a request body or Path. Follow the generation already used by your project unless you are deliberately migrating.
Choosing file, bytes or stream
| PDF representation | Best fit | Memory and correctness notes |
|---|---|---|
Path with SDK 2.x |
PDF already saved on disk | Direct code path; avoids loading the whole file into memory. |
| Byte array | Small document already in memory | Simple, but heap usage grows with document size. |
InputStream with known length |
Generator emits a stream and can report exact bytes | Use fromInputStream; an incorrect length can truncate, fail or hang. |
| Unknown-length stream or very large file | Streaming generation, large reports, or stronger retry behavior | Use a documented content provider or multipart/transfer strategy instead of guessing. |
SDK v1 File |
Existing v1 codebase | Use the v1 AmazonS3 API; do not combine it with v2 classes. |
Keys, replacement and verification
Design a stable key
Use a predictable prefix and identifier, for example reports/2026/invoice-123.pdf. Reusing a key gives consumers a stable URL but replaces the object. If every revision must remain available, include a version or unique ID in the key, or rely on bucket versioning configured by your administrator.
Verify after the call
Print or record the bucket and key returned by your application only after putObject completes. For higher-assurance workflows, issue a normal metadata check through the SDK and verify content length and content type. A successful request means S3 accepted the object; application-level checks can confirm that the expected key and size are present.
Security and operational choices
- Grant the runtime identity only the write permissions it needs, ideally scoped to a bucket prefix rather than every bucket.
- Keep the bucket private unless public delivery is an explicit requirement. Generate controlled download access through your application’s normal mechanism.
- New uploads use SSE-S3 by default according to S3 documentation. Configure SSE-KMS when your policy requires a customer-managed key, and grant the caller permission to use that key.
- Treat invoice and report PDFs as sensitive data: avoid logging document contents, credentials or signed URLs.
- Choose timeouts and retry behavior appropriate to document size and network conditions. Multipart transfer can recover individual parts instead of restarting a very large single request.
Troubleshooting common failures
Access denied
Confirm the credentials in the running environment, the bucket policy, the identity’s write permission for the exact key prefix, and (for SSE-KMS) permission to use the KMS key. Also verify that you are targeting the intended account and region.
NoSuchBucket or a region error
Check the bucket name character-for-character and configure the client for the bucket’s actual region. A bucket must exist before putObject can succeed.
Object is truncated or the request hangs
This usually indicates an incorrect stream length. Measure the exact byte count, or switch to a content provider or multipart strategy that handles the stream correctly.
Rank #4
Out-of-memory during generation
A byte-array approach retains the whole PDF. Generate to a temporary file and use the Path overload, or stream through a transfer strategy designed for large content. Delete temporary files after a confirmed upload.
PDF downloads with the wrong content type
Set contentType("application/pdf") on the request and verify the stored metadata. This metadata affects browser behavior but does not repair invalid PDF bytes.
Upload succeeds but the application reports failure
Do not mark the job failed because a later notification or database update failed. Record the S3 key separately, make post-upload updates idempotent, and use a metadata check when your workflow requires confirmation.
Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Or skip the browser setup
If your workflow also needs screenshots of a generated report or a web page, ScreenshotNeo provides a one-call website screenshot API. It is separate from S3 and PDF generation, but can remove browser automation from that part of a pipeline.
Recommended Free Tools
Best Value
curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://stripe.com -o shot.webp
See the ScreenshotNeo documentation for all request options. Cookie banners, newsletter popups and chat widgets are removed before the shot; bot checks, blank pages and failed loads are never billed. An MCP server lets AI agents use screenshots, page information and PDF capture tools. The Free plan includes 1,000 screenshots each month with no card, and paid plans start at $5 for 3,000. Create a free ScreenshotNeo account.
Practical checklist
- PDF generation completed and produced valid bytes.
- Bucket exists in the configured region.
- Runtime credentials can write the target key.
- Object key replacement or versioning behavior is intentional.
- File, byte array or stream method matches the document size.
- Stream length is exact when using
fromInputStream. - Content type and encryption settings match application policy.
- Success is recorded only after the SDK call returns.
Frequently Asked Questions
Can I upload a PDF without saving it locally?
Yes. Pass the generator’s InputStream to AWS SDK 2.x with RequestBody.fromInputStream and the exact content length, or use a suitable content-provider or multipart strategy when the length is unknown.
Will uploading the same S3 key create a second PDF?
Normally it replaces the current object at that key. Use a unique key or bucket versioning when older revisions must remain available.
Which Java SDK should a new implementation use?
Use the AWS SDK generation already standardized by your project. The v1 AmazonS3 API and v2 S3Client/PutObjectRequest API are not interchangeable.
Quick Recap
Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.

