34

I have a local Maven project under development. How can I launch jshell with the project class path with all the dependencies, so that I can test project or dependency classes inside JShell.

Naman
  • 27,789
  • 26
  • 218
  • 353
Jianwu Chen
  • 5,336
  • 3
  • 30
  • 35
  • 3
    This seems to be a useful use case that is not clearly addressed by jshell tutorials or elsewhere online. – Jason Dec 08 '17 at 13:23
  • What about using exec-maven-plugin? – khmarbaise Dec 12 '17 at 12:46
  • Are you looking for a command line only solution? Here is an IDE-specific solution: https://stackoverflow.com/questions/48143960/how-to-import-a-custom-class-in-intellij-jshell-console – Jason Jan 13 '18 at 13:44
  • you would probably be better off looking into gradle – Thufir Dec 20 '18 at 10:23

5 Answers5

40

You can use the jshell-maven-plugin:

mvn com.github.johnpoth:jshell-maven-plugin:1.3:run

which will fire up a JShell session with your project's runtime path. If you want to include your test dependencies just add -DtestClasspath to the command.

NOTE: the plugin expects the project to be built already. If not, invoke the appropriate Maven build phase before the plugin e.g:

mvn [install|compile|test-compile] com.github.johnpoth:jshell-maven-plugin:1.3:run

Source code: https://github.com/johnpoth/jshell-maven-plugin; contributions are welcome :) full disclaimer: I wrote the plugin.

Enjoy!

jpoth
  • 431
  • 1
  • 4
  • 4
  • 1
    This is really promising, and is not OS-dependent as is the accepted answer!One problem is that if there are non-jar dependencies, the plugin will just fail to launch on invalid classpath argument. Is there a way to do the equivalent of -DincludeTypes=jar as in the other answer? I can't use this plugin in a project that has a .nar dependency. – Jason Apr 12 '18 at 11:59
  • Tried this with spring-based project, but it does not see spring. I ran it where pom.xml was. Could not import anything from org.springframework. ... ; Am I doing something wrong? – Witold Kaczurba Feb 14 '19 at 09:57
24

I wrote a simple shell script put in the execution search path:

Shell script file: mshell (for *inux)

mvn dependency:build-classpath -DincludeTypes=jar -Dmdep.outputFile=.cp.txt
jshell --class-path `cat .cp.txt`:target/classes

Shell script file: mshell (for Windows cmd.exe)

mvn dependency:build-classpath -DincludeTypes=jar -Dmdep.outputFile=.cp.txt
for /F %i in (.cp.txt) do jshell --class-path "%i;target/classes"

Then in the maven project directory (for multi-module project, make sure in the module directory instead of parent directory), run:

$ cd $MAVEN_PROJECT_HOME   #make sure module folder for multi-module project
$ mshell

gist link

Thanks Jay for pointing out -DincludeTypes=jar maven option.

Robert
  • 39,162
  • 17
  • 99
  • 152
Jianwu Chen
  • 5,336
  • 3
  • 30
  • 35
  • 2
    if you use mvn dependency:build-classpath -DincludeTypes=jar then it won't include the pom dependencies. – Jason Dec 08 '17 at 13:21
  • Happy to upvote if you can create script for Windows as well. – Witold Kaczurba Feb 14 '19 at 09:49
  • "Goal requires a project to execute but there is no POM in this directory" - requires some pom.xml in the current dir to work. – mvmn Mar 31 '23 at 23:12
  • This is a nice solution, however cmd variables are limited to 8191 characters. So it will not work for a looong classpath. – Marcos Pirmez Jun 28 '23 at 18:37
  • @MarcosPirmez In Java9, there's Argument File concept. That could help to solve the cmd line limit problem. Haven't tried that. Feel free to try it and update the answer. https://stackoverflow.com/questions/201816/how-to-set-a-long-java-classpath-in-windows – Jianwu Chen Jul 03 '23 at 22:29
3

See In Maven, how to output the classpath being used?.

According to:

jshell --help

run JShell with:

jshell --class-path <path>
Naman
  • 27,789
  • 26
  • 218
  • 353
Gerold Broser
  • 14,080
  • 5
  • 48
  • 107
  • This gives you the dependency classes but not the project classes. Is there a straightforward way to include those as well, so you can use a REPL over your entire project? – Jason Dec 08 '17 at 12:36
  • Could you update this with a working sample or a detailed explanation of how does this work actually for you? – Naman Dec 21 '17 at 11:38
2

Because of JDK bug 8177650, the solutions here using the --class-path option or launching from maven will break package autocompletion. Here is a bash one-liner that works with package autocompletion:

CLASSPATH=`mvn dependency:build-classpath -DincludeTypes=jar -Dmdep.outputFile=/dev/stderr 2>&1 >/dev/null`:target/classes jshell
Roger Keays
  • 3,117
  • 1
  • 31
  • 23
0

Use Groovy shell (groovysh) instead and do groovy.grape.Grape.grab([group:"<maven group>", artifact:"<maven artifact ID>", version:"<version>"]) - this will give you REPL with necessary Maven dependencies in classpath.

Not sure if jshell has any advantages over Groovy shell that are worth the pain with Maven dependencies.

mvmn
  • 3,717
  • 27
  • 30