I was playing around with JShell after the Java 9 release, and I tried importing a package I made. As the entire application I'm coding it for will be contained in that package, every class but one (which I haven't coded yet) is package-private. My classpath is correct, but I still can't use any of the types declared in the package in JShell (it throws a "cannot find symbol" error). Do I need to make them public for them to be accessible, or is there some way I can test package-private classes? Here's the exact code I tried.
My current directory is
C:\Users\Sylvaenn\OneDrive\Documents\Programs\Java\src
My class path is
C:\Users\Sylvaenn\OneDrive\Documents\Programs\Java\cls
and the package directory (for the bytecode) is
C:\Users\Sylvaenn\OneDrive\Documents\Programs\Java\cls\collatz
CollatzSequence
is a package-private class contained in collatz
.
PS C:\Users\Sylvaenn> cd OneDrive\Documents\Programs\Java\src
PS C:\Users\Sylvaenn\OneDrive\Documents\Programs\Java\src> jshell
| Welcome to JShell -- Version 9
| For an introduction type: /help intro
jshell> import collatz.*;
jshell> CollatzSequence seq = new CollatzSequence(BigInteger.ONE);
| Error:
| cannot find symbol
| symbol: class CollatzSequence
| CollatzSequence seq = new CollatzSequence(BigInteger.ONE);
| ^-------------^
| Error:
| cannot find symbol
| symbol: class CollatzSequence
| CollatzSequence seq = new CollatzSequence(BigInteger.ONE);
| ^-------------^
jshell> /imports
| import java.io.*
| import java.math.*
| import java.net.*
| import java.nio.file.*
| import java.util.*
| import java.util.concurrent.*
| import java.util.function.*
| import java.util.prefs.*
| import java.util.regex.*
| import java.util.stream.*
| import collatz.*
jshell>
In general, 10 packages are imported using the JShell. The following command shows the packages that were imported by default. import java.io.* import java.math.* import java.net.* import java.nio.file* import java.sql.* import java.util.* import java.util.regex* import java.util.function* import java.util.prefs* import java.util.stream.*
What you have to do is add the packages to the JShell classpath with the /env -class-path <path> command (if we already started a JShell session) or the option $jshell --class-path <path> (on the command-line). You can specify a directory (in this example, it's the current directory): 1 jshell> /env -class-path .
We can also import external libraries in JShell by using the below steps: If we want to create an InternetAddress object that resides in the j avax.mail.internet package, then we need to import that package in JShell. In the above, just importing the class doesn't work because the package is unknown to the classpath.
To see, default import packages, we can use following command. Importing java.sql package. Listing import packages and it will show available accessible packages. Jshell provides various useful commands that we can use to modify environment, manage code and to get code related information.
From the JEP#220 - The Java Shell (Read-Eval-Print Loop)
A snippet may not declare a package or a module. All JShell code is placed in a single package in an unnamed module. The name of the package is controlled by JShell.
That is the reason probably why you are not able to declare a package
within JShell.
As the tool documentation suggests though you can give this a try:-
The default startup script consists of several common imports. You can personalize your startup entries with the
/set
start command.
where you can set the classpath or the modulepath of the class you would make use of :
jshell --class-path C:\Users\Sylvaenn\OneDrive\Documents\Programs\Java\cls
As far as i know (correct me if i am wrong), you cannot create a Class in a specific package using JShell (classes created within JShell are always in the default package).
That being said, you cannot access your package-private classes from within JShell. This is "normal" Java behaviour.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With