Some problems about adding external library in IntellijIdea - java

I have added an external library.
But I can only use it in src.I cannot use stdlib.jar(the external library) in com.jc.Searching. How to fix it?
detailed information:

According to your answer on my comment above. Usually, you need to provide an import statement in your ST class, which belong to com.ja.Searching package. Here you can read about it.
In your case, you can't do it, because a StdOut class is probably declared in default package within your external library and it's not possible in Java to import classes from unnamed package. Only way to get this class instance, is to try to use reflection, but obviously, that's not the way you need and even have to do.
It seems to me, you are using some lib, which doesn't provide any packages and all it's classes belong to the default one, that is why you don't need to make an import in your class within default package. It's not a good practice at all, but sometimes used in some tutorials to make a code snippets be more readable.

Classes in the default package can't be imported. So they can effectively be only used by classes in the default package as well.
It's a really, really bad practice to put classes in the default package, especially for a reusable library. Ask the author of the library to fix it, and use a proper package name.

Related

How to make a private package?

I'm doing a library. I have three packages:
Spreadsheet is the main package. The io package is an internal package for internal use. Unfortunately, the user can access to them since they are public classes.
I would like to keep this package, since it allows me to separate concepts while programming, but i would like to "hide" these classes to the end user.
What could i do?
It's good that you're asking yourself this question! I don't see much attention on this lately.
As OdsReader and OdsWriter are used only inside the Spreadsheet class, just move them inside the spreadsheet package, removing the public visibility keywork. They'll now be accessible only from the spreadsheed package's classes.
The solution proposed above, which is over-complicated for your use-case, and which is to use Java 9+ modules (or OSGi - please no!), is not really necessary here, but it's neverthless a step forward in maintaining definitions private and sealed, even to Reflection abusers.
As a side note, I see you've got an exceptions package.
I never recommend doing so, as you'll have to expose those exceptions' constructor to the users of your code, and they'll be able to instantiate them for no good reasons.
Move the exceptions inside the packages which uses them, and declare the constructor as package private.
Starting with java9, you can turn this library into a module. See this jigsaw tutorial.
Modules need to export a package in order for its public members to be accessible from other modules: Simply don't export your internal package, and it won't be visible.
You can also go with something like OSGi, a module system that predates java9. It too has this notion that there's a level beyond public (let's call it 'visible').
A final option is to use classloader shenanigans (where you for example rename your class files to some other extension during the build phase, and have a small bootstrapper in your visible package which creates a classloader that loads classes by looking in the same place as the visible API, and then load files with the alternative extension, and defineClass those into being), but that's a drastic step that introduces quite a bit of headache. I wouldn't take it unless you have excellent reasons to go down this rabbit hole.

Would making package in Java something other that a folder be a good idea?

Right now, that is all a package is. So when I create a new Package in Eclipse, I am just asked its name. But what if Package was something like or exactly like Interface and everything under the Package would have to implement that interface? Or at least Package is a place to store descriptive info?
Dumb idea or not?
EDIT: I just noticed that Eclipse creates automatically the file package-info.java -- this serves the purpose I was aiming at in this question.
Packages are usually used for structuring your files (classes, interfaces, e.t.c,).
Only addition is that your default access specifier in Java is Package private.
i.e., classes/interfaces for which you do not explicitly specify the access modifier, it remains accessible throughout that package.
package-info.java does what I was looking for.

How to edit Java Platform Package (Built-in API) source code?

As good as the Java API is, I need to change the code of some classes in the default API packages (for example java.util.Scanner) for a project I am working on.
Ideally, I would extend the classes I am interested and create my own sub-classes, but the classes I want to extend are declared 'final'. How do you suggest I do this? Will I get into trouble with the compiler if I customize the source code of these packages?
If you can, you should rather wrap and delegate, as suggested in another answer. See the Adapter Pattern.
But there are of course ways to do this if you really need it.
A straightforward approach is to simply modify the code in downloaded sources and substitute your own version of a jar in the classpath.
Another option is to use aspect-oriented programming techniques, likely with AspectJ to intercept and modify calls as needed.
It might also be possible to hack together a solution using reflection and home-grown classloaders, but it will be painful to code.
All of these are however quite risky if you don't know what you're doing. Frequently classes are made final for good reason.
If you tell us more specifically what it is you're hoping to change, we might be able to provide assistance in avoiding what you currently think you need.
you really cant extend a final class..
if u really want to add a functionality by extending a class you can do it by modifying class src. from JDK and save it as your own class and use it.
Don't do that. Write your own code which wraps around the original scanner and use that. To update internal packages, there is an endorsed directory property which you can provide at runtime.
Never do it! Never change core classes. If class is final - use composition not inheritance.

When to package-private (no explicit modifier) in java?

I have been reading the tutorial Controlling Access to Members of a Class. I am confused what might be good use case for using package-private. Because as I understand, you can always change your package declaration to whatever the package declaration of such a class and act as if that is a public class. I understand that this is not a good thing to do, but what is stopping me?
Because as I understand, you can always change your package declaration to whatever the package declaration of such a class and act as if that is a public class
Well, for one thing, the access modifiers are there to help the developer. There's always ways around them, such as via reflection for instance.
I understand that this is not a good thing to do, but what is stopping me?
Not much really!
As a developer you can however distribute your classes in sealed .jar-files which basically means that you're not letting anyone else in to your packages.
From Sealing Packages within a JAR File
Sealing Packages within a JAR File
Packages within JAR files can be optionally sealed, which means that all classes defined in that package must be archived in the same JAR file. You might want to seal a package, for example, to ensure version consistency among the classes in your software.
A couple of reasons to use package-private classes/methods:
Implementation classes that are part of a library, but not part of the library's API. This allows you to still have modular code, and acts as a sign to users of the API that the implementation classes are not for use as part of the API.
Making things available to tests. Sometimes (particularly when working with legacy code) you need to make classes or members more visible so that you can more easily unit test them. An example might be testing a class with a method that performs a resource-intensive operation that you want to override with a no-op version in your test. Another example is a class that only gets used in one place: it doesn't want to be visible to the whole app, but it needs to be unit tested.
In both cases using package-priviate visibility helps to make your code easier to use (people using it have a better idea of the scope of the class/member's intended use), while allowing you to still have modular code.
Regarding "what is stopping me":
The Java Security mechanism is stopping you, potentially. If the "target" package is sealed and signed, then Java will not allow any source other than the original to declare classes in that package.

Creating a java library

This may be a silly question, but right now I have a rather large class that I want to use as a library. Where somebody can simply add this jar file to their classpath. And then simply do an import statement at the top, then he or she can start using this class.
Is there anything special I need to do or can I simply just use the jar file built?
a rather large class
Large classes don't usually make good libraries :)
Technically, yeah, all you need it put it in a JAR. To make it easy to use (including by yourself), you should spend some time to refactor it and break up the functionality into smaller classes according to the Single Responsibility Principle. For static utility methods, consider whether you can group them into several classes according to some theme, or perhaps even turn some of them into non-static methods (if there are situations where a client would use more than one of those methods on the same data, they're begging to become instance methods).
And you definitely should write Javadoc comments for all public classes and methods, and publish the Javadocs along with the code. A library without an API doc is almost useless.
You can simply put the JAR into the classpath and can import the class. No more magic needed.
You should just be able to use the jar, as is. All you need to ensure is that the class files in the JAR are in the correct directory structure (according to their package names)
Class Foo in package bar -> bar/Foo.class in the jar
create a JAR of .class files of your "large class" and then put that JAR in your CLASSPATH.
Then you should be able to import the classes in the JAR via "import" statements.
If you anticipate too many huge classes/libraries, check out the JVM parameters -Xms and -Xmx that takes care of heap usage.

Categories