Pushy for Java APNs Notifications
A Java library for sending APNs (iOS/macOS/Safari) push notifications
At a glance
- What is it?
- Pushy is a Java library for sending APNs push notifications to iOS, macOS, and Safari applications. It supports TLS and token authentication, asynchronous operation, and pooled HTTP/2 connections.
- Who is it for?
- Pushy fits Java services that need an asynchronous APNs client, parallel connections, and a choice between TLS and token authentication. It does not fit a developer who only wants a graphical notification tester, and it cannot remove Apple's app registration or authentication requirements.
- Can I use it commercially?
- Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
- Is it still maintained?
- Yes. The repository last received commits 22 days ago.
- What is it written in?
- Mainly Java, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on October 23, 2026, and from our analysis. They are not legal advice.
Editorial analysis
Pushy's APNs Scope and Intended Java Users
Pushy solves the problem of sending remote push notifications from a Java application to iOS, macOS, and Safari destinations. It is a library, not a desktop application for composing test notifications, and it does not register an app or create Apple credentials. The intended users are developers building server-side notification services, particularly services that deliver notifications for multiple receiving applications.
The library communicates with Apple's HTTP/2-based APNs protocol and supports TLS-based and token-based authentication. The README also describes asynchronous operation and the ability to maintain multiple parallel connections to the APNs gateway. Those characteristics place it closer to a server integration library than to a simple demonstration client. A caller is still responsible for obtaining Apple credentials, identifying each destination device, selecting the correct application topic, and constructing a valid APNs payload.
The README uses `com.example.myApp` as an example topic. A topic identifies the receiving application, while a device token identifies the destination device. Neither should be confused with the signed token used for token-based authentication. These separate identifiers are an easy source of configuration errors. Pushy handles the protocol client, but the calling application must supply accurate application and device data.
Pushy's Pooled Connections and Notification Flow
An `ApnsClient` maintains an internal pool of connections to APNs and creates new connections when needed. The README explicitly states that a client does not need to be started before use. Once the client has been built with an APNs server and valid credentials, the application can begin constructing and sending notifications.
The configuration and message layers are separate. `ApnsClientBuilder` selects an APNs environment and supplies either client credentials or a signing key. `SimpleApnsPushNotification` then receives three core values: a sanitized device token, an application topic, and a JSON payload. This separation allows the payload construction method to remain under the caller's control.
Pushy includes `ApnsPayloadBuilder` for common payload assembly, including an alert body, but the builder is optional. APNs payloads are JSON strings, and callers may construct them by another method. That flexibility is useful when an application needs fields that a higher-level builder does not expose, but it also makes validation the caller's responsibility. The README ends its displayed sending-process section before showing the complete result-handling API, so this review does not invent a future, callback, or timeout example.
Maven Installation and TLS Client Setup
The README specifies Java 8 or newer and Maven dependency coordinates for Pushy 0.15.6. Add the library to the project `pom.xml` with the declaration below. This version matches the newest release listed in the repository facts, while newer patch releases should be checked against Maven Central before an upgrade.
<dependency>
<groupId>com.eatthepath</groupId>
<artifactId>pushy</artifactId>
<version>0.15.6</version>
</dependency>For the first TLS-authenticated client, replace the example certificate path and password with provisioned values. `DEVELOPMENT_APNS_HOST` selects Apple's development environment, so this example is not configured for production APNs.
final ApnsClient apnsClient = new ApnsClientBuilder()
.setApnsServer(ApnsClientBuilder.DEVELOPMENT_APNS_HOST)
.setClientCredentials(new File("/path/to/certificate.p12"), "p12-file-password")
.build();Pushy requires both a certificate and its private key. The README says PKCS#12 files are common and password-protected files may result from following Apple's provisioning instructions. A certificate commonly permits sending only to the topic named in it, which makes TLS clients a poor fit for one shared client spanning many unrelated applications unless the application organizes credentials accordingly.
Token Authentication with an Apple Signing Key
Token authentication still uses a TLS-protected connection, but it does not present an APNs certificate. Instead, each notification carries a cryptographically signed token. Pushy generates that token automatically once the builder receives the signing key and its identifiers.
Apple provides the required `.p8` signing key. `ApnsSigningKey.loadFromPkcs8File` reads that file, while the `TEAMID1234` and `KEYID67890` values identify the team and key in this documentation example. These placeholders must be replaced with values associated with the actual Apple account.
final ApnsClient apnsClient = new ApnsClientBuilder()
.setApnsServer(ApnsClientBuilder.DEVELOPMENT_APNS_HOST)
.setSigningKey(ApnsSigningKey.loadFromPkcs8File(new File("/path/to/key.p8"),
"TEAMID1234", "KEYID67890"))
.build();TLS authentication and token authentication cannot be combined in the same client configuration. The choice affects credential storage, the topics a client can use, and how each request is authorized. Pushy removes the need to implement token signing, but the application remains responsible for protecting the `.p8` file and keeping the team and key identifiers correct. The README does not document key rotation procedures or a dedicated credential refresh API, so an operator should consult the API documentation before designing that part of a production service.
Building and Sending the First APNs Payload
A basic Pushy notification needs a destination device token, an application topic, and an APNs JSON payload. `TokenUtil.sanitizeTokenString` removes formatting from the token string used in the example. The builder creates an alert body, serializes the payload, and the notification object receives that JSON alongside the destination data.
final SimpleApnsPushNotification pushNotification;
{
final ApnsPayloadBuilder payloadBuilder = new ApnsPayloadBuilder();
payloadBuilder.setAlertBody("Example!");
final String payload = payloadBuilder.build();
final String token = TokenUtil.sanitizeTokenString("<efc7492 bdbd8209>");
pushNotification = new SimpleApnsPushNotification(token, "com.example.myApp", payload);
}This establishes the message but does not show the complete send call because the displayed README ends at the beginning of the sending-process section. For a real first use, Java compilation should resolve the documented Pushy classes, the server should point to the intended APNs environment, and the notification should carry a token belonging to that environment and topic. A successful JSON build only confirms local payload construction. It does not confirm that Apple accepts the destination, credentials, or notification content.
The example is intentionally small. Production services may need device registration storage, topic selection, payload versioning, response handling, and backoff policies. The repository includes separate `dropwizard-metrics-listener` and `micrometer-metrics-listener` modules, but the README does not show their configuration. Their presence indicates optional metrics integrations, not a documented requirement for the basic client.
netty-tcnative Performance and Platform Trade-offs
Pushy does not require a native SSL provider, but the README says users may add `netty-tcnative-boringssl-static` for enhanced performance. It is a runtime dependency rather than a required installation step.
<dependency>
<groupId>io.netty</groupId>
<artifactId>netty-tcnative-boringssl-static</artifactId>
<version>2.0.77.Final</version>
<scope>runtime</scope>
</dependency>The README describes potential performance benefits but gives no benchmark figures or platform compatibility matrix for this provider. Consequently, adopting it solely because the documentation calls it faster would be unsupported. The concrete cost is an extra native dependency that must be compatible with the deployment runtime and the Netty components resolved by the application.
Pushy is also the wrong tool when the requirement is a GUI for manually sending development notifications. The README points that use case to Pushy Console, a separate sister project. Choosing Pushy means integrating protocol behavior into Java code. A team without a server component or without the Apple credentials required by APNs cannot use the library as a complete provisioning solution.
Pushy's Maintenance Signals and MIT Dependency Costs
The repository is not archived, and its last push was on 2026-10-01. Pushy 0.15.6 was released on 2026-05-24 with dependency updates, while 0.15.4 added `attributes-type` and `start` fields for Live Activities payloads. Those release entries and the recent push provide maintenance signals, although they do not guarantee compatibility with every future Apple protocol change.
The project uses the MIT license. That means the repository grants use, modification, distribution, and sublicensing under the license's conditions and includes its warranty and liability text. This is not legal advice. An adopting organization still needs to review the actual `LICENSE.md`, dependency licenses, notices, and its own distribution obligations. Pushy brings transitive runtime dependencies through its Maven build, so the license review is wider than the top-level project file.
Upgrading from an older Pushy version also requires checking the release-specific API and transitive dependency changes. The 0.15.6 release is described only as dependency updates, with no migration note in the repository release entry. The repository's Maven wrapper files, including `mvnw` and `mvnw.cmd`, indicate a Maven-based build, but the README does not document an exact wrapper invocation for running the full project.
Editorial conclusion
Pushy fits Java services that need an asynchronous APNs client, parallel connections, and a choice between TLS and token authentication. It does not fit a developer who only wants a graphical notification tester, and it cannot remove Apple's app registration or authentication requirements. Before the first send, verify the Java runtime version, APNs environment, credential type, application topic, device token, JSON payload, and handling of APNs responses. For production use, also confirm that the selected `pushy` version remains compatible with the rest of the application dependency graph.
Frequently asked questions
What is Pushy used for in a Java application?
Pushy sends APNs push notifications to iOS, macOS, and Safari destinations. It handles HTTP/2-based APNs communication, connection pooling, and the two documented authentication methods.
How do I install Pushy with Maven?
Add `com.eatthepath:pushy` version `0.15.6` to the Maven project dependencies and run it with Java 8 or newer. The project also offers `netty-tcnative-boringssl-static` as an optional runtime SSL provider.
Should a Pushy client use TLS authentication or token authentication?
The methods are mutually exclusive. TLS authentication presents a certificate and private key, while token authentication loads an Apple `.p8` signing key with a team identifier and key identifier.
Does Pushy provide a graphical tool for testing notifications?
No. Pushy is a Java library. The README points developers who need a simple GUI for development notifications to the separate Pushy Console project.
Can Pushy build APNs payloads for me?
Pushy includes `ApnsPayloadBuilder`, which can create common JSON payloads such as alert notifications. Callers may use another method because the builder is optional and APNs payloads are JSON strings.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/jchambers-pushy)Was this useful?