title: Java client
Using Bareun from Java
Use the Java client bareun-client for morphological analysis, spelling and grammar correction,
homonym sense disambiguation, and Urimalsaem (Open Korean Dictionary) phoneme search.
- Repository: bareun-java
- Current version: 2.0.0
- Java 17 or later
2.0.0 is being prepared for release
It is not on Maven Central yet. Until it is, clone the repository and install it locally
with mvn install.
The already released 1.4.3 (ai.bareun.tagger:bareun) supports only morphological analysis and the custom dictionary.
Spelling and grammar correction, sense disambiguation, and phoneme search are available from 2.0.0.
Installation
<dependency>
<groupId>ai.bareun</groupId>
<artifactId>bareun-client</artifactId>
<version>2.0.0</version>
</dependency>
implementation 'ai.bareun:bareun-client:2.0.0'
The only runtime dependency is protobuf-java.
What you need
- A running Bareun server. The default port is 5658 for a local install and 5656 for Docker.
- An API key. It starts with
koba-. How to get one
Spelling and grammar correction and Urimalsaem phoneme search work only on a server that includes the spell-check feature.
Morphological analysis
import ai.bareun.client.BareunClient;
import ai.bareun.tagger.Tagger;
import ai.bareun.tagger.Tagged;
BareunClient client = BareunClient.builder()
.host("localhost").port(5656)
.apiKey("koba-...")
.build();
Tagger tagger = new Tagger(client);
Tagged t = tagger.tag("아버지가 방에 들어가신다.");
t.pos(); // [아버지/NNG, 가/JKS, 방/NNG, 에/JKB, 들어가/VV, 시/EP, ㄴ다/EF, ./SF]
t.morphs(); // [아버지, 가, 방, 에, 들어가, 시, ㄴ다, .]
t.nouns(); // [아버지, 방]
t.verbs(); // [들어가]
To connect to the cloud, give the full address.
BareunClient.builder().baseUrl("https://api.bareun.ai").apiKey("koba-...").build();
BareunClient is thread-safe. Create one and share it.
Position information
Requests are sent with UTF-16 offsets. Java strings are UTF-16, so you can pass the positions
returned by the server straight into substring.
var span = t.sentences().get(0).getTokens(0).getText();
text.substring(span.getBeginOffset(), span.getBeginOffset() + span.getLength());
// "아버지가"
Several sentences at once
If sentence boundaries are already decided, you can reduce round trips.
List<Tagged> results = tagger.tagAll(List.of("첫 문장입니다.", "둘째 문장입니다."), false);
Custom dictionary
Tagger tagger = new Tagger(client, List.of("mydict"));
You create and delete dictionaries with client.customDictionary(). When you pass several, the earlier one
takes priority. See the custom dictionary API.
Spelling and grammar correction
import ai.bareun.tagger.Corrector;
Corrector c = new Corrector(client);
c.correct("이거 안되요. 학교에 갔읍니다.");
// "이거 안되요. 학교에 갔습니다."
for (Corrector.Change ch : c.changes("이거 안되요. 학교에 갔읍니다.")) {
System.out.println(ch.origin() + " → " + ch.revised() + " (" + ch.category() + ")");
}
// 갔읍니다. → 갔습니다. (STANDARD)
beginOffset and length of a Change are also based on Java strings, so you can use them directly with substring.
To see nested corrections or the help text, use c.raw(text) to get the server response as is.
For details, see the spell check API.
Homonym sense disambiguation
When the same characters can have several meanings, it picks which meaning is intended.
for (Tagged.SenseEntry s : tagger.tag("나는 밤에 밤을 먹었다.", true).senses()) {
System.out.println(s.morph() + "/" + s.tag() + " " + s.senseNo() + " " + s.meaning());
}
// 밤/NNG 2 밤나무의 열매. ...
// 먹/VV 2 음식 따위를 입을 통하여 뱃속에 들여보내다.
Morphemes that carry no meaning, such as particles (josa) and endings (eomi), have no sense attached to begin with, so most morphemes do not appear in the result. See the homonym sense disambiguation API.
Urimalsaem phoneme search
With precomposed Hangul syllables, you cannot write a condition such as "a syllable whose initial consonant is ㅅ and whose final consonant is ㄴ".
import ai.bareun.protos.DictSearchAnchor;
client.dictSearch().words("{ㅅ//ㄴ}다", DictSearchAnchor.DICT_SEARCH_ANCHOR_WORD, 10);
// [신다]
client.dictSearch().words("아지", DictSearchAnchor.DICT_SEARCH_ANCHOR_SUFFIX, 5);
// [아지, 가아지, 강아지, 개아지, 갱아지]
For the pattern syntax, see the Urimalsaem phoneme search API.
Error handling
When a call fails, a BareunException is thrown, and you tell the kinds apart by ConnectCode.
try {
tagger.tag("문장");
} catch (BareunException e) {
switch (e.getCode()) {
case PERMISSION_DENIED -> System.err.println("Check your API key");
case UNAVAILABLE -> System.err.println("Check the server address and whether it is running");
case UNIMPLEMENTED -> System.err.println("This server does not provide that feature");
default -> System.err.println(e.getMessage());
}
}
| Code | When |
|---|---|
UNAVAILABLE | Could not reach the server: wrong address, server not running, firewall, or timeout |
PERMISSION_DENIED | The API key is invalid or the license has expired |
UNIMPLEMENTED | A feature the server does not provide, such as a correction request to a server without the spell-check feature |
INTERNAL | Internal server error, or the response could not be parsed |
Migrating from 1.x
2.0.0 is not compatible with 1.x.
| 1.x | 2.0.0 |
|---|---|
ai.bareun.tagger:bareun | ai.bareun:bareun-client |
gRPC (io.grpc 1.21.0) | Connect (JDK HttpClient) |
| Java 8 | Java 17 |
| About 20 dependencies | Only protobuf-java |
| Morphological analysis and custom dictionary | + correction, sense disambiguation, phoneme search |
Code that created a LanguageServiceClient directly should switch to BareunClient.builder().
Features this library does not wrap
You can call any server method directly with client.connect().call(...).
client.connect().call("bareun.LanguageService", "AnalyzeSyntax", request,
AnalyzeSyntaxResponse.parser());
Streaming correction (StreamCorrectError) is not supported yet.
Frequently asked questions
Q. Can I use it on Java 8 or 11? A. 2.0.0 requires Java 17 or later. In older environments, use 1.4.3, and call spelling and grammar correction and sense disambiguation directly through the REST API.
Q. Why did you remove gRPC?
A. Connect unary calls are plain HTTP POST requests, so the JDK HttpClient alone is enough.
The gRPC stack brought in about 20 dependencies such as grpc-netty-shaded and guava, and their versions
often conflicted with other libraries in the application.
Q. Can several threads use one client?
A. Yes. BareunClient, Tagger, and Corrector are all thread-safe.
The internal HttpClient reuses connections, so sharing one is actually better.