mirror of
https://github.com/BillyOutlast/posthog.com.git
synced 2026-02-06 12:21:21 +01:00
Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com>
238 lines
8.3 KiB
Plaintext
238 lines
8.3 KiB
Plaintext
---
|
||
title: Java
|
||
sidebarTitle: Java
|
||
sidebar: Docs
|
||
showTitle: true
|
||
github: 'https://github.com/PostHog/posthog-android'
|
||
icon: >-
|
||
https://res.cloudinary.com/dmukukwp6/image/upload/posthog.com/contents/images/docs/integrate/java.svg
|
||
features:
|
||
eventCapture: true
|
||
userIdentification: true
|
||
featureFlags: true
|
||
groupAnalytics: true
|
||
surveys: false
|
||
llmAnalytics: false
|
||
---
|
||
|
||
This is an optional library you can install if you're working with server-side Java applications. It uses an internal queue to make calls fast and non-blocking. It also batches requests and flushes asynchronously, making it perfect to use in any part of your web app or other server side application that needs performance.
|
||
|
||
## Installation
|
||
|
||
import JavaInstall from '../../integrate/_snippets/install-java.mdx'
|
||
|
||
<JavaInstall />
|
||
|
||
|
||
## Capturing events
|
||
|
||
import JavaSendEvents from '../../integrate/send-events/_snippets/send-events-java.mdx'
|
||
|
||
<JavaSendEvents />
|
||
|
||
## Person profiles and properties
|
||
|
||
The Java SDK captures identified events by default. These create [person profiles](/docs/data/persons). To set [person properties](/docs/data/user-properties) in these profiles, include them when capturing an event:
|
||
|
||
```java
|
||
postHog.capture(
|
||
"distinct_id_of_the_user",
|
||
"event_name",
|
||
PostHogCaptureOptions
|
||
.builder()
|
||
.userProperty("name", "Max Hedgehog")
|
||
.userPropertySetOnce("initial_url", "/blog")
|
||
.build()
|
||
);
|
||
```
|
||
|
||
For more details on the difference between `$set` and `$set_once`, see our [person properties docs](/docs/data/user-properties#what-is-the-difference-between-set-and-set_once).
|
||
|
||
To capture [anonymous events](/docs/data/anonymous-vs-identified-events) without person profiles, set the event's `$process_person_profile` property to `false`:
|
||
|
||
```java
|
||
postHog.capture(
|
||
"distinct_id_of_the_user",
|
||
"event_name",
|
||
PostHogCaptureOptions
|
||
.builder()
|
||
.property("$process_person_profile", false)
|
||
.build()
|
||
);
|
||
```
|
||
|
||
## Alias
|
||
|
||
Sometimes, you want to assign multiple distinct IDs to a single user. This is helpful when your primary distinct ID is inaccessible. For example, if a distinct ID used on the frontend is not available in your backend.
|
||
|
||
In this case, you can use `alias` to assign another distinct ID to the same user.
|
||
|
||
```java
|
||
postHog.alias("distinct_id", "alias_id");
|
||
```
|
||
|
||
We strongly recommend reading our docs on [alias](/docs/data/identify#alias-assigning-multiple-distinct-ids-to-the-same-user) to best understand how to correctly use this method.
|
||
|
||
## Group analytics
|
||
|
||
Group analytics allows you to associate an event with a group (e.g. teams, organizations, etc.). Read the [group analytics](/docs/product-analytics/group-analytics) guide for more information.
|
||
|
||
> **Note:** This is a paid feature and is not available on the open-source or free cloud plan. Learn more on our [pricing page](/pricing).
|
||
|
||
To create a group, use the `group` method. This associates a user with a group and optionally sets properties on the group:
|
||
|
||
```java
|
||
postHog.group(
|
||
"user_distinct_id",
|
||
"company",
|
||
"company_id_in_your_db",
|
||
Map.of(
|
||
"name", "Acme Corporation",
|
||
"industry", "Technology",
|
||
"employee_count", 500
|
||
)
|
||
);
|
||
```
|
||
|
||
You can also create a group without setting properties:
|
||
|
||
```java
|
||
postHog.group("user_distinct_id", "organization", "org_123");
|
||
```
|
||
|
||
To associate an event with a group, include the group information when capturing the event:
|
||
|
||
```java
|
||
postHog.capture(
|
||
"user_distinct_id",
|
||
"some_event",
|
||
PostHogCaptureOptions
|
||
.builder()
|
||
.group("company", "company_id_in_your_db")
|
||
.build()
|
||
);
|
||
```
|
||
|
||
## Feature flags
|
||
|
||
import FeatureFlagsLibsIntro from "../_snippets/feature-flags-libs-intro.mdx"
|
||
|
||
<FeatureFlagsLibsIntro />
|
||
|
||
### Boolean feature flags
|
||
|
||
```java
|
||
boolean isEnabled = postHog.isFeatureEnabled("user_distinct_id", "use_optimized_query", false);
|
||
if (isEnabled) {
|
||
// Do something differently for this user
|
||
}
|
||
```
|
||
|
||
### Multivariate feature flags
|
||
|
||
```java
|
||
Object flagValue = postHog.getFeatureFlag("user_distinct_id", "recommendation_algorithm", "control");
|
||
String algorithm = flagValue instanceof String ? (String) flagValue : "control";
|
||
switch (algorithm) {
|
||
case "collaborative_filtering":
|
||
useCollaborativeFiltering();
|
||
break;
|
||
case "neural_network":
|
||
useNeuralNetwork();
|
||
break;
|
||
default:
|
||
useControlAlgorithm();
|
||
}
|
||
```
|
||
|
||
### Feature flag payloads
|
||
|
||
```java
|
||
Object payload = postHog.getFeatureFlagPayload("user_distinct_id", "recommendation_algorithm");
|
||
if (payload instanceof Map) {
|
||
Map<String, Object> config = (Map<String, Object>) payload;
|
||
String modelVersion = config.get("model_version") instanceof String
|
||
? (String) config.get("model_version") : "v1.0";
|
||
boolean enableFallback = config.get("enable_fallback") instanceof Boolean
|
||
? (Boolean) config.get("enable_fallback") : true;
|
||
}
|
||
```
|
||
|
||
### Sending `$feature_flag_called` events
|
||
|
||
Capturing `$feature_flag_called` events enable PostHog to know when a flag was accessed by a user and thus provide [analytics and insights](/docs/product-analytics/insights) on the flag. By default, we send these events when:
|
||
|
||
1. You call `postHog.getFeatureFlag()` or `postHog.isFeatureEnabled()`, AND
|
||
2. It's a new user, or the value of the flag has changed.
|
||
|
||
> *Note:* Tracking whether it's a new user or if a flag value has changed happens in a local cache. This means that if you reinitialize the PostHog client, the cache resets as well – causing `$feature_flag_called` events to be sent again when calling `getFeatureFlag` or `isFeatureEnabled`. PostHog is built to handle this, and so duplicate `$feature_flag_called` events won't affect your analytics.
|
||
|
||
You can control the automatic capture of `$feature_flag_called` events using the `sendFeatureFlagEvent` configuration option when initializing PostHog:
|
||
|
||
```java
|
||
PostHogConfig config = PostHogConfig
|
||
.builder(POSTHOG_API_KEY)
|
||
.host(POSTHOG_HOST)
|
||
.sendFeatureFlagEvent(false) // Disable automatic feature flag events
|
||
.build();
|
||
```
|
||
|
||
### Local evaluation
|
||
|
||
While planned, local evaluation of feature flags is not yet supported in the Java SDK. All feature flag evaluations occur remotely via the PostHog API.
|
||
|
||
### Feature flag caching
|
||
|
||
To improve performance and reduce API calls, the Java SDK caches feature flag results in memory. You can configure the cache behavior when initializing PostHog:
|
||
|
||
```java
|
||
PostHogConfig config = PostHogConfig
|
||
.builder(POSTHOG_API_KEY)
|
||
.featureFlagCacheSize(1000) // Maximum number of cached flag results (default: 1000)
|
||
.featureFlagCacheMaxAgeMs(300000) // Cache expiry in milliseconds (default: 300000 = 5 minutes)
|
||
.build();
|
||
```
|
||
|
||
**Configuration options:**
|
||
|
||
- `featureFlagCacheSize`: The maximum number of feature flag results to cache in memory (default: `1000`)
|
||
- `featureFlagCacheMaxAgeMs`: The maximum age of a cached feature flag result in milliseconds (default: `300000` or 5 minutes)
|
||
|
||
Cached results are stored per distinct ID and flag key combination. When a cached result expires or the cache is full, the SDK will fetch fresh results from the PostHog API.
|
||
|
||
## Experiments (A/B tests)
|
||
|
||
Since [experiments](/docs/experiments/manual) use feature flags, the code for running an experiment is very similar to the feature flags code:
|
||
|
||
```java
|
||
Object flagValue = postHog.getFeatureFlag("user_distinct_id", "recommendation_algorithm", "control");
|
||
String variant = flagValue instanceof String ? (String) flagValue : "control";
|
||
if (variant.equals("neural_network")) {
|
||
// Do something differently for this user
|
||
}
|
||
```
|
||
|
||
It's also possible to [run experiments without using feature flags](/docs/experiments/running-experiments-without-feature-flags).
|
||
|
||
## GeoIP properties
|
||
|
||
The `posthog-server` library disregards the server IP, does not add the GeoIP properties, and does not use the values for feature flag evaluations.
|
||
|
||
## Serverless environments
|
||
|
||
By default, the library buffers events before sending them to the `/batch` endpoint for better performance. This can lead to lost events in serverless environments if the Java process is terminated by the platform before the buffer is fully flushed.
|
||
|
||
To avoid this, call `postHog.flush()` after processing every request. This allows `postHog.capture()` to remain asynchronous for better performance.
|
||
|
||
```java
|
||
postHog.flush();
|
||
```
|
||
|
||
## Shutdown
|
||
|
||
When you're done using PostHog, make sure to call `close()` to ensure all events are flushed before your application exits:
|
||
|
||
```java
|
||
postHog.close();
|
||
```
|