Skip to content

Commit 8faad0a

Browse files
committed
Fix #1 Add JLine
1 parent fe0fb9e commit 8faad0a

File tree

5 files changed

+63
-47
lines changed

5 files changed

+63
-47
lines changed

build.sbt

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,17 +2,19 @@ organization := "tv.cntt"
22
name := "scalive"
33
version := "1.6"
44

5-
scalaVersion := "2.11.6"
6-
libraryDependencies += "org.scala-lang" % "scala-compiler" % scalaVersion.value % "provided"
7-
autoScalaLibrary := false
8-
crossPaths := false // Do not append Scala versions to the generated artifacts
5+
scalaVersion := "2.11.8"
6+
autoScalaLibrary := false
7+
crossPaths := false // Do not append Scala versions to the generated artifacts
98

109
javacOptions ++= Seq("-Xlint:deprecation")
1110

1211
// Ensure Scalive can run on Java 6
1312
scalacOptions += "-target:jvm-1.6"
1413
javacOptions ++= Seq("-source", "1.6", "-target", "1.6")
1514

15+
libraryDependencies += "org.scala-lang" % "scala-compiler" % scalaVersion.value % "provided"
16+
libraryDependencies += "jline" % "jline" % "2.14.2"
17+
1618
// Add tools.jar to classpath
1719
// https://blogs.oracle.com/CoreJavaTechTips/entry/the_attach_api
1820
unmanagedJars in Compile := (file(System.getProperty("java.home")) / ".." / "lib" * "tools.jar").classpath

src/main/java/scalive/AgentLoader.java

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@
66

77
import java.io.File;
88
import java.net.URLClassLoader;
9-
import java.util.Iterator;
109

1110
public class AgentLoader {
1211
/**
@@ -65,9 +64,7 @@ private static void listJvmProcesses() {
6564
System.out.println("JVM processes:");
6665
System.out.println("#pid\tDisplay name");
6766

68-
Iterator<VirtualMachineDescriptor> it = VirtualMachine.list().iterator();
69-
while (it.hasNext()) {
70-
VirtualMachineDescriptor vmd = it.next();
67+
for (VirtualMachineDescriptor vmd : VirtualMachine.list()) {
7168
System.out.println(vmd.id() + "\t" + vmd.displayName());
7269
}
7370
}
@@ -89,6 +86,6 @@ private static void loadAgent(String jarSearchDirs, String pid) throws Exception
8986
}
9087
});
9188

92-
Client.connectToRepl(port);
89+
Client.connectToReplServer(port);
9390
}
9491
}

src/main/java/scalive/Client.java

Lines changed: 32 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
package scalive;
22

3+
import jline.console.ConsoleReader;
4+
35
import java.io.InputStream;
46
import java.io.InputStreamReader;
57
import java.io.OutputStream;
@@ -8,7 +10,8 @@
810
import java.net.Socket;
911

1012
public class Client {
11-
private static final InetAddress LOCALHOST = getLocalHostAddress();
13+
private static final InetAddress LOCALHOST = getLocalHostAddress();
14+
private static final String SCALA_PROMPT = "scala> "; // Needs to match the prompt of REPL server
1215

1316
private static InetAddress getLocalHostAddress() {
1417
try {
@@ -27,13 +30,33 @@ public static int getFreePort() throws Exception {
2730
return port;
2831
}
2932

30-
public static void connectToRepl(int port) throws Exception {
31-
final Socket client = new Socket(LOCALHOST, port);
32-
final InputStream in = client.getInputStream();
33-
final OutputStream out = client.getOutputStream();
34-
33+
public static void connectToReplServer(int port) throws Exception {
34+
Socket socket = new Socket(LOCALHOST, port);
3535
System.out.println("[Scalive] Attached to remote process at port " + port);
3636

37+
InputStream sin = socket.getInputStream();
38+
OutputStream sout = socket.getOutputStream();
39+
printServerOutput(sin);
40+
41+
ConsoleReader reader = new ConsoleReader(System.in, System.out);
42+
reader.setPrompt(SCALA_PROMPT);
43+
44+
boolean closed = false;
45+
while (!closed) {
46+
try {
47+
String line = reader.readLine();
48+
sout.write(line.getBytes());
49+
sout.write('\n');
50+
sout.flush();
51+
} catch (Exception e) {
52+
closed = true;
53+
}
54+
}
55+
56+
socket.close();
57+
}
58+
59+
private static void printServerOutput(final InputStream in) {
3760
new Thread(new Runnable() {
3861
@Override public void run() {
3962
InputStreamReader reader = new InputStreamReader(in);
@@ -43,28 +66,14 @@ public static void connectToRepl(int port) throws Exception {
4366
int i = reader.read();
4467
closed = i < 0;
4568
if (!closed) System.out.print((char) i);
46-
} catch (Exception e) {
47-
closed = true;
48-
}
69+
} catch (Exception e) {
70+
closed = true;
71+
}
4972
}
5073

5174
System.out.println("[Scalive] Connection to remote process closed");
5275
System.exit(0);
5376
}
5477
}).start();
55-
56-
boolean closed = false;
57-
while (!closed) {
58-
try {
59-
String line = System.console().readLine();
60-
out.write(line.getBytes());
61-
out.write('\n');
62-
out.flush();
63-
} catch (Exception e) {
64-
closed = true;
65-
}
66-
}
67-
68-
client.close();
6978
}
7079
}

src/main/java/scalive/Repl.java

Lines changed: 19 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,19 @@
11
package scalive;
22

3+
import scala.Console;
4+
import scala.Option;
5+
import scala.runtime.AbstractFunction0;
6+
import scala.tools.nsc.Settings;
7+
import scala.tools.nsc.interpreter.ILoop;
8+
39
import java.io.BufferedReader;
410
import java.io.InputStream;
511
import java.io.InputStreamReader;
612
import java.io.OutputStream;
713
import java.io.PrintWriter;
814

9-
import scala.Console;
10-
import scala.Function0;
11-
import scala.Option;
12-
import scala.runtime.AbstractFunction0;
13-
import scala.tools.nsc.interpreter.ILoop;
14-
import scala.tools.nsc.Settings;
15-
1615
public class Repl {
17-
public static void run(ClassLoader cl, String classpath, final InputStream in, final OutputStream out) {
16+
public static void run(ClassLoader cl, String classpath, InputStream in, OutputStream out) {
1817
// Without the below settings, there will be error:
1918
// Failed to initialize compiler: object scala.runtime in compiler mirror not found.
2019
// ** Note that as of 2.8 scala does not assume use of the java classpath.
@@ -41,8 +40,17 @@ public static void run(ClassLoader cl, String classpath, final InputStream in, f
4140
new PrintWriter(out)
4241
);
4342

44-
// https://github.com/xitrum-framework/scalive/issues/11
45-
// http://stackoverflow.com/questions/25623779/implementing-a-scala-function-in-java
43+
overrideScalaConsole(in, out, new Runnable() {
44+
@Override
45+
public void run() {
46+
repl.process(settings);
47+
}
48+
});
49+
}
50+
51+
// https://github.com/xitrum-framework/scalive/issues/11
52+
// http://stackoverflow.com/questions/25623779/implementing-a-scala-function-in-java
53+
private static void overrideScalaConsole(final InputStream in, final OutputStream out, final Runnable runnable) {
4654
Console.withIn(in, new AbstractFunction0<Object>() {
4755
@Override
4856
public Object apply() {
@@ -53,7 +61,7 @@ public Object apply() {
5361
@Override
5462
public Object apply() {
5563
// This call does not return until the stream (connection) is closed
56-
repl.process(settings);
64+
runnable.run();
5765
return null;
5866
}
5967
});

src/main/java/scalive/Server.java

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,11 +7,11 @@
77
import java.net.URLClassLoader;
88

99
public class Server {
10-
public static void serve(Socket client, String[] jarSearchDirs) throws Exception {
10+
public static void serve(Socket socket, String[] jarSearchDirs) throws Exception {
1111
// Create a REPL console and wire IO streams of the socket to it
1212

13-
InputStream in = client.getInputStream();
14-
OutputStream out = client.getOutputStream();
13+
InputStream in = socket.getInputStream();
14+
OutputStream out = socket.getOutputStream();
1515

1616
InputStream oldIn = System.in;
1717
PrintStream oldOut = System.out;
@@ -32,7 +32,7 @@ public static void serve(Socket client, String[] jarSearchDirs) throws Exception
3232
System.setOut(oldOut);
3333
System.setErr(oldErr);
3434
System.out.println("[Scalive] REPL closed");
35-
client.close();
35+
socket.close();
3636
}
3737
}
3838

0 commit comments

Comments
 (0)