Using external libraries in JShell

栏目: IT技术 · 发布时间: 4年前

内容简介:After I’veIdeally, JShell itself would offer a resolution mechanism to grab external dependencies but currently, there’s no such feature. There’s aAlthough external

After I’ve experimented with JShell to solve mathematical puzzles with the Java’s Standard Library, I set out to use it for two other use cases: investigate external libraries, and use the REPL experiment with classes defined in a project.

Loading external classes with vanilla JShell

Ideally, JShell itself would offer a resolution mechanism to grab external dependencies but currently, there’s no such feature. There’s a custom version of JShell which provides the /resolve command to download artifacts, but it’s not maintained anymore.

Although external JAR files can be imported via classpath , this alone is pretty cumbersome to try third-party libraries. A typical library is available on a Maven repository, and normally it’s consumed by a dependency management tool. So first, you have to download the JAR file manually, and put it on the classpath. If it has any dependencies, those have to be downloaded as well. Finally, you have to craft the classpath yourself.

Also, I’ve found out the hard way that there’s a strange bug in JShell: packages in classpath don’t always appear in completions . If the classpath is specified via the --class-path argument, autocompletions will not list the external packages.

# Set classpath via --class-path
jshell --class-path=”...classpath with Guava...”
|  Welcome to JShell -- Version 9.0.1
|  For an introduction type: /help intro

jshell> import com.google<TAB>
# No autocompletion!
jshell> com.google.common.base.Strings.repeat("I'm here!", 3)
$1 ==> "I'm here!I'm here!I'm here!"

However, if the classpath is specified using the CLASSPATH environment variable, it works:

# Set classpath in Bash (in Windows, use SET instead of export)
export CLASSPATH=”...”

# Start JShell using the custom classpath defined above
jshell
# Set classpath via --class-path
jshell --class-path=”...classpath with Guava...”
|  Welcome to JShell -- Version 9.0.1
|  For an introduction type: /help intro

jshell> import com.<TAB>
google.   sun.
jshell> import com.google.
common.       errorprone.   j2objc.       thirdparty.

To summarize, while it’s possible to download dependencies by hand and craft the classpath manually, it’s really tedious.

Build tool integration

To make things a bit easier, I decided to see how JShell could be integrated into a Maven or Gradle project which already solves the problem of dependency resolution. A plugin exists for both build tools ( jshell-maven-plugin , jshell-gradle-plugin ) that allows launching JShell with the project’s classpath.

One problem with these plugins is that they are using the --class-path argument under the hood, so they are affected by the bug I’ve mentioned in the previous section. The solution is simple: even without the plugins, it’s quite easy to get the project’s classpath directly from the build tool and use it in the CLASSPATH environment variable.

For a Maven project, the Maven Dependency Plugin ’s build-classpath goal can be used for this purpose (note that the usual verbose is suppressed by the grep command which leaves only the classpath):

export CLASSPATH=$(mvn dependency:build-classpath | grep -vE "[INFO]|[ERROR]")
jshell

It’s not as easy for Gradle, but with a simple task, you can print the classpath…

task printClasspath {
   doLast {
       println sourceSets.main.runtimeClasspath.asPath
   }
}

… which can be used to fill the environment variable (again, the -q flag is necessary to suppress the other noises from the build log):

export CLASSPATH=$(gradle -q printClasspath)
jshell

Both of these approaches allow us to load external libraries and experiment with classes defined in the project .

jshell-resolve

Occasionally I want to quickly check how a library works without opening an IDE or altering a project. To make this easier, I’ve put a custom bash script called jshell-resolve to my PATH that expects one or more Maven Coordinates as arguments, resolves them using a generated Gradle build and starts JShell with all the artifacts available on the classpath.

For example, with jshell-resolve com.google.guava:guava:28.2-jre JShell starts with Guava:

Using external libraries in JShell

The script launches a Docker container including a JDK, Gradle and an empty Gradle project with the specified dependencies. The classpath will only contain the specified packages.

IDE support

In IntelliJ IDEA there’s built-in support for JShell, which can be launched with the project’s classpath. Although the experience is a bit different than the terminal-based shell, as there are separate input and output windows. (For an example, see the Java 9 and IntelliJ IDEA post from the JetBrains blog .)

The support is not so nice for Eclipse though. I’ve tried to use JShell as an External Tool suggested by this post , but autocompletion did not work in the Console window. Sadly, I’ve found no viable alternatives other than the old Scrapbook Page feature, (suggested in this SO thread ) which is not quite the same as JShell.

Summary

This post covered alternatives about accessing your classes in JShell. It’s really great to see a shift from the IDE oriented Java language to having a REPL, which is a great addition to the ecosystem.


以上所述就是小编给大家介绍的《Using external libraries in JShell》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

程序员2010精华本

程序员2010精华本

程序员杂志社 / 电子工业 / 2011-1 / 49.00元

《程序员(2010精华本)》主要内容:《程序员》创刊10年来,每年末编辑部精心打造的“合订本”已经形成一个品牌,得到广大读者的认可和喜爱。今年,《程序员》杂志内容再次进行了优化整合,除了每期推出的一个大型专题策划,各版块也纷纷以专题、策划的形式,将每月的重点进行了整合,让内容非常具有凝聚力,如专题篇、人物篇、实践篇等。另外杂志的版式、色彩方面也有了很大的飞跃,给读者带来耳目一新的阅读体验。一起来看看 《程序员2010精华本》 这本书的介绍吧!

JS 压缩/解压工具
JS 压缩/解压工具

在线压缩/解压 JS 代码

Base64 编码/解码
Base64 编码/解码

Base64 编码/解码

html转js在线工具
html转js在线工具

html转js在线工具