Can't access Classes in default package - java

I have a problem with the default package.
Basically my project structure consists of three main classes which extend one abstract class in a package called simulation.
Yesterday I did a name change in the project and now my three main classes are put automatically in the default package, so they can't be visible by the class inside the simulation package and vice versa.
For the following code
import simulation.*;
class SSQSim extends Simulation{
}
I get these errors
"This class must implement the inherited abstract method Simulation.stop(), but cannot override it since it is not visible from SSQSim. Either make the type abstract or make the inherited method visible"
"The type Simulation is not visible"
Thank you in advance.
EDIT
The problem is that I don't have to use any other packages. It's basically homework and the rules for the submission are pretty strict: First, I have to submit the package "simulation" which contains the abstract class "Simulation" with some methods to implement with the help of the other classes. This part is fine.
Then, I have to create three classes which import the package "simulation" and extend its class "Simulation". They have specifically said not to put these classes in any package. At first, they all worked fine but after I renamed the project. These classes suddenly moved into the default package and now they give me these errors.

How are you creating your classes? When you create a new class, Eclipse shows a New Java Class dialog. This dialog lets you choose which package to create your new class in:
Just click the Browse button and you'll be able to pick a package.

Why you use the default package,From the java specs:
It is a compile time error to import a type from the unnamed package.
So you have to create a new package with a different name and add your classes or put them in the same package as your class and do the required imports.

This is due to the fact that the signature of Simulation.stop() method mentions some class that is package-restricted (non-public) to the simulation package.
You solve it by either
Move SSQSim to the simulation package so it can access the same classes as Simulation, or
Make the classes required to extend the Simulation class package-public.
To move a class from one package to another in eclipse, you can simply drag the source-code file into the desired package, and eclipse will refactor the code accordingly.
(A side-note: As a rule of thumb, don't use the default package. The problem you ran into however, can occur even if you avoid the default package!)

This is just a hint for now, as the source code for all the classes is not posted. The error message implies the presence of an abstract method in the parent class, that cannot be overriden due to loss in visibility in the child class. Usually, this is due to the use of the default access specifier ("friendly"), or the private access specifier (which is meaningless, especially if the method is declared as abstract). One will have to use the protected access modifier on the parent, to ensure that the method is now visible to all child classes irrespective of whether they are present in the same package or not.
In short, if the child cannot "see" the method that is being overriden, then the compiler issues a warning that informs about the inevitability to deduce whether the method defined in the parent or the child should used at runtime.
As far as Eclipse's behavior of creating classes in the default package is concerned, one can always ensure that a package is specified when creating a new class in the appropriate dialog (the new Java Class dialog, where a package field is present).

Related

How does Java know which class to use in this example?

I am beginning to learn the principles of OOP and inheritance, and I came across this question while writing some code:
Suppose there is a package which contains a class called ClassA. Then, in a separate folder, I have another class called MyClass. Inside the same folder as MyClass, I have another class called ClassA, which is unrelated to the ClassA in the package. When I write the code for MyClass, I make it extend ClassA.
Which ClassA does MyClass extend from? Does MyClass inherit the ClassA which is in the imported package, or does MyClass inherit the ClassA which is in the same folder as MyClass? Would the code even compile?
I am trying to understand this from a theory perspective before diving into examples.
what you're looking at is a Statically scoped language which will work its way out of its inner scope, all the way to its outter scopes.
In this case, since import Class A is declared directly inside the file to which it is first called, it will use import Class A and stop.This will be its default behavior.
It will not carry on to look at the packaged Class A because it found one already, declared inside of the same class file.
This is the default behavior of java's (static) scope hierarchy.
IF it had not found an import of Class A imported inside the same file, it would reach out to its package to search for one.
This is very useful when declaring like variables. Do a little research how statically scope languages work.
If it is easier for you to understand, you can be explicit in your intentions by declaring exactly which Class A you would like though.
Just a side note- this is more of a programming languages question than directly a java question, but since you ask specifically for java, we only need to cover the simple specific answer. if you would like to know more, i can direct you (or tell you) more about statically vs dynamically scoped languages.
I suppose it is worth noting that if you decide to import both Class As even from your package (which you do NOT need to do) you would have to explicitly declare which you would like.
In that situation, to make it perfectly clear to the compiler you would probably want to do something like extends otherPackage.ClassA, and use the full reference name to extend the classA from the other package. If you want to use the one from the package MyClass is in, then just don't import the other ClassA and do extends ClassA
Since you're new to programming, I'm going to explain it in really simple words. Say there is a package called Salads. In that package, you have a class called Caesar. Then, you have another package called People. In that package, you have another class called Caesar. Obviously, Salads.Caesar refers to Caesar salad, and People.Caesar refers to a person named Caesar. But both classes have the same name: Caesar.
So when you're writing java code, java looks in two places for class definitions:
classes defined in the same folder (because they are implicitly in the same package if they are in the same folder assuming you're following all the normal rules.
classes defined in any imported packages
So the question is asking if you just say Caesar in the code, will it recognize it as the one in the same folder or the one in the imported package? Well, this is a bad question to ask because first of all, you should not name your classes so ambiguously. Secondly, if it can't be helped, you should always refer to the fully qualified name in your code.
If you mean People.Caesar then type People.Caesar and if you mean Salads.Caesar, type Salads.Caesar. Don't take shortcuts. You can only take shortcuts if there is no ambiguity. The compiler will probably complain about it anyway asking you to specify. AKA your code will not work unless you change all references of Caesar to Salads.Caesar or People.Caesar.
Packages in Java is a mechanism to encapsulate a group of classes,
interfaces and sub packages. Many implementations of Java use a
hierarchical file system to manage source and class files. It is easy
to organize class files into packages. All we need to do is put
related class files in the same directory, give the directory a name
that relates to the purpose of the classes, and add a line to the top
of each class file that declares the package name, which is the same
as the directory name where they reside.
in the top of java files, you have import that you can choose what class from what package you mean of course as #Jason said too if the class you want its in your package you don't need to tell it explicitly and compiler know that but if its in another package you have to tell him explicitly.
assume you have FirstClass.java in src folder and another in mycodes folder when in your class you import FirstClass you mean FirstClass.java that exist in src folder and when you import mycodes.FirstClass you mean FirstClass in mycodes folder.
your class can be member of packag.when you extend class that you class are in package A when you extend SomeClass you mean SomeClass that is in package A and if you want extend other class that is in other package like B you must extend B.SomClass
Here is another information about packages in java

java dynamic class loading that avoids java.lang.IllegalAccessError

Oracle JavaDocs explains that IllegalAccessError is
"Thrown if an application attempts to access or modify a field, or to
call a method that it does not have access to."
I try to load a class dynamically and I get this exception.
if I understand correctly when you use a classloader to load a class with a private package dynamically IllegalAccessError happens
the class I am trying to load is using
org.xml.sax.helpers.SecuritySupport
which also states in their description in the following url
http://grepcode.com/file/repository.springsource.com/org.apache.xmlcommons/com.springsource.org.apache.xmlcommons/1.3.4/org/xml/sax/helpers/SecuritySupport.java
that
Unfortunately, we can't load the class using reflection
* because the class is package private. And the class has
* to be package private so the APIs aren't exposed to other
* code that could use them to circumvent security. Thus,
* we accept the risk that the direct reference might fail
* on some JDK 1.1 JVMs, even though we would never execute
* this code in such a case. Sigh...
how can I dynamically load it anyway? I have to get it to work.
also if I get an error when I use a classloader, I cannot recover from that, so how can I know in advance that I cannot load this class?
thanks in advance to anyone who helps
The statement “we can't load the class using reflection because the class is package private” doesn’t make any sense, as can be shown easily:
package somepackage;
class BaseClass {
public static void main(String[] args) throws ReflectiveOperationException {
BaseClass obj=(BaseClass)
Class.forName("somepackage.SubClass").newInstance();
obj.aMethod();
}
void aMethod() {
System.out.println("base class");
}
}
class SubClass extends BaseClass {
#Override
void aMethod() {
System.out.println("method overridden by subclass");
}
}
This works flawlessly, printing method overridden by subclass replicated the actual use case of that SecuritySupport class.
However, since that class obviously serves the purpose of allowing a transition between Java 1.1 and Java 1.2, it might be possible that there were such restrictions twenty years ago, when this transition happened.
Your use case, however, is entirely different. You say that you are trying to load a class which “is using org.xml.sax.helpers.SecuritySupport”, which doesn’t imply that it is using said class via Reflection, but as shown above, that doesn’t matter anyway. It either case, it would only work, if the class is in the same package, whether you load the class “dynamically” or not.
There are only two possible scenarios.
If the class is truly within the same package, which at runtime implies that it also has been loaded by the same class loader, which would require that is also part of the JRE, if the JRE’s org.xml.sax.helpers package defines a SecuritySupport class, then the class can access the class within the same package.
If you are trying to load a class via a different ClassLoader from a different code source, it will not be of that package, even if you’d give it a qualified name of the org.xml.sax.helpers.SomeClass form. If the JRE’s org.xml.sax.helpers package happens to define a SecuritySupport class, all non-JRE classes would be in a different package. When it tries to access that class, which is not part of the official API, it doesn’t work.
Note that all standard class loaders follow a delegation model trying to resolve a name through their parent class loader first, which is the reason why they all would prefer the JRE’s org.xml.sax.helpers.SecuritySupport class, if there is one. With non-standard class loaders, you could have different, unrelated classes with that qualified name, being in different runtime packages.
In that second scenario, the question arises, why your class is using that class. In 2017, there’s rarely a need to differentiate between Java 1.1 and Java 1.2 and the functionality offered by that class is also only relevant for a class within the privileged code source of the JRE (or different code sources with different privileges in general).

Gaining access to package-access members by creating the same package name

I have a question about a sneaky way to gain access to package-access members that occurred to me. Specifically, I want to extend a class - let's call it com.acme.Foo - to add some functionality. This is pure addition: all current methods of Foo would be supported just by delegating to the superclass's method. However, there is no accessible constructor of Foo, so I can't extend the class and my implementation won't pass the "isA" test for being a Foo. There is no interface that expresses Foo-ness that I can use instead of inheritance.
This is where the sneaky thought occurred to me: Foo has a package-access constructor, so why not just create a package com.acme in my source folder and create an InheritableFoo class in that package:
package com.acme;
public class InheritableFoo extends Foo {
public InheritableFoo() {
super();
}
}
Now I can implement my extension to Foo by extending InheritableFoo, since that DOES have an accessible constructor.
This feels all wrong, and somehow unethical: I'm not respecting the decision the original programmer made when he or she decided to not expose a constructor for Foo. But it could be the case that they simply adopted the "deny everything until there's a reason for it" approach. Either way, is there anything fundamentally wrong with this idea? Am I going to cause myself problems in the future if I go this route, and if so, why?
You are correct regarding the fact that you can "sneak" in a class of your own into another package and get access to package restricted elements.
This will however only as long as the author of com.acme.foo distribute his code as source or an unsealed package. Should the author of this package distribute it as a sealed jar (which is quite common I believe) your approach will no longer work.
From 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.

Using cglib to override package-local methods

I have a Java library I'm working on that uses cglib to create subclasses of abstract classes provided by the library user, and provides automatically-generated implementations of abstract methods left in there by the user.
My problem is that if the method in question has package-local (i.e. default) accessibility, the method I produce is apparently ignored, and the user gets an AbstractMethodError when it is called.
The classes I generate are in the same package as the original class (I generate a class whose name is original.package.OriginalClassName_AutomaticImplementation), although they are of course loaded by a different classloader (i.e. one that loads the byte array generated by cglib rather than a disk file); my suspicion is that this is the problem. If so, is there any way around it?
When working with package local it is the class loader and the package name that define whether the method is accessible or not. This is to stop classes getting unauthorised access to API methods. You could crate a class in the java.lang package and access the package local methods in java.lang.
You could try adjusting the class loader you load the class to be extended and then load the cglib version with that classloader as the cglib loader's parent. Don't know if it will work.

Should I keep the package name when extending a class?

I plan to extend a JSF renderer. The package name is oracle.adfinternal.view.faces.renderkit.rich
Should the extended class be in the same package structure:
oracle.adfinternal.view.faces.renderkit.rich
or even oracle.adfinternal.view.faces.renderkit.rich.[subpackage]
or can/should I put it into my own package? com.company.renderkits.
I suppose package-private variables might be interfered with if I put this into my own package name?
Any thoughts?
In general, you should put your extended classes in your own package.
The package-private access level should be used by closely connected classes, possibly written by the same developer, who knows all the implementation details. This is not the case if you extend a class with some functionality.
All that said, there are a few occasions where you need to place your class in the package of the superclass as a workaround, but remember, this is an ugly hack, and try hard to avoid it.
You should put the class into your own package. There shouldn't be any compilation/access problems. The superclass already sees what it needs to see.
I suppose package-private variables might be interfered with if I put this into my own package name?
This is true, but normally the extending class shouldn't worry about this. The to-be-extended class would have used the protected modifier for this otherwise.
You should not add things to other entities (companies, person) packages. They could make a class with the same name (and same package of course) at a later date. They could also choose to seal their JAR files as well which would prevent you from adding classes to their packages.
The purpose of packages is to give each entity their own unique namepsace in which to create types.
In your case I would name the package something like: com.foobar.oracle.adfinternal.view.faces.renderkit.rich where "com.foobar" is the reverse domain name of your entity (if you don't have one pick something that is unique).

Categories