Closed laeubi closed 2 weeks ago
When I change the project settings to use Java 17 for example the problem vanishes, compiling with maven/tycho that also uses ecj works without a problem...
I saw this error today playing with one old 1.8 based plugin project containing e4 views that use old injection & annotation libs. Once switched to 17 & updating to jakarta namespace the error went away too.
It might work with any Java 9+ as it is since 9 here:
could it bee that if a dependency is using higher / more recent compile code it becomes an issue?
Today I got a quite strange error in the IDE
The type java.lang.invoke.StringConcatFactory cannot be resolved. It is indirectly referenced from required .class files
but I never use that anywhere in my code.
The only "special" think seems be that my code is using java 1.8 JVM, I already cleaned the project but the project still persist.
There is some class file that has been compiled at a level >=9 - if you use + to concatenate strings, the dependency to StringConcatFactory
gets encoded into the class files for levels >=9
There is some class file that has been compiled at a level >=9 - if you use + to concatenate strings, the dependency to
StringConcatFactory
gets encoded into the class files for levels >=9
How could that be if I have java 1.8 in project settings and clean the project?
How could that be if I have java 1.8 in project settings and clean the project?
One of the project dependencies is compiled with Java 9+?
How could that be if I have java 1.8 in project settings and clean the project?
One of the project dependencies is compiled with Java 9+?
That's what I suspect but the error is really odd/not very helpful and does that mean that one can no longer build code in the IDE for java 1.8 target if one of its dependencies are Java 9+? then I think a specific error message should be emitted mention the offending dependency.
@jarthana, your take on @laeubi's observation here ??
one can no longer build code in the IDE for java 1.8 target
How would you run the code on the 1.8 JRE - the class file version would be to big.
Is the solution to compile against a JRE 9+ but use the --release flag?
I can compile (with Tycho!) without a problem, just the IDE shows these strange "indirectly referenced from required .class files" ... An yes it uses the --release
for this.
I'm having this same issue. For years I had zero issues with Luna and finally upgraded. Now, I import a project from GitHub that I could import before, and I get this. A showstopper. I guess I'm going to give up on upgrading Eclipse.
Similar issue here after I upgrade from 2023-12 to 2024-03 yesterday.
Stuff like:
The type org.apache.commons.logging.Log cannot be resolved. It is indirectly referenced from required type org.springframework.dao.support.DaoSupport
suddenly appears.
Trying to go back to 2023-12 now, since my project is not building anymore. Building on the commandline (Gradle bndtools works fine though).
Similar issue here after I upgrade from 2023-12 to 2024-03 yesterday. Stuff like:
The type org.apache.commons.logging.Log cannot be resolved. It is indirectly referenced from required type org.springframework.dao.support.DaoSupport
suddenly appears.![]()
Trying to go back to 2023-12 now, since my project is not building anymore. Building on the commandline (Gradle bndtools works fine though).
Have you tried the suggestion from @szarnekow to use --release in the IDE? At the moment, I can't think of another solution to this.
Have you tried the suggestion from @szarnekow to use --release in the IDE? At the moment, I can't think of another solution to this.
If you are referring to this checkbox, then yes, it was checked. I think it has always been checked in my case.
I can confirm the errors go away after rolling back from 2024-03 to 2023-12.
Any Update?
I just tested with upcoming Eclipse
Version: 2024-06 M2 (4.32.0 M2)
Build id: 20240502-0722
Update: And with latest I-Build:
Eclipse SDK
Version: 2024-06 (4.32)
Build id: I20240529-1800
The problem is still there.
Any other workaround ideas? I am still on Eclipse 2023-12 where I do not have this problem. But I would like to upgrade :)
I am having the same problem using vscode-java from 1.31.0 (May 30th, 2024).
Edit: turned out my case is not caused by jdt (alone) but rather a misconfiguration in vscode-java, i.e. it does not seem to be caused by jdt but I will nevertheless leave this info here just in case someone else ends up here.
It took me a while to find out how to configure and how to make it stable (survive restarts).
"java.import.gradle.java.home": "/my/jvm/path",
"java.configuration.detectJdksAtStart": false,
"java.configuration.runtimes": [
{
"name": "JavaSE-17",
"path": "/my/jvm/path",
"default": true
}
],
Setting either of these two alone does not solve the problem. Setting JDK Runtime in step 2 solves the problem only for the current session, the setting is lost during restart of VSCode.
This probably deserves a ticket to vscode-java extension.
@jarthana Are you able to reconstruct one or more scenarios where the problem can be observed so we can study options available for us ?
Reading through the bug again it seems to me that the problem is the projects using -target 8
instead of --release 8
and the users of such projects run into troubles executing the code on Java 8 because projects compiled on Java 21 with -target 8
can freely use any Java 9+ API's.
So not sure if that is really compiler issue at all as the compiler just does what it was told by user.
So not sure if that is really compiler issue at all as the compiler just does what it was told by user.
So the user told the compiler to use StringConcatFactory
and then complain it can not be found? :-)
No one complained about the code producing any runtime problems, just the IDE shows strange errors... If its compiled with Java 21 it should be able to resolve StringConcatFactory
with Java 21 as well?
No one complained about the code producing any runtime problems, just the IDE shows strange errors
I believe it would be very handy to have at least one simple reproducer everyone can look at. Any discussion without that is wasted time.
No one complained about the code producing any runtime problems, just the IDE shows strange errors
I believe it would be very handy to have at least one simple reproducer everyone can look at. Any discussion without that is wasted time.
Indeed. The symptom is common and looking at Christoph's scenario, it appears this has nothing to do with StringConcatFactory, or we are dealing with two different issues. It will be good to have the bug extracted into a small workspace or project.
It seems you already have a reproducer:
I saw this error today playing with one old 1.8 based plugin project containing e4 views that use old injection & annotation libs. Once switched to 17 & updating to jakarta namespace the error went away too.
So maybe this can be shared?
It's actually quite easy to reproduce given the discussion above:
This shows a situation where this exact error message is actually justified.
There may be situations where we can avoid touching the sore spot (see #543), but it cannot be eliminated completely.
The type org.apache.commons.logging.Log cannot be resolved. It is indirectly referenced from required type org.springframework.dao.support.DaoSupport suddenly appears.
Nice, finally we see effect of #327. @chrisrueger , does this help to trace the causality?
DaoSupport
needs Log
?DaoSupport
?@stephan-herrmann thanks for the .zip reproducer:
When I import this in my (old) Eclipse 2023-12 (!) (this is the Eclipse still working) then I see this:
This appears right after import the "Existing projects into Workspace". My Eclipse had JDK21 as default JRE.
Description Resource Path Location Type
The project was not built since its build path is incomplete. Cannot find the class file for java.lang.invoke.StringConcatFactory. Fix the build path then try building this project Client_1_8 Unknown Java Problem
The type java.lang.invoke.StringConcatFactory cannot be resolved. It is indirectly referenced from required type p17.LibClass Client.java /Client_1_8/src/p_1_8 line 7 Java Problem
When I change default JRE to JDK17 the error changes to:
Description Resource Path Location Type
The method m(StringConcatFactory) is ambiguous for the type LibClass Client.java /Client_1_8/src/p_1_8 line 7 Java Problem
Now I try the same with eclipse-SDK-I20240529-1800:
Default JRE JDK21:
Default JRE JDK17:
I notice that this is different than on Eclipse 2023-12, because I do not see the errror "The type java.lang.invoke.StringConcatFactory cannot be resolved. It is indirectly referenced from required type "
BUT:
When I then manually change the Execution Environment to JDK 1.8.
then the 2 errors are back:
Description Resource Path Location Type
The project was not built since its build path is incomplete. Cannot find the class file for java.lang.invoke.StringConcatFactory. Fix the build path then try building this project Client_1_8 Unknown Java Problem
The type java.lang.invoke.StringConcatFactory cannot be resolved. It is indirectly referenced from required type p17.LibClass Client.java /Client_1_8/src/p_1_8 line 7 Java Problem
Both happens regardless if Eclipse Preferences Default JRE is still on JDK 17 , JDK 21, JDK 1.8).
- can you see why
DaoSupport
needsLog
?- can you see why your application needs
DaoSupport
?
We have a abstract class AbstractHibernateDAOImpl<T extends PersistentObject> extends HibernateDaoSupport
import org.springframework.orm.hibernate5.support.HibernateDaoSupport;
and HibernateDaoSupport
looks like this public abstract class org.springframework.orm.hibernate5.support.HibernateDaoSupport extends org.springframework.dao.support.DaoSupport
and org.springframework.dao.support.DaoSupport
imports import org.apache.commons.logging.Log
see https://github.com/spring-projects/spring-framework/blob/main/spring-tx/src/main/java/org/springframework/dao/support/DaoSupport.java#L19
I don't know how to answer the "why" other than: "because that's what our application does since ten years :)" It works in Eclipse 2023-12. Starting with Eclipse 2024-03 we see the error and cannot use the newer Eclipses anymore.
- can you see why
DaoSupport
needsLog
?- can you see why your application needs
DaoSupport
?We have a
abstract class AbstractHibernateDAOImpl<T extends PersistentObject> extends HibernateDaoSupport
import org.springframework.orm.hibernate5.support.HibernateDaoSupport;
and
HibernateDaoSupport
looks like thispublic abstract class org.springframework.orm.hibernate5.support.HibernateDaoSupport extends org.springframework.dao.support.DaoSupport
and
org.springframework.dao.support.DaoSupport
importsimport org.apache.commons.logging.Log
see https://github.com/spring-projects/spring-framework/blob/main/spring-tx/src/main/java/org/springframework/dao/support/DaoSupport.java#L19
Thanks, so looking for the missing class is not completely unfounded. The remaining, interesting question is: is type Log
necessary for analysing your own code? This typically happens, when the type appears in some member signature which needs to be resolved in order to determine legality of your code.
The fact that you have the dependency (regarding Log
) directly in a superclass (DaoSupport
) of your own class (AbstractHibernateDAOImpl
) makes it hard not to touch that dependency.
Seeing this field:
/** Logger available to subclasses. */
protected final Log logger = LogFactory.getLog(getClass());
actually indicates that the author assumed that subclasses have type Log
in their dependencies, too! When subclassing DaoSupport
type Log
is also part of your own API.
Found a solution
I am using bndtools / OSGi.
In the bundle which had the Eclipse error in the Problems view I had to add the dependency to the -buildpath
in bnd.bnd
BundleA:
-buildpath:
org.apache.commons.logging
Then commons-logging-1.2.jar
appeared on the Bnd Bundle Path
and the error was gone:
Now I went back to the old Eclipse 2023-12 and checked how the Bnd bundle path
looked before when org.apache.commons.logging
was not explicitly added to the -buildpath
in bnd.bnd
:
Bnd bundle path was indeed not showing the commons-logging-1.2.jar
but the error does not appear.
It seems newer Eclipse >= 2024-03 is "stricter" and you need to add bundles to your -buildpath in bnd.bnd which maybe required indirectly e.g. by classes you are inheriting from (like protected members of 3rd pary classes which you are subclassing in your code, although your code does not use the inherited member directly). This was not needed before in Eclipse <= 2023-12
Mentioning @pkriens of bndtools to make him aware. Not sure if there is anything bndtools needs to do based on this observation.
Update: I just wanted to highlight a subtle difference in error messages which I observed in this discussion:
The discussion starts with the error:
The type java.lang.invoke.StringConcatFactory cannot be resolved. It is indirectly referenced from required .class files
vs. in my case I got:
The type org.apache.commons.logging.Log cannot be resolved. It is indirectly referenced from required type
...
Notice the .class
vs. type
at the end of the messages. I did not notice this in the beginning. Sorry if I diluted this discussion. Maybe my problem is a different one than the original posted.
It seems newer Eclipse >= 2024-03 is "stricter" ...
lots of things in a compiler are "demand-driven", such that small implementation changes can cause differences in which class files are needed during analysis. I don't think any specification exists, which defines a boundary between classes visible to the compiler and classes that it must not touch (although at runtime they need to be present).
A decent module system might actually report some of these situations as API-leaks: accessibility of members with inaccesible type.
In the end it's always a matter of "best-effort" trying to cope with missing classes based on some judgement that their absence will not affect the compilation outcome.
Update: I just wanted to highlight a subtle difference in error messages which I observed in this discussion:
The discussion starts with the error:
The type java.lang.invoke.StringConcatFactory cannot be resolved. It is indirectly referenced from required .class files
vs. in my case I got:
The type org.apache.commons.logging.Log cannot be resolved. It is indirectly referenced from required type
...Notice the
.class
vs.type
at the end of the messages. I did not notice this in the beginning. Sorry if I diluted this discussion. Maybe my problem is a different one than the original posted.
The variant with .class
is the old message. Since #327 we try to report where the failing lookup was triggered. Still seeing the old message only means that the addition from #327 did not provide any additional information.
So at face value both are reporting the same problem, but yes, the more general "from required .class files" indicates that perhaps the path to the missing type was more obscure.
lots of things in a compiler are "demand-driven", such that small implementation changes can cause differences in which class files are needed during analysis. I don't think any specification exists, which defines a boundary between classes visible to the compiler and classes that it must not touch (although at runtime they need to be present).
A decent module system might actually report some of these situations as API-leaks: accessibility of members with inaccesible type.
In the end it's always a matter of "best-effort" trying to cope with missing classes based on some judgement that their absence will not affect the compilation outcome.
Thanks for the explanation. It wasn't my intent to negatively criticize this. I was just surprised. and often when something stops working as before, the initial reflex is to think this is a bug :)
But now that I know, I can react and solve our problem.
One question out of curiosity:
How (or why) was it decided that this should be an error
vs be a warning
?
One question out of curiosity: How (or why) was it decided that this should be an
error
vs be awarning
?
I cannot say about the original decision, which happened before Eclipse became open source :)
What I can say is that this problem is classified as a build path problem. And generally all build path errors should be resolved before all other problems. Build path problems can be the root of various errors, so reporting with lesser severity would make people try to solve secondary problems before they even see the report of the (assumed) root cause.
OK thanks. Just want to say: My problem is solved. Not sure if this is the case for the initial report by @laeubi
Not sure if this is the case for the initial report by @laeubi
I think my problem is actually different, as far as I understood the discussion here your code "suddenly" required (indirectly) a user type, this always has been the case and as far as I know bnd tools even has a Quickfix for that (PDE should now as well for Automatic Manifest projects).
So even if the error message is similar the cause is different here as JDT complains about something from java.lang
that is never used in the code anywhere (just indirectly due to compiler optimization) this should simply always be accessible and seems not very helpful to the user.
I see some options to really resolve this:
java.lang
and hope for the best that another error show up or it actually is not an issue at allStringConcatFactory
if it cannot be foundAlso it should be investigated if something in the compiler is using StringConcatFactory
even though the source / target / .... is < 9 even though strictly it is allowed it seems not very useful and waiting for bad things to happen.
So even if the error message is similar the cause is different here as JDT complains about something from
java.lang
that is never used in the code anywhere (just indirectly due to compiler optimization)
why do you say optimization? The main reason for loading referenced class files is for correctness of the compilation result.
1. Ignore any non resolvable Type of `java.lang` and hope for the best that another error show up or it actually is not an issue at all
ignoring an error and hoping for something doesn't sound like a strategy suitable for a compiler, if you ask me.
2. Have a polyfill type for `StringConcatFactory` if it cannot be found
from a compiler p.o.v. I don't see reason why this particular class should get special treatment.
As we know that this error message can be caused by a wide range of possible situations, I'd love to analyse your specific problem using a minimal reproducer.
Until we have a reproducer I'll focus on #543 instead.
why do you say optimization?
Oracle/Java/JDK says that
Methods to facilitate the creation of String concatenation methods, that can be used to efficiently concatenate a known number of arguments of known types
So obviously there is (a less efficient) alternative or something else that was used before Java 9+
from a compiler p.o.v. I don't see reason why this particular class should get special treatment.
Again the javadoc gives some hint:
These methods are typically used as bootstrap methods for invokedynamic call sites, to support the string concatenation feature of the Java Programming Language.
So I (as a user) can't influence what the compiler emits here as I don't use this type anywhere in my code, it is more like a special byte-code instruction / built in, so I would expect it to only be used when the compiler is sure it can be used (Java >= 9) in contrast when I reference a Type in my sourceode where the compiler must use that.
That's why I think special treatment would be justified here as it is more a "language feature (Java doc says See The Java™ Language Specification: 5.1.11 String Conversion, 15.18.1 String Concatenation Operator +
) than a regular classpath type.
Thanks, @laeubi now I see where you are coming from. You seem to say that the compiler chose an optimization strategy in a configuration where the class required for that strategy is not available.
That's not, however, how I read the error.
The type java.lang.invoke.StringConcatFactory cannot be resolved. It is indirectly referenced from required .class files
Saying "indirectly referenced from required .class files" seems to indicate the following two-step scenario:
X.class
) was generated that legitimately refers to class StringConcatFactory
Y
was compiled, where the source code mentions X
in one way or other.
StringConcatFactory
is no-where to be foundX.class
in a way that requires lookup of StringConcatFactory
It's this "something" we need to know in order to investigate, in order to see whether or not StringConcatFactory
is actually needed for compiling Y
.
Y
does not allow you to use X
in the way you doStringConcatFactory
Thanks for the additional explanation @stephan-herrmann
in a separate compiler invocation another class Y was compiled, where the source code mentions X in one way or other. in this second invocation class StringConcatFactory is no-where to be found something still causes the compiler to analyse X.class in a way that requires lookup of StringConcatFactory
As it is a very special java class, one might think about that if the compiler find java.lang.StringConcatFactory
but can't look it up I think there are two ways:
StringConcatFactory
looks like, one could simply use some polyfill type that is simulating the type is there, this is a very common practice in backward compatibility scenarios.X.class
and maybe even from wehre it was loaded e.g. X.class (previously loaded from X-lib.jar) requires Java 9+ and Y indirectly references it but currently is compiled for Java 1.8
As it is a very special java class, one might think about
Should we focus on addressing the special symptom regarding StringConcatFactory, or on finding the root cause that also affects many other situations?
I very much prefer solving root causes than introducing kludges for specific situations (without having understood their root cause).
Thinking of better diagnostics is of course a useful approach, that's what we did in #327 already, and I'm surprised that your issue is not helped, i.e., in your case we are unable to provide the additional information.
So here's a proposal: we could introduce a "hidden" flag via a system property that will let the compiler print more debug information (mostly: stacktrace) to console when the problem occurs. Will you be able to reproduce the problem with a compiler from a PR or I-Build and report back any stacktraces that will be printed with that flag enabled?
Otherwise I would wait what happens first:
Should we focus on addressing the special symptom regarding StringConcatFactory, or on finding the root cause that also affects many other situations?
The situation is that one see the error when the project uses Java 1.8 and goes away once one uses a higher Java version, so I'm not sure what else should be the root cause than that Java 1.8 does not has StringConcatFactory
... sadly I currently have no reproducer as back then I just raised the java version...
I'm not sure what else should be the root cause than that Java 1.8 does not has
StringConcatFactory
Let's call this the surface cause.
What we need is understanding why the compiler considers StringConcatFactory
necessary for compilation in that particular setup:
@laeubi may we close this, since (a) #2543 reduced the effect of missing types and (b) we don't seem to have a reproducer?
I don't see anything we can reasonably do here. Closing.
Today I got a quite strange error in the IDE
but I never use that anywhere in my code.
The only "special" think seems be that my code is using java 1.8 JVM, I already cleaned the project but the project still persist.