eclipse-pde / eclipse.pde

Eclipse Public License 2.0
28 stars 74 forks source link

"build.properties does not exist" warning on no-PDE projects #1185

Closed jukzi closed 5 months ago

jukzi commented 7 months ago

Happens in platform workspace and is also asked often on Stackoverflow image It is produced by ManifestConsistencyChecker - no idea why it runs on non-PDE projects, Anybody an idea? otherwise i would just add a doublecheck that it does nothing when the project has no plugin nature.

merks commented 7 months ago

It's strange and annoying because it seems like an intermittent problem. Have you been able to reproduce it in a debug launch? I failed in that effort last I tried.

jukzi commented 7 months ago

Have you been able to reproduce it in a debug launch?

I was not able to reproduce it in debug or manual set up projects. Best thing i can offer is to double check and may be log an IllegalStateexception to get a stacktrace how it happens. it is only supposed to run when there is a

        <buildCommand>
            <name>org.eclipse.pde.ManifestBuilder</name>
            <arguments>
            </arguments>
        </buildCommand>
    <natures>
        <nature>org.eclipse.pde.PluginNature</nature>
    </natures>

in the .project and since normally that seems to hold the error is never removed even if the workspace rebuilds (because such project are not build)

(see projectToBuild.hasNature(PDE.PLUGIN_NATURE) in org.eclipse.pde.internal.ui.preferences.PDECompilersConfigurationBlock.doFullBuild().new Job() {...}.run(IProgressMonitor)

laeubi commented 7 months ago

Happens in platform workspace and is also asked often on Stackoverflow

Is there a link / reproducer? I'm not sure I really understand when it happens, e.g if the builder is configured for the project or has this projects no builder and no nature at all?

tivervac commented 6 months ago

Just want to confirm that I experienced the same in our company's workspace. Sadly, I have no reproducer.

I got it on the .JETEmitters project, which only has the javabuilder build command and the java nature. Other projects which have false positives even have no builders and no natures.

merks commented 6 months ago

Yes, I keep getting this problem too, on many projects, but it kind of comes and goes. Yesterday my Oomph environment has that, but a clean build make it go away.

jubax commented 6 months ago

I seem to have the same problem. After I installed a new default Java runtime I suddenly got

image

in all my projects. I'm using the J2EE bundle and I'm not doing Eclipse plug-in development. Before seeing this issue I uninstalled maven and PDE (I don't need those), but this did not change anything.

Eclipse version: 2024-03.

merks commented 6 months ago

If you uninstalled, likely nothing will ever remove the errors. Deleting them will be necessary once.

minduch commented 6 months ago

It happens to me all the time in Eclipse 2024-06 M1 Comitters version, in projects that doesn't require a build.properties file. The warning is also still there if I add this file! Example projects are: plain Java, or just a plain Project, and others (it's correct and works fine for plugin projects).

BTW: I have noticed that the call hasNature(String natureId) have returned true even if the project didn't have this nature. This happened first time I saw it in Eclipse 2023-12 and 2024-03, but it was not all the time, and eventually we worked around it in another way. We grabbed the nature instance of the project that should have been a Java project, then cast it to IJavaProject. That no longer works, so we had to use JavaCore to get a new IJavaProject instance instead from the IProject instance.

Our code now:

  /**
   * Checks if a Project is of Java Nature.
   * 
   * @param project  The project to check.
   * 
   * @return {@code true} if the nature {@link JavaCore#NATURE_ID} is present, {@code false} otherwise.
   * 
   * @throws CoreException  If project nature could'nt be retrieved, or if it is not accessible (closed perhaps). 
   */
  public static boolean hasJavaNature(IProject project) throws CoreException
    {
    if ( !project.isAccessible() )
      throw new CoreException(Activator.createErrorStatus(ERR_PROJECT_CLOSED));

    return project.hasNature(JavaCore.NATURE_ID);
    }

  /**
   * Gets the Java Project from a Project.
   * 
   * @return The Java project.
   * 
   * @throws CoreException  If project nature could'nt be retrieved. 
   */
  public static IJavaProject getJavaProject(IProject project) throws CoreException
    {
    if ( !hasJavaNature(project) )
      throw new CoreException(Activator.createErrorStatus("Project is not of Java Nature"));

    // Get Java project: must work!
    IProjectNature nature=project.getNature(JavaCore.NATURE_ID);
    try
      {
      try
        {
        // This used to work up until Eclipse 2024-xx when it suddenly stopped!
        return (IJavaProject)nature;
        }
      catch(ClassCastException e)
        {
        // This way, at least a JavaProject is created...
        return JavaCore.create(project);
        }
      }
    catch(Throwable t)
      {
      throw new CoreException(Activator.createErrorStatus(ERR_PROJECT_CLOSED,t));
      }
    }
minduch commented 6 months ago

OK, so there might be a hint here: I opened another workspace that contained only plain and Java projects, along with two plug-in projects, without Maven (Tycho), then I didn't get the warning about missing build.properties file. Note: I'm using Eclipse 2024-06 M1.

The only two plugin projects has build.properties files as they should, the other did not...

Plugin projects like:

<?xml version="1.0" encoding="UTF-8"?>
<projectDescription>
    <name>com.netphantom.eclipse.common</name>
    <comment></comment>
    <projects>
    </projects>
    <buildSpec>
    </buildSpec>
    <natures>
        <nature>org.eclipse.jdt.core.javanature</nature>
        <nature>org.eclipse.pde.PluginNature</nature>
    </natures>
</projectDescription>

Java projects as:

<?xml version="1.0" encoding="UTF-8"?>
<projectDescription>
    <name>Client</name>
    <comment></comment>
    <projects>
    </projects>
    <buildSpec>
        <buildCommand>
            <name>org.eclipse.jdt.core.javabuilder</name>
            <arguments>
            </arguments>
        </buildCommand>
    </buildSpec>
    <natures>
        <nature>org.eclipse.jdt.core.javanature</nature>
    </natures>
</projectDescription>

Other projects as:

<?xml version="1.0" encoding="UTF-8"?>
<projectDescription>
    <name>Install</name>
    <comment></comment>
    <projects>
    </projects>
    <buildSpec>
    </buildSpec>
    <natures>
    </natures>
</projectDescription>
jukzi commented 6 months ago

BTW: I have noticed that the call hasNature(String natureId) have returned true even if the project didn't have this nature.

That ProjectDescription.natures seems not to be multithreading save, i will suggest a PR

laeubi commented 6 months ago

BTW: I have noticed that the call hasNature(String natureId) have returned true even if the project didn't have this nature.

That ProjectDescription.natures seems not to be multithreading save, i will suggest a PR

Can you please explain where multiple threads are involved here?

jukzi commented 6 months ago

Can you please explain where multiple threads are involved here?

eclipse ide is multithreaded. any thread can call get/set on that natures

laeubi commented 6 months ago

Can you please explain where multiple threads are involved here?

eclipse ide is multithreaded. any thread can call get/set on that natures

That's a general purpose statement like "eclipse ide uses java" if we use this as a general development guideline then we need to effectively sync everything everywhere... especially in this case, the project description will be read exactly once and nothing in this thread indicates that the natures are ever changed.

szarnekow commented 6 months ago

I think what may happen (to be confirmend in practice):

See org.eclipse.core.internal.resources.Project.basicSetDescription(ProjectDescription, int) which could run concurrently with org.eclipse.core.internal.resources.Project.getDescription() and both will work with the same instance obtained from Project.internalGetDescription() The former will modify the fields of the ProjectDescription, the latter will clone the object.

szarnekow commented 6 months ago

A possible solution would be to clone the current description, update it with the values of the new description and set it atomically on the ProjectInfo.

ProjectInfo.description must be marked as volatile in that case, though.

jukzi commented 6 months ago

we need to effectively sync everything everywhere..

Thats exactly what java demands: either make sure your data is private and accessed single threaded only or use concurrent datastructures :-(

especially in this case, the project description will be read exactly once and nothing in this thread indicates that the natures are ever changed.

Even the initialize technically would be an update that can go wrong without a final keyword, but there is not even a initializer on the natures field but setter access only.

laeubi commented 5 months ago

This now gives false positive errors:

eclipse.buildId=4.32.0.I20240512-1800
java.version=17.0.2
java.vendor=Oracle Corporation
BootLoader constants: OS=linux, ARCH=x86_64, WS=gtk, NL=de_DE
Command-line arguments:  -os linux -ws gtk -arch x86_64 -console -consoleLog -data file:/opt/eclipse/platform-sdk/ws/

org.eclipse.pde.core
Error
Mon May 13 08:24:06 CEST 2024
eclipse.pde/issues/1185: validateBuildPropertiesExists called for project without plugin nature: org.eclipse.ui.tests.feature

java.lang.IllegalStateException
    at org.eclipse.pde.internal.core.builders.ManifestConsistencyChecker.validateBuildPropertiesExists(ManifestConsistencyChecker.java:382)
    at org.eclipse.pde.internal.core.builders.ManifestConsistencyChecker.validateProjectStructure(ManifestConsistencyChecker.java:299)
    at org.eclipse.pde.internal.core.builders.ManifestConsistencyChecker.validateProject(ManifestConsistencyChecker.java:252)
    at org.eclipse.pde.internal.core.builders.ManifestConsistencyChecker.build(ManifestConsistencyChecker.java:195)
    at org.eclipse.core.internal.events.BuildManager$2.run(BuildManager.java:1077)
    at org.eclipse.core.runtime.SafeRunner.run(SafeRunner.java:47)
    at org.eclipse.core.internal.events.BuildManager.basicBuild(BuildManager.java:296)
    at org.eclipse.core.internal.events.BuildManager.basicBuild(BuildManager.java:468)
    at org.eclipse.core.internal.events.BuildManager.build(BuildManager.java:670)
    at org.eclipse.core.internal.resources.Project$1.run(Project.java:604)
    at org.eclipse.core.internal.resources.Workspace.run(Workspace.java:2448)
    at org.eclipse.core.internal.resources.Project.internalBuild(Project.java:642)
    at org.eclipse.core.internal.resources.Project.build(Project.java:162)
    at org.eclipse.pde.internal.core.MinimalState.reloadSystemPackagesIntoState(MinimalState.java:341)
    at org.eclipse.pde.internal.core.MinimalState$2.runInWorkspace(MinimalState.java:313)
    at org.eclipse.core.internal.resources.InternalWorkspaceJob.run(InternalWorkspaceJob.java:43)
    at org.eclipse.core.internal.jobs.Worker.run(Worker.java:63)

org.eclipse.ui.tests.feature is a feature and features can contain build.properties as it is required for the bin.includes

laeubi commented 5 months ago

I have now been able to reproduce the problem and will provide a PR soon one need the following setup:

Now one must delete the build.properties files of the projects, set a breakpoint at org.eclipse.pde.internal.core.builders.ManifestConsistencyChecker.validateBuildPropertiesExists(IProject) after the file.exits check.

Now go to the JDK preferences and choose another JDK as the default (e.g. Java 21 if currently Java 17 is the default), this will trigger a rebuild of both projects and the checker complains that both projects have a missing build.properties file even though only the Plugin Project has the builder explicitly enabled, this is because org.eclipse.pde.internal.core.MinimalState.reloadSystemPackagesIntoState() request a build with the ManifestBuilder on projects that don't have configured it.

laeubi commented 5 months ago

I'll consider this fixed unless someone can provide a new stack trace from the error log view here.

Be aware that likely one needs to delete the warnings once manually as there is no one who will clean them automatically.

merks commented 5 months ago

Yes, definitely one needs to remove the warnings manually. Even a clean does not remove them.