Skip to content

Commit 965ca6c

Browse files
committed
ZOOKEEPER-3938: Upgrade JLine to 3.25.1
JLine API has been changed between 2x and 3.x quite much so JLineZNodeCompleter and ZooKeeperMain had to be changed quite much.
1 parent d8e5217 commit 965ca6c

File tree

7 files changed

+53
-38
lines changed

7 files changed

+53
-38
lines changed

pom.xml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -562,7 +562,7 @@
562562
<netty.version>4.1.127.Final</netty.version>
563563
<jetty.version>9.4.57.v20241219</jetty.version>
564564
<jackson.version>2.15.2</jackson.version>
565-
<jline.version>2.14.6</jline.version>
565+
<jline.version>3.25.1</jline.version>
566566
<snappy.version>1.1.10.5</snappy.version>
567567
<kerby.version>2.0.0</kerby.version>
568568
<bouncycastle.version>1.78</bouncycastle.version>
@@ -748,7 +748,7 @@
748748
<version>${jackson.version}</version>
749749
</dependency>
750750
<dependency>
751-
<groupId>jline</groupId>
751+
<groupId>org.jline</groupId>
752752
<artifactId>jline</artifactId>
753753
<version>${jline.version}</version>
754754
</dependency>

zookeeper-assembly/pom.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -100,7 +100,7 @@
100100
<artifactId>jackson-databind</artifactId>
101101
</dependency>
102102
<dependency>
103-
<groupId>jline</groupId>
103+
<groupId>org.jline</groupId>
104104
<artifactId>jline</artifactId>
105105
</dependency>
106106
<dependency>

zookeeper-contrib/zookeeper-contrib-fatjar/pom.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,7 @@
7979
<artifactId>jackson-databind</artifactId>
8080
</dependency>
8181
<dependency>
82-
<groupId>jline</groupId>
82+
<groupId>org.jline</groupId>
8383
<artifactId>jline</artifactId>
8484
</dependency>
8585
<dependency>

zookeeper-server/pom.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -116,7 +116,7 @@
116116
<scope>test</scope>
117117
</dependency>
118118
<dependency>
119-
<groupId>jline</groupId>
119+
<groupId>org.jline</groupId>
120120
<artifactId>jline</artifactId>
121121
<scope>provided</scope>
122122
</dependency>

zookeeper-server/src/main/java/org/apache/zookeeper/JLineZNodeCompleter.java

Lines changed: 22 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -20,44 +20,41 @@
2020

2121
import java.util.Collections;
2222
import java.util.List;
23-
import jline.console.completer.Completer;
23+
import org.jline.reader.Candidate;
24+
import org.jline.reader.Completer;
25+
import org.jline.reader.LineReader;
26+
import org.jline.reader.ParsedLine;
27+
import org.jline.utils.AttributedString;
2428

2529
class JLineZNodeCompleter implements Completer {
2630

27-
private ZooKeeper zk;
31+
private final ZooKeeper zk;
2832

2933
public JLineZNodeCompleter(ZooKeeper zk) {
3034
this.zk = zk;
3135
}
3236

33-
@SuppressWarnings({"unchecked", "rawtypes"})
34-
public int complete(String buffer, int cursor, List candidates) {
37+
@Override
38+
public void complete(LineReader lineReader, ParsedLine commandLine, List<Candidate> candidates) {
3539
// Guarantee that the final token is the one we're expanding
36-
buffer = buffer.substring(0, cursor);
37-
String token = "";
38-
if (!buffer.endsWith(" ")) {
39-
String[] tokens = buffer.split(" ");
40-
if (tokens.length != 0) {
41-
token = tokens[tokens.length - 1];
42-
}
43-
}
40+
String token = commandLine.words().get(commandLine.words().size() - 1);
4441

4542
if (token.startsWith("/")) {
46-
return completeZNode(buffer, token, candidates);
43+
completeZNode(token, candidates);
44+
} else {
45+
completeCommand(token, candidates);
4746
}
48-
return completeCommand(buffer, token, candidates);
4947
}
5048

51-
private int completeCommand(String buffer, String token, List<String> candidates) {
49+
private void completeCommand(String token, List<Candidate> candidates) {
5250
for (String cmd : ZooKeeperMain.getCommands()) {
5351
if (cmd.startsWith(token)) {
54-
candidates.add(cmd);
52+
candidates.add(createCandidate(cmd));
5553
}
5654
}
57-
return buffer.lastIndexOf(" ") + 1;
5855
}
5956

60-
private int completeZNode(String buffer, String token, List<String> candidates) {
57+
private void completeZNode(String token, List<Candidate> candidates) {
6158
String path = token;
6259
int idx = path.lastIndexOf("/") + 1;
6360
String prefix = path.substring(idx);
@@ -67,16 +64,17 @@ private int completeZNode(String buffer, String token, List<String> candidates)
6764
List<String> children = zk.getChildren(dir, false);
6865
for (String child : children) {
6966
if (child.startsWith(prefix)) {
70-
candidates.add(child);
67+
String zNode = dir + (idx == 1 ? "" : "/") + child;
68+
candidates.add(createCandidate(zNode));
7169
}
7270
}
73-
} catch (InterruptedException e) {
74-
return 0;
75-
} catch (KeeperException e) {
76-
return 0;
71+
} catch (InterruptedException | KeeperException e) {
72+
return;
7773
}
7874
Collections.sort(candidates);
79-
return candidates.size() == 0 ? buffer.length() : buffer.lastIndexOf("/") + 1;
8075
}
8176

77+
private static Candidate createCandidate(String cmd) {
78+
return new Candidate(AttributedString.stripAnsi(cmd), cmd, null, null, null, null, true);
79+
}
8280
}

zookeeper-server/src/main/java/org/apache/zookeeper/ZooKeeperMain.java

Lines changed: 25 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -311,20 +311,18 @@ void run() throws IOException, InterruptedException {
311311
boolean jlinemissing = false;
312312
// only use jline if it's in the classpath
313313
try {
314-
Class<?> consoleC = Class.forName("jline.console.ConsoleReader");
314+
Class<?> readerC = Class.forName("org.jline.reader.LineReader");
315315
Class<?> completerC = Class.forName("org.apache.zookeeper.JLineZNodeCompleter");
316316

317317
System.out.println("JLine support is enabled");
318318

319-
Object console = consoleC.getConstructor().newInstance();
320-
321319
Object completer = completerC.getConstructor(ZooKeeper.class).newInstance(zk);
322-
Method addCompleter = consoleC.getMethod("addCompleter", Class.forName("jline.console.completer.Completer"));
323-
addCompleter.invoke(console, completer);
320+
Object terminal = createTerminal();
321+
Object reader = createLineReader(terminal, completer);
324322

325323
String line;
326-
Method readLine = consoleC.getMethod("readLine", String.class);
327-
while ((line = (String) readLine.invoke(console, getPrompt())) != null) {
324+
Method readLine = readerC.getMethod("readLine", String.class);
325+
while ((line = (String) readLine.invoke(reader, getPrompt())) != null) {
328326
executeLine(line);
329327
}
330328
} catch (ClassNotFoundException
@@ -353,6 +351,26 @@ void run() throws IOException, InterruptedException {
353351
ServiceUtils.requestSystemExit(exitCode);
354352
}
355353

354+
private static Object createTerminal() throws ClassNotFoundException, NoSuchMethodException, IllegalAccessException, InvocationTargetException {
355+
Class<?> terminalBuilderC = Class.forName("org.jline.terminal.TerminalBuilder");
356+
Method terminalBuilderMethod = terminalBuilderC.getMethod("builder");
357+
Object terminalBuilder = terminalBuilderMethod.invoke(null);
358+
Method terminalBuildMethod = terminalBuilderC.getMethod("build");
359+
return terminalBuildMethod.invoke(terminalBuilder);
360+
}
361+
362+
private static Object createLineReader(Object terminal, Object completer) throws ClassNotFoundException, NoSuchMethodException, IllegalAccessException, InvocationTargetException {
363+
Class<?> readerBuilderC = Class.forName("org.jline.reader.LineReaderBuilder");
364+
Method readerBuilderMethod = readerBuilderC.getMethod("builder");
365+
Object readerBuilder = readerBuilderMethod.invoke(null);
366+
Method setTerminalMethod = readerBuilderC.getMethod("terminal", Class.forName("org.jline.terminal.Terminal"));
367+
setTerminalMethod.invoke(readerBuilder, terminal);
368+
Method setCompleterMethod = readerBuilderC.getMethod("completer", Class.forName("org.jline.reader.Completer"));
369+
setCompleterMethod.invoke(readerBuilder, completer);
370+
Method readerBuildMethod = readerBuilderC.getMethod("build");
371+
return readerBuildMethod.invoke(readerBuilder);
372+
}
373+
356374
public void executeLine(String line) throws InterruptedException, IOException {
357375
if (!line.equals("")) {
358376
cl.parseCommand(line);

zookeeper-server/src/test/java/org/apache/zookeeper/server/ClientSSLReloadTest.java

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,6 @@
2525
import java.util.Properties;
2626
import java.util.concurrent.CountDownLatch;
2727
import java.util.concurrent.TimeUnit;
28-
import jline.internal.Log;
2928
import org.apache.commons.io.FileUtils;
3029
import org.apache.zookeeper.PortAssignment;
3130
import org.apache.zookeeper.WatchedEvent;
@@ -144,7 +143,7 @@ public void certificateReloadTest() throws Exception {
144143
assertTrue(l.await(10, TimeUnit.SECONDS));
145144
}
146145

147-
Log.info("Updating keyStore & trustStore files !!!!");
146+
LOG.info("Updating keyStore & trustStore files !!!!");
148147
// Update the keyStoreFile1 and trustStoreFile1 files in the filesystem with keyStoreFile2 & trustStoreFile2
149148
FileUtils.writeStringToFile(keyStoreFile1, FileUtils.readFileToString(keyStoreFile2, StandardCharsets.US_ASCII), StandardCharsets.US_ASCII, false);
150149
FileUtils.writeStringToFile(trustStoreFile1, FileUtils.readFileToString(trustStoreFile2, StandardCharsets.US_ASCII), StandardCharsets.US_ASCII, false);

0 commit comments

Comments
 (0)