Maven Quick Start
A complete pom.xml that compiles and runs a first call from Java, with llm4s-java-api.
Table of contents
- Before you start
- The coordinate
- The pom.xml
- The code and the configuration
- Run it
- If something goes wrong
- Next steps
The project is in
modules/samples/maven-java, and CI compiles
it against the library on every pull request. For Gradle, see Gradle Integration; for the Java API itself,
the Java guide.
Before you start
- JDK 21 or newer and Maven 3.9 or newer.
llm4s-java-apiis JDK 21 bytecode, so the project setsmaven.compiler.releaseto 21. - An API key for OpenAI, or a local Ollama (no key).
The coordinate
LLM4S is published for Scala 3 only, and Maven does not add the Scala cross-version suffix: the artifact is
org.llm4s:llm4s-java-api_3, and you write the _3 yourself. Its POM brings llm4s-core, llm4s-agent and the
provider modules, so it is the one llm4s dependency a Java project needs.
The pom.xml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0">
<modelVersion>4.0.0</modelVersion>
<groupId>org.llm4s.samples</groupId>
<artifactId>llm4s-maven-sample</artifactId>
<version>1</version>
<properties>
<maven.compiler.release>21</maven.compiler.release>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<llm4s.version>0.5.1</llm4s.version>
<scala3.version>3.7.1</scala3.version>
</properties>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.scala-lang</groupId>
<artifactId>scala3-library_3</artifactId>
<version>${scala3.version}</version>
</dependency>
<!-- The OpenAI and Anthropic SDKs, pureconfig and the llm4s modules ask for different versions of these;
dependencyConvergence fails until each is pinned. Pin the newest version any of them asks for. -->
<dependency>
<groupId>com.fasterxml.jackson</groupId>
<artifactId>jackson-bom</artifactId>
<version>2.19.4</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<dependency>
<groupId>org.jetbrains.kotlin</groupId>
<artifactId>kotlin-bom</artifactId>
<version>1.9.10</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<dependency>
<groupId>com.typesafe</groupId>
<artifactId>config</artifactId>
<version>1.4.9</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>2.0.17</version>
</dependency>
<dependency>
<groupId>com.google.errorprone</groupId>
<artifactId>error_prone_annotations</artifactId>
<version>2.50.0</version>
</dependency>
<dependency>
<groupId>io.swagger.core.v3</groupId>
<artifactId>swagger-annotations</artifactId>
<version>2.2.50</version>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<dependency>
<groupId>org.llm4s</groupId>
<artifactId>llm4s-java-api_3</artifactId>
<version>${llm4s.version}</version>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<version>1.5.34</version>
<scope>runtime</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-enforcer-plugin</artifactId>
<version>3.5.0</version>
<executions>
<execution>
<id>enforce-convergence</id>
<goals><goal>enforce</goal></goals>
<configuration>
<rules><dependencyConvergence/></rules>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>exec-maven-plugin</artifactId>
<version>3.5.0</version>
<configuration>
<mainClass>org.llm4s.samples.HelloLLM4S</mainClass>
</configuration>
</plugin>
</plugins>
</build>
</project>
What each part is for:
llm4s-java-api_3is the library. Changellm4s.versionto move to another release; every llm4s artifact is released at the same version.logback-classicis the logging backend. llm4s logs through SLF4J and ships none; without one SLF4J prints a single “no SLF4J providers were found” warning and drops the logs.scala3-library_3independencyManagementpins the Scala 3 library. Several llm4s modules may ask for different micro-versions, and Maven’s nearest-wins rule would pick one silently. Pinscala3-library_3by name, never the wholeorg.scala-langgroup: Scala 3 runs on the Scala 2.13scala-library, which has no 3.x release. The dependency conflicts reference has the matrix.maven-enforcer-pluginwithdependencyConvergencefails the build when two dependencies need different versions of one library, so a conflict shows up at build time and not as aNoSuchMethodErrorat run time. When it fails, it names the library and both paths: add adependencyManagemententry for it, as forscala3-library_3, or an exclusion.- The other
dependencyManagemententries settle the conflicts the enforcer finds today: the OpenAI and Anthropic SDKs ask for different Jackson, Kotlin, error-prone and Swagger versions, and pureconfig for an older Typesafe Config and SLF4J than llm4s. Each pin is the newest version any of them asks for; the Jackson and Kotlin BOMs pin every artifact of those families at once. exec-maven-plugingivesmvn exec:java, which runs themainclass.
The code and the configuration
src/main/java/org/llm4s/samples/HelloLLM4S.java creates a client from the default provider, asks one question
and prints the answer or the error. Every call returns an LlmResult, so there is no Scala Either in the code:
1
2
3
4
5
6
7
8
9
LlmResult<JLlmClient> created = Llm4s.createDefaultClient();
if (created.isFailure()) {
System.err.println("Could not create a client: " + created.getError().getMessage());
return 1;
}
try (JLlmClient client = created.get()) {
LlmResult<String> answer = client.complete("In one sentence, what is Scala?");
// ... print answer.get(), or answer.getError().getMessage()
}
src/main/resources/application.conf names the provider, as a named section; the
Configuration guide covers the others:
1
2
3
4
5
6
7
8
9
10
llm4s {
providers {
provider = "openai-main"
openai-main {
provider = "openai"
model = "gpt-4o-mini"
}
}
}
Run it
1
2
export OPENAI_API_KEY=sk-...
mvn -q compile exec:java
You should see one sentence; the wording depends on the model. With a local Ollama, change the section to
provider = "ollama" with a model you have pulled, as in the Ollama quick start.
If something goes wrong
Could not find artifact org.llm4s:llm4s-java-api:jar (no _3): add the suffix, llm4s-java-api_3.
Could not create a client: ... apiKey: set OPENAI_API_KEY: the key is not set in the shell that runs mvn.
Rule 0: ...DependencyConvergence failed: see the enforcer entry above.
class file has wrong version 65.0 or similar: Maven is running on a JDK older than 21. Check mvn -v.
Next steps
- Java guide: conversations, options, agents and errors from Java
- Gradle Integration: the same project in Gradle
- Configuration: all providers and how keys are found