Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Java 8 no longer works #187

Closed
MarkRx opened this issue Jun 16, 2021 · 15 comments
Closed

Java 8 no longer works #187

MarkRx opened this issue Jun 16, 2021 · 15 comments

Comments

@MarkRx
Copy link

MarkRx commented Jun 16, 2021

org.eclipse.platform:org.eclipse.equinox.common:3.15.0 was recently published and it gets pulled in from transitive dependency ranges. As a result attempting to run generateXtext fails on any version of xtend and the gradle plugin with a class version error.

Expected
xtend 2.25.0 and xtext-gradle-plugin 2.0.8 supports compiling java 8

Actual
Using java 8 fails

* Exception is:                                                                                                                                    
org.gradle.api.tasks.TaskExecutionException: Execution failed for task ':generateXtext'.                                                           
        at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter.executeActions(ExecuteActionsTaskExecuter.java:103)                  
        at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter.execute(ExecuteActionsTaskExecuter.java:73)                          
        at org.gradle.api.internal.tasks.execution.OutputDirectoryCreatingTaskExecuter.execute(OutputDirectoryCreatingTaskExecuter.java:51)        
        at org.gradle.api.internal.tasks.execution.SkipUpToDateTaskExecuter.execute(SkipUpToDateTaskExecuter.java:59)                              
        at org.gradle.api.internal.tasks.execution.ResolveTaskOutputCachingStateExecuter.execute(ResolveTaskOutputCachingStateExecuter.java:54)    
        at org.gradle.api.internal.tasks.execution.ValidatingTaskExecuter.execute(ValidatingTaskExecuter.java:59)                                  
        at org.gradle.api.internal.tasks.execution.SkipEmptySourceFilesTaskExecuter.execute(SkipEmptySourceFilesTaskExecuter.java:101)             
        at org.gradle.api.internal.tasks.execution.FinalizeInputFilePropertiesTaskExecuter.execute(FinalizeInputFilePropertiesTaskExecuter.java:44)
                                                                                                                                                   
        at org.gradle.api.internal.tasks.execution.CleanupStaleOutputsExecuter.execute(CleanupStaleOutputsExecuter.java:91)                        
        at org.gradle.api.internal.tasks.execution.ResolveTaskArtifactStateTaskExecuter.execute(ResolveTaskArtifactStateTaskExecuter.java:62)      
        at org.gradle.api.internal.tasks.execution.SkipTaskWithNoActionsExecuter.execute(SkipTaskWithNoActionsExecuter.java:59)                    
        at org.gradle.api.internal.tasks.execution.SkipOnlyIfTaskExecuter.execute(SkipOnlyIfTaskExecuter.java:54)                                  
        at org.gradle.api.internal.tasks.execution.ExecuteAtMostOnceTaskExecuter.execute(ExecuteAtMostOnceTaskExecuter.java:43)                    
        at org.gradle.api.internal.tasks.execution.CatchExceptionTaskExecuter.execute(CatchExceptionTaskExecuter.java:34)                          
        at org.gradle.execution.taskgraph.DefaultTaskGraphExecuter$EventFiringTaskWorker$1.run(DefaultTaskGraphExecuter.java:256)                  
        at org.gradle.internal.operations.DefaultBuildOperationExecutor$RunnableBuildOperationWorker.execute(DefaultBuildOperationExecutor.java:317
)                                                                                                                                                  
        at org.gradle.internal.operations.DefaultBuildOperationExecutor$RunnableBuildOperationWorker.execute(DefaultBuildOperationExecutor.java:309
)                                                                                                                                                  
        at org.gradle.internal.operations.DefaultBuildOperationExecutor.execute(DefaultBuildOperationExecutor.java:185)                            
        at org.gradle.internal.operations.DefaultBuildOperationExecutor.run(DefaultBuildOperationExecutor.java:97)                                 
        at org.gradle.internal.operations.DelegatingBuildOperationExecutor.run(DelegatingBuildOperationExecutor.java:31)                           
        at org.gradle.execution.taskgraph.DefaultTaskGraphExecuter$EventFiringTaskWorker.execute(DefaultTaskGraphExecuter.java:249)                
        at org.gradle.execution.taskgraph.DefaultTaskGraphExecuter$EventFiringTaskWorker.execute(DefaultTaskGraphExecuter.java:238)                
        at org.gradle.execution.taskgraph.DefaultTaskPlanExecutor$TaskExecutorWorker$1.execute(DefaultTaskPlanExecutor.java:104)                   
        at org.gradle.execution.taskgraph.DefaultTaskPlanExecutor$TaskExecutorWorker$1.execute(DefaultTaskPlanExecutor.java:98)                    
        at org.gradle.execution.taskgraph.DefaultTaskExecutionPlan.execute(DefaultTaskExecutionPlan.java:663)                                      
        at org.gradle.execution.taskgraph.DefaultTaskExecutionPlan.executeWithTask(DefaultTaskExecutionPlan.java:596)                              
        at org.gradle.execution.taskgraph.DefaultTaskPlanExecutor$TaskExecutorWorker.run(DefaultTaskPlanExecutor.java:98)                          
        at org.gradle.internal.concurrent.ExecutorPolicy$CatchAndRecordFailures.onExecute(ExecutorPolicy.java:63)                                  
        at org.gradle.internal.concurrent.ManagedExecutorImpl$1.run(ManagedExecutorImpl.java:46)                                                   
        at org.gradle.internal.concurrent.ThreadFactoryImpl$ManagedThreadRunnable.run(ThreadFactoryImpl.java:55)                                   
Caused by: com.google.common.util.concurrent.ExecutionError: com.google.common.util.concurrent.ExecutionError: com.google.common.util.concurrent.Ex
ecutionError: com.google.common.util.concurrent.ExecutionError: com.google.common.util.concurrent.ExecutionError: com.google.common.util.concurrent
.ExecutionError: java.lang.UnsupportedClassVersionError: org/eclipse/core/runtime/OperationCanceledException has been compiled by a more recent ver
sion of the Java Runtime (class file version 55.0), this version of the Java Runtime only recognizes class file versions up to 52.0                
        at com.google.common.cache.LocalCache$Segment.get(LocalCache.java:2199)                                                                    
        at com.google.common.cache.LocalCache.get(LocalCache.java:3934)                                                                            
        at com.google.common.cache.LocalCache.getOrLoad(LocalCache.java:3938)                                                                      
        at com.google.common.cache.LocalCache$LocalLoadingCache.get(LocalCache.java:4821)                                                          
        at com.google.common.cache.LocalCache$LocalLoadingCache.getUnchecked(LocalCache.java:4827)                                                 
        at com.google.inject.internal.FailableCache.get(FailableCache.java:48)                                                                     
        at com.google.inject.internal.ConstructorInjectorStore.get(ConstructorInjectorStore.java:50)                                               
        at com.google.inject.internal.ConstructorBindingImpl.initialize(ConstructorBindingImpl.java:136)                                           
        at com.google.inject.internal.InjectorImpl.initializeJitBinding(InjectorImpl.java:547)                                                     
        at com.google.inject.internal.InjectorImpl.createJustInTimeBinding(InjectorImpl.java:884)                                                  
        at com.google.inject.internal.InjectorImpl.createJustInTimeBindingRecursive(InjectorImpl.java:805)                                         
        at com.google.inject.internal.InjectorImpl.getJustInTimeBinding(InjectorImpl.java:282)                                                     
        at com.google.inject.internal.InjectorImpl.getBindingOrThrow(InjectorImpl.java:214)                                                        
        at com.google.inject.internal.InjectorImpl.getProviderOrThrow(InjectorImpl.java:1006)                                                      
        at com.google.inject.internal.InjectorImpl.getProvider(InjectorImpl.java:1038)                                                             
        at com.google.inject.internal.InjectorImpl.getProvider(InjectorImpl.java:1001)                                                             
        at com.google.inject.internal.InjectorImpl.getInstance(InjectorImpl.java:1051)                                                             
        at org.xtext.gradle.builder.XtextGradleBuilder.<init>(XtextGradleBuilder.java:88)                                                          
        at org.xtext.gradle.builder.XtextGradleBuilderFactory.get(XtextGradleBuilderFactory.java:14)                                               
        at org.xtext.gradle.tasks.internal.IncrementalXtextBuilderProvider.createBuilder(IncrementalXtextBuilderProvider.java:77)                  
        at org.xtext.gradle.tasks.internal.IncrementalXtextBuilderProvider.getBuilder(IncrementalXtextBuilderProvider.java:37)                     
        at org.xtext.gradle.tasks.XtextGenerate.initializeBuilder(XtextGenerate.java:380)                                                          
        at org.xtext.gradle.tasks.XtextGenerate.generate(XtextGenerate.java:163)                                                                   
        at org.gradle.internal.reflect.JavaMethod.invoke(JavaMethod.java:73)                                                                       
        at org.gradle.api.internal.project.taskfactory.IncrementalTaskAction.doExecute(IncrementalTaskAction.java:50)                              
        at org.gradle.api.internal.project.taskfactory.StandardTaskAction.execute(StandardTaskAction.java:39)                                      
        at org.gradle.api.internal.project.taskfactory.StandardTaskAction.execute(StandardTaskAction.java:26)                                      
        at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter$1.run(ExecuteActionsTaskExecuter.java:124)                           
        at org.gradle.internal.operations.DefaultBuildOperationExecutor$RunnableBuildOperationWorker.execute(DefaultBuildOperationExecutor.java:317
)                                                                                                                                                  
        at org.gradle.internal.operations.DefaultBuildOperationExecutor$RunnableBuildOperationWorker.execute(DefaultBuildOperationExecutor.java:309
)                                                                                                                                                  
        at org.gradle.internal.operations.DefaultBuildOperationExecutor.execute(DefaultBuildOperationExecutor.java:185)                            
        at org.gradle.internal.operations.DefaultBuildOperationExecutor.run(DefaultBuildOperationExecutor.java:97)                                 
        at org.gradle.internal.operations.DelegatingBuildOperationExecutor.run(DelegatingBuildOperationExecutor.java:31)                           
        at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter.executeAction(ExecuteActionsTaskExecuter.java:113)                   
        at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter.executeActions(ExecuteActionsTaskExecuter.java:95)                   
        ... 29 more                                                                                                                                
@cdietrich
Copy link
Member

cdietrich commented Jun 16, 2021

see discussions in eclipse/xtext#1976

it should also work to run the build with Java 11 against 8 source&target

@oehme
Copy link
Member

oehme commented Jun 16, 2021

Workaround till the plugin adds the BOM automatically:

configurations.all {
    if (name.contains("Tooling")) {
        dependencies {
            add(name, "org.eclipse.xtend:org.eclipse.xtend.core:$xtextVersion"))
            add(name, platform("org.eclipse.xtext:xtext-dev-bom:$xtextVersion"))
        }
    }
}

@kuniss
Copy link

kuniss commented Jun 24, 2021

@oehme How this workaround could look like for Gradle 4?
I guess, the "platform" concept had been introduced at a later Gradle version. Unfortunately, we are stack to version 4 because Buildship had not finished eclipse/buildship#988 yet.
Thanks for any hint.

(But the problem is the same for ...)

@cdietrich
Copy link
Member

There should be the way to use explicit versions as you can find in a few of the 100 comments in the Xtext issue

@oehme
Copy link
Member

oehme commented Jun 24, 2021

@kuniss you can use resolutionStrategy instead, like @cdietrich did here.

@kuniss
Copy link

kuniss commented Jul 8, 2021

@kuniss you can use resolutionStrategy instead, like @cdietrich did here.

Worked well for me. 🤝

@cdietrich
Copy link
Member

cdietrich commented Aug 27, 2021

i assume to fix this we have to

  • update to gradle 5x
  • update to min Xtext version 2.17.1 (test problem)
  • modernize android plugin/dep or drop it
  • fix a lot of tests with new input validations etc.

maybe we also can use some reflection,
but then we need to find another solution for older xtext versions
https://github.com/xtext/xtext-gradle-plugin/compare/cd_reflectionIdea
maybe for older xtext versions we can
have a enhanced
org.xtext.gradle.tasks.XtextExtension.makeXtextCompatible(Configuration)
which also sets the runtime and equinox common version

@oehme
Copy link
Member

oehme commented Aug 27, 2021

I think the first question should be: How much do we care about keeping support for these outdated Xtext, Gradle and Java versions? I already have a rewrite of the plugin in progress and this is the main open question: What will our minimum requirements be?

@cdietrich
Copy link
Member

cdietrich commented Aug 27, 2021

@oehme i would be perfectly fine with Xtext 2.17.1+ (the first with a dev bom)
but i have no idea how to deal with the ton of test fails i get when updating to gradle 5/7 + Java 8

@oehme
Copy link
Member

oehme commented Aug 27, 2021

The question is: Why support Java 8? Java 11 is the current LTS and has been out forever. We'll soon have the next LTS (Java 17). So spending extra effort to support Java 8 is something I'd need a really good reason for.

@cdietrich
Copy link
Member

Xtext still supports Java 8, so it would be nice to have a fix that also works on Java 8, for Java 11 we can sit out the problem for now, but it will reappear once platform messes with java 17

@oehme
Copy link
Member

oehme commented Aug 27, 2021

Okay, I'll think about an approach that'll keep maximum compatibility for now and just fixes this current issue in a patch release. Independently of this I still want to modernize/simplify this plugin, so that patch might be the last version to support Java 8/Gradle 4 etc.

@cdietrich
Copy link
Member

cdietrich commented Aug 27, 2021

👍
my reflection solution seems to work in my tests, but is a bit ugly, need to test with java 16 though
(the force guice 4 still seems to be a problem)

@MarkRx
Copy link
Author

MarkRx commented Aug 27, 2021

Java 8 is still alive and will remain in use for a long time. It takes time for large companies to upgrade things like this. They also may have support contracts that extend support & security patches beyond the public EOL schedule.

Below is the hotfix plugin I wrote to work around this issue to support Java 8 (and 6 sadly):

package com.paychex.eba.xtextjava6hotfix;

import org.gradle.api.Action;
import org.gradle.api.Plugin;
import org.gradle.api.Project;
import org.gradle.api.artifacts.Configuration;
import org.xtext.gradle.tasks.XtextGenerate;

/**
 * Hotfix that puts java 6 compatible JDT libraries in the front of the classpath used to compile xtend
 */
public class XtextJava6HotfixPlugin implements Plugin<Project> {
    
    @Override
    public void apply(final Project project) {
        final Configuration config = project.getConfigurations().create("xtexthotfix");
        
        project.getDependencies().add("xtexthotfix", "org.eclipse.jdt:org.eclipse.jdt.core:3.10.0");
        
        // 3.15 was compiled with java 11 and because of ranges a transitive dependency ends up picking it up
        project.getDependencies().add("xtexthotfix", "org.eclipse.platform:org.eclipse.equinox.common:3.14.100");
        
        // We need to do after evaluate because of the order that task events are fired. It appears a task is created, 
        // an event is fired, and then the task is configured. We unfortunately need to be notified after a task is
        // configured because we need to access some of the task properties. To work around this we modify the task
        // configuration after the project is evaluated.
        // See https://github.com/gradle/gradle/blob/master/subprojects/core/src/main/java/org/gradle/api/internal/tasks/DefaultTaskContainer.java#L173
        project.afterEvaluate(new Action<Project>() {

            @Override
            public void execute(final Project project) {
                project.getTasks().withType(XtextGenerate.class, new Action<XtextGenerate>() {

                    @Override
                    public void execute(XtextGenerate task) {
                        task.setXtextClasspath(project.files(config, task.getXtextClasspath()));
                    }

                });

            }
        });
    }
}

oehme added a commit that referenced this issue Aug 27, 2021
EMF has open version ranges pulling in whatever the latest core runtime
version is, thereby breaking Java 8 compatibility. This change fixes those
versions back up. For newer Xtext/Gradle versions it uses the Xtext BOM.
For older versions it does some hand-picked version fixes.

To test this properly, we're now not just testing against  different Gradle versions.
I've also raised the maximum versions to the latest ones that we can support without
major test rewrites.

Fixes #187
Fixes #189
oehme added a commit that referenced this issue Aug 28, 2021
EMF has open version ranges pulling in whatever the latest core runtime
version is, thereby breaking Java 8 compatibility. This change fixes those
versions back up. For newer Xtext/Gradle versions it uses the Xtext BOM.
For older versions it does some hand-picked version fixes.

To test this properly, we're now not just testing against  different Gradle versions.
I've also raised the maximum versions to the latest ones that we can support without
major test rewrites.

Fixes #187
Fixes #189
@oehme oehme closed this as completed in 1ffdb7b Aug 28, 2021
@oehme
Copy link
Member

oehme commented Aug 28, 2021

Version 2.0.9 of the plugin fixes this.

oehme added a commit that referenced this issue Aug 31, 2021
Create the xtextTooling Configuration for each SourceSet right away
rather than lazily. This makes it visible in the output of the `dependencies`
task and allows users to easily customize it in their build scripts, e.g.
when there is another issue like #187

Use lazy callback APIs like `eachDependency` (to align versions for Xtext itself)
and `withDependencies` (to add the BOM when that Xtext version has one) instead of
using the Gradle-interna LazilyInitializedFileCollection.

Load all dependencies, including the Xtext languages into the xtextTooling Configuration
so that all version numbers are aligned. Previously it was possible for the xtextLanguages
Configuration to bring in incompatible versions of libraries like eclipse.core.resources,
which was especially visible when trying to use Xcore with this plugin. Now everything
is aligned with the Xtext BOM and/or our dependency resolution rules.

Remove the complicated "classpathInferrer" logic in favor of this new approach.
This also means that the Xtend plugin is now much simpler, since it only needs to add
the xtend.core dependency to the xtextTooling Configurations and that version will automatically
be aligned by our resolution rules.

This raises the minimum Gradle version to 4.7, which seems very reasonable given that the
latest is 7.2.
@kuniss kuniss mentioned this issue Sep 28, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants