Java SDK integrations
DVARA is an AI governance platform with an OpenAI-compatible data plane. The official OpenAI Java SDK, Spring AI, and LangChain4j all accept a custom base URL, so adding governance to an existing Java service is a single config change. Examples assume DVARA is running at http://localhost:8080 and you've created a tenant + API key via the Quickstart.
OpenAI Java SDK
The official OpenAI Java SDK exposes a .baseUrl() builder — same contract as the Python and JavaScript SDKs.
Maven dependency:
<dependency>
<groupId>com.openai</groupId>
<artifactId>openai-java</artifactId>
<version>0.31.0</version>
</dependency>
Basic chat:
import com.openai.client.OpenAIClient;
import com.openai.client.okhttp.OpenAIOkHttpClient;
import com.openai.models.ChatModel;
import com.openai.models.chat.completions.ChatCompletion;
import com.openai.models.chat.completions.ChatCompletionCreateParams;
OpenAIClient client = OpenAIOkHttpClient.builder()
.baseUrl("http://localhost:8080/v1")
.apiKey("your-dvara-api-key")
.build();
ChatCompletionCreateParams params = ChatCompletionCreateParams.builder()
.model(ChatModel.GPT_4O)
.addUserMessage("Explain microservices in one paragraph.")
.build();
ChatCompletion completion = client.chat().completions().create(params);
completion.choices().forEach(c -> System.out.println(c.message().content().orElse("")));
Streaming:
import com.openai.core.http.StreamResponse;
import com.openai.models.chat.completions.ChatCompletionChunk;
try (StreamResponse<ChatCompletionChunk> stream =
client.chat().completions().createStreaming(
ChatCompletionCreateParams.builder()
.model(ChatModel.GPT_4O)
.addUserMessage("Write a haiku about Java.")
.build())) {
stream.stream()
.flatMap(chunk -> chunk.choices().stream())
.flatMap(choice -> choice.delta().content().stream())
.forEach(System.out::print);
}
Structured output (JSON schema):
import com.openai.core.JsonValue;
import com.openai.models.ResponseFormatJsonSchema;
ChatCompletionCreateParams params = ChatCompletionCreateParams.builder()
.model(ChatModel.GPT_4O)
.addUserMessage("List 3 planets with their diameter in km.")
.responseFormat(ResponseFormatJsonSchema.builder()
.jsonSchema(ResponseFormatJsonSchema.JsonSchema.builder()
.name("planets")
.strict(true)
.schema(JsonValue.from(Map.of(
"type", "object",
"properties", Map.of(
"planets", Map.of(
"type", "array",
"items", Map.of(
"type", "object",
"properties", Map.of(
"name", Map.of("type", "string"),
"diameter_km", Map.of("type", "integer")),
"required", List.of("name", "diameter_km"))))
, "required", List.of("planets"))))
.build())
.build())
.build();
ChatCompletion completion = client.chat().completions().create(params);
Using Claude / Gemini via DVARA (same SDK):
// No SDK change — DVARA translates to the upstream provider based on the model name.
ChatCompletionCreateParams claudeParams = ChatCompletionCreateParams.builder()
.model("claude-sonnet-4-20250514")
.addUserMessage("Hello from the OpenAI Java SDK via DVARA!")
.build();
ChatCompletion claudeResponse = client.chat().completions().create(claudeParams);
ChatCompletionCreateParams geminiParams = ChatCompletionCreateParams.builder()
.model("gemini-2.0-flash")
.addUserMessage("Hello from Gemini via DVARA!")
.build();
ChatCompletion geminiResponse = client.chat().completions().create(geminiParams);
Environment variable approach:
export OPENAI_BASE_URL="http://localhost:8080/v1"
export OPENAI_API_KEY="your-dvara-api-key"
// fromEnv() reads OPENAI_BASE_URL and OPENAI_API_KEY.
OpenAIClient client = OpenAIOkHttpClient.fromEnv();
LangChain4j
Maven dependency:
<dependency>
<groupId>dev.langchain4j</groupId>
<artifactId>langchain4j-open-ai</artifactId>
<version>1.0.0-beta1</version>
</dependency>
Basic chat:
import dev.langchain4j.model.openai.OpenAiChatModel;
OpenAiChatModel model = OpenAiChatModel.builder()
.baseUrl("http://localhost:8080/v1")
.apiKey("your-dvara-api-key")
.modelName("gpt-4o")
.build();
String response = model.chat("What is the capital of Germany?");
System.out.println(response);
Streaming:
import dev.langchain4j.model.openai.OpenAiStreamingChatModel;
import dev.langchain4j.model.chat.response.StreamingChatResponseHandler;
OpenAiStreamingChatModel model = OpenAiStreamingChatModel.builder()
.baseUrl("http://localhost:8080/v1")
.apiKey("your-dvara-api-key")
.modelName("gpt-4o")
.build();
model.chat("Write a haiku about Java.", new StreamingChatResponseHandler() {
@Override
public void onPartialResponse(String partialResponse) {
System.out.print(partialResponse);
}
@Override
public void onCompleteResponse(String completeResponse) {
System.out.println("\n--- Done ---");
}
@Override
public void onError(Throwable error) {
error.printStackTrace();
}
});
With AI Services (structured output):
import dev.langchain4j.service.AiServices;
interface MovieExpert {
@dev.langchain4j.service.UserMessage("Review the movie: {{movie}}")
MovieReview review(@dev.langchain4j.service.V("movie") String movie);
}
record MovieReview(String title, double rating, String summary) {}
OpenAiChatModel model = OpenAiChatModel.builder()
.baseUrl("http://localhost:8080/v1")
.apiKey("your-dvara-api-key")
.modelName("gpt-4o")
.responseFormat("json")
.build();
MovieExpert expert = AiServices.create(MovieExpert.class, model);
MovieReview review = expert.review("Inception");
System.out.printf("%s: %.1f/10 - %s%n", review.title(), review.rating(), review.summary());
Using Claude via DVARA:
OpenAiChatModel claude = OpenAiChatModel.builder()
.baseUrl("http://localhost:8080/v1")
.apiKey("your-dvara-api-key")
.modelName("claude-sonnet-4-20250514")
.build();
String response = claude.chat("Hello from LangChain4j via DVARA!");
Spring AI
Spring AI has native OpenAI support with a configurable base URL.
Maven dependency:
<dependency>
<groupId>org.springframework.ai</groupId>
<artifactId>spring-ai-openai-spring-boot-starter</artifactId>
</dependency>
application.yml:
spring:
ai:
openai:
base-url: http://localhost:8080/v1
api-key: ${DVARA_API_KEY:your-dvara-api-key}
chat:
options:
model: gpt-4o
temperature: 0.7
Service class:
import org.springframework.ai.chat.client.ChatClient;
import org.springframework.stereotype.Service;
import reactor.core.publisher.Flux;
@Service
public class ChatService {
private final ChatClient chatClient;
public ChatService(ChatClient.Builder builder) {
this.chatClient = builder.build();
}
public String chat(String message) {
return chatClient.prompt()
.user(message)
.call()
.content();
}
// Streaming
public Flux<String> streamChat(String message) {
return chatClient.prompt()
.user(message)
.stream()
.content();
}
}
Structured output:
record CityInfo(String name, String country, int population, List<String> landmarks) {}
CityInfo city = chatClient.prompt()
.user("Tell me about Paris")
.call()
.entity(CityInfo.class);
System.out.printf("%s, %s — pop: %,d%n", city.name(), city.country(), city.population());
Switch models at runtime:
// Use GPT-4o
String gptResponse = chatClient.prompt()
.user("Hello!")
.options(OpenAiChatOptions.builder().model("gpt-4o").build())
.call()
.content();
// Use Claude — same client, different model
String claudeResponse = chatClient.prompt()
.user("Hello!")
.options(OpenAiChatOptions.builder().model("claude-sonnet-4-20250514").build())
.call()
.content();
Function calling:
@Bean
@Description("Get the current weather for a location")
public Function<WeatherRequest, WeatherResponse> getWeather() {
return request -> new WeatherResponse(request.city(), 22.5, "Sunny");
}
record WeatherRequest(String city) {}
record WeatherResponse(String city, double temperature, String condition) {}
String response = chatClient.prompt()
.user("What's the weather in Tokyo?")
.functions("getWeather")
.call()
.content();
Next steps
- Looking for other languages? See Python or JavaScript / TypeScript.
- Routing additional OpenAI-compatible providers? See Additional providers.
- Need distributed tracing across SDKs? See DVARA headers.