Permanently hidden warning from Scalac parsing Java code - compiler bug? - java

The scalac Java parser is taking objection to my Java code
imported `Entity' is permanently hidden by definition of object Entity in package domain Asset.java
This seems to be a collision between an import and a class with the same name in the package being compiled.
In my package I have a class
package iMP2020.domain;
public interface Entity {
public Serializable getId();
}
with the same name as an imported class from a different package
package iMP2020.domain;
import javax.persistence.Entity; // compiler warning
#Entity
public class Asset {
where it is complaining about the import. Javac is quite happy. Note that I don't have to reference my version of the class- just its existence is enough to trigger the warning on the import.
I can fix this by removing the import and explicitly referencing #Entity, but is it a bug in the compiler?

I don't seem to be able to reproduce this except with the Scala Eclipse plugin, so I'm going to wait for that to stabilise before coming to a conclusion.

You have two Entity references, one for your interface, and another one for javax.persistence.Entity.
Try to replace the second one with the full qualified name, removing the import:
package iMP2020.domain;
public interface Entity {
public Serializable getId();
}
and
package iMP2020.domain;
#javax.persistence.Entity
public class Asset {

I don't think it is a bug.
It doesn't make sense for an import to have the same name as a package member.

Related

In java, why can I only import abstract classes?

In my Java I have a class import:
import cc.hyperium.mods.HyperiumModIntegration;
however, it fails to import with error Cannot resolve symbol 'HyperiumModIntegration'.
The class I'm importing looks like this:
package cc.hyperium.mods;
public class HyperiumModIntegration {
public HyperiumModIntegration() {
}
}
Weirdly, if I make the class abstract, it imports just fine.
IntelliJ will show the class in code completion, however.
Invalidating caches and restarting in IntelliJ fixed it.
(Note to self: stop using EAP.)

Java import static fails when imported class extends 3rd party lib

The problem setup consists of three java libs (I stripped all package names for readability, full qualified names are used everywhere):
external-lib: provides the abstract class
public abstract class AbstractExternal {}
my-lib-A: provides the class
public class ClassA extends AbstractExternal {
public static final String FOO = "foo";
}
external-lib is in my-lib-A's classpath.
my-lib-B statically imports FOO from ClassA:
import static ClassA.FOO;
public class ClassB {
private String foo = FOO;
}
my-lib-A is in my-lib-B's classpath but external-lib is not.
Problem: The import static line produces the following error:
The type AbstractExternal cannot be resolved. It is indirectly referenced from required .class files.
However (1), when modifying ClassB to
import ClassA;
public class ClassB {
private String foo = ClassA.FOO;
}
the compiler is happy.
However (2), when adding a second abstraction two my-lib-A like
public class AbstractClassA extends AbstractExternal {}
and
public class ClassA extends AbstractClassA {
public static final String FOO = "foo";
}
the static import of ClassA.FOO in the example above works.
Question 1: Why does import static ClassA.FOO fails while import ClassA with ClassA.FOO works?
Question 2: Why does import static ClassA.FOO works when it extends another class from my-lib-A which then extends AbstractExternal?
Edit: a significant information: the compiler in question is the Eclipse Compiler for Java (ECJ).
Edit 2: javac is in sync with ECJ and is able to compile the normal import and class access in ClassB while the static import fails.
Ecj ideally "shouldn't" report this error. I filed Bug 533890 to track this.
The common theme behind all errors of this message ("... cannot be resolved. It is indirectly referenced ...") is a conflict between:
wanting full semantic analysis which is aware of all relevant classes and
wanting resilience if the build path does not contain all classes upon which the current class (indirectly) depends.
Obviously, JLS doesn't specify how compilers should handle incomplete build paths, but as a convenience for users, no errors should be reported if semantic analysis can avoid looking into certain indirect dependencies.
Where and when this can indeed be avoided needs to be checked (and implemented) on a case-by-case basis, but the given example likely qualifies as a case that can be avoided.
Until this issue is resolved, the problem can be avoided by making external-lib visible also to my-lib-B (e.g., using a project dependency). In module systems like OSGi or JPMS, it might actually be a good idea to let my-lib-A "re-export" its dependency external-lib, since its API class ClassA is "incomplete" for clients that are unable to see AbstractExternal.

Hibernate MetaModel <class> cannot be resolved to a type

I've generated my metamodels correctly as seen below.
They do not import the actual entity class therefore I get the " cannot be resolved to a type" compiler error.
package dummy.package;
import javax.annotation.Generated;
import javax.persistence.metamodel.StaticMetamodel;
#Generated(value = "org.hibernate.jpamodelgen.JPAMetaModelEntityProcessor")
#StaticMetamodel(MyClass.class)
public abstract class MyClass_ {
}
as you can see, the class used in the #StaticMetamodel annotation isn't imported
My assumptions and questions are:
1) Assumption: Both classes have the same package structure, so i'm assuming that we won't need to import the class (both declared under "dummy.package") But why do I get the error?
2) The metamodel is actually under "annotations.dummy.package" even though the file says "dummy.package", that's a different error (does not match the expected package) Can this be the reason for issue #1 above?

Using classes in my project that originate in a jar file

I'm using Eclipse on a Windows 7 64x machine. I've researched this problem and found many have had a similar one, but no solution I came across quite worked for me.
I'm working on a Project named Assignment_1, on a class named Percolation. I'd like to use the object WeightedQuickUnionUF which is inside a package contained within a jar file, named algs4.jar.
I seem to have added the Jar file I'm interested in to the build-path (it now appears under "Referenced Libraries"). The jar file algs4.jar resides in a folder named lib inside my project's folder.
However, when I try to declare an object of type WeightedQuickUnionUF inside my class, I get an error "WeightedQuickUnionUF cannot be resolved to a type".
I tried various import commands (including just import WeightedQuickUnionUF )before the class declaration and all of them yield the error "The import so and so cannot be resolved".
For example, this piece of code yields both of these errors. One at the import line, and another at the declaration of the WeightedQuickUnionUF object:
package assignment_1_package;
import algs4.WeightedQuickUnionUF;
public class Percolation {
private int[][] grid;
public int gridDimension;
private int opensGrid[][];
private WeightedQuickUnionUF model;
... //rest of class body here
This has baffled me for an entire day and I can't seem to figure this out. Thanks for your efforts.
Edit: here is a link to the class I wish to import: http://algs4.cs.princeton.edu/15uf/WeightedQuickUnionUF.java.html
Assuming you are talking about the algs4.jar of the class http://algs4.cs.princeton.edu/code/ , your import is incorrect you should do :
import WeightedQuickUnionUF;
BUT it's never a good idea to have class in the default package and it's actually not allowed to import a type from the unnamed package: this gives a compilation error.
http://docs.oracle.com/javase/specs/jls/se5.0/html/packages.html#7.4.2:
A type-import-on-demand declaration (§7.5.2) imports all the
accessible (§6.6) types of a named type or package as needed. It is a
compile time error to import a type from the unnamed package.
So in your case to solve your issue just create your classes in the default package so you don't have to do the import at all.
I'm in the same class, had the same problem. Removing my equivalent to these two statements
package assignment_1_package;
import algs4.WeightedQuickUnionUF;
resolved the problem. That's to say the following now resolves correcly
private WeightedQuickUnionUF model;
In my case, it helped adding
import edu.princeton.cs.algs4.StdRandom;
import edu.princeton.cs.algs4.StdStats;
import edu.princeton.cs.algs4.WeightedQuickUnionUF;

Removing class ambiguity without being overly verbose

I have a Java library that I am working on with a directory structure which looks like the following:
/com
/example
/LibX
Server.java
Client.java
Now, from a project which is using the above classes, it seems to me that importing com.example.LibX.* and using Client client = new Client(...); is a bit ambiguous, as "Client" could mean anything. Therefore, I tried the following, only to receive "package not found" errors:
import com.example.*;
LibX.Client client = new LibX.Client(...);
It is possible to do what I described? Or is there another way to remove the ambiguity without using com.example.LibX.Client?
Java packages are not hierarchical, even if they may sometimes look like it. You can't import a "tree" of packages, as you're suggesting. You either need to import a specific package with a wildcard, or you import the specific class name, or you use fully-qualified class names in your code directly.
The following isn't ambiguous, and is considered best practice:
import com.example.LibX.Client;
...
Client client = new Client(...);
In a world where IDEs can organise your imports for you, there's no reason not to state them all explicitly.
Your concern about ambiguity is unnecessary - if you have an ambiguous reference your class won't compile -
e.g.
import java.util.Date;
import java.sql.Date;
public class Test {
private Date date;
}
won't compile. So if you can compile the class then by definition you don't have an ambiguous reference.
Incidentally LibX.Client is a bit confusing. Usually classnames are capitalized, package names lowercased, so if you did that (if LibX was a top-level package and you were giving the full name) it looks more like an inner class reference, as in Andy's response above.
It's possible if you're willing to group Client and Server as static nested classes.
public class LibX {
public static class Client {
//...
}
public static class Server {
//...
}
}
Now you can import mypak.LibX and then do new LibX.Client(). This has the unfortunate drawbacks of forcing you to group your classes and also creating the additional empty LibX class.
There's no such mechanism like what you described. Your only other possibility is to use single class imports:
import com.example.LibX.Client;

Categories