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

How to handle extra classpath from generated code #177

Open
minkyn opened this issue Apr 1, 2017 · 48 comments
Open

How to handle extra classpath from generated code #177

minkyn opened this issue Apr 1, 2017 · 48 comments

Comments

@minkyn
Copy link

minkyn commented Apr 1, 2017

I'm using Google's AutoValue and Protocol Buffer, both which generate source code under build/generated/source/.... However, each time I start vscode, this java plugin would automatically create a new .classpath file that overrides my manual edit.

Is the plugin going to handle the generated source code? Is there a workaround for now? Thanks.

@fbricon
Copy link
Collaborator

fbricon commented Apr 1, 2017

Are you using Maven or Gradle?
With Maven, if you configure build-helper-maven-plugin, vscode-java 0.1.0 should setup the classpath accordingly.

Could you please attach a sample project?

@fbricon
Copy link
Collaborator

fbricon commented May 30, 2017

@minkyn ping. See previous comment

@fbricon
Copy link
Collaborator

fbricon commented Aug 24, 2017

That seems like a duplicate of #285. @minkyn are you using gradle?

@IzakMarais
Copy link

I have the same problem when using Maven to generate protocol buffer sources.

Source files are generated like so in the pom:

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-dependency-plugin</artifactId>
    <version>3.0.1</version>
    <executions>
        <execution>
            <id>unpack-proto-dependencies</id>
            <phase>generate-sources</phase>
            <goals>
                <goal>unpack-dependencies</goal>
            </goals>
            <configuration>
                <includeArtifactIds>artifact-name-here</includeArtifactIds>
                <excludeTransitive>true</excludeTransitive>
                <overWrite>true</overWrite>
                <outputDirectory>${project.build.directory}/generated-sources/proto</outputDirectory>                            
                <overWriteReleases>true</overWriteReleases>
                <overWriteSnapshots>true</overWriteSnapshots>
            </configuration>
        </execution>
    </executions>
</plugin>

we event try to add it to the test class path like so (not needed for mvn install to work).

<plugin>
    <!-- a hint for IDE's to add the java sources to the classpath -->
    <groupId>org.codehaus.mojo</groupId>
    <artifactId>build-helper-maven-plugin</artifactId>
    <version>3.0.0</version>
    <executions>
        <execution>
            <id>01-add-test-sources</id>
            <phase>generate-test-sources</phase>
            <goals>
                <goal>add-test-source</goal>
            </goals>
            <configuration>
                <sources>
                    <source>${project.build.directory}/generated-sources/protobuf/java</source>
                </sources>
            </configuration>
        </execution>
    </executions>
</plugin>    

@IzakMarais
Copy link

The problem is compounded by interaction with #322. Since I often need to close VSCode to get tests to run, the classpath gets messed up often.

@unguiculus
Copy link

There seems to be support specifically for build-helper-maven-plugin. However, there are lots of plugins which generate sources and add them to the classpath, usually under target/generated-sources. In this case, build-helper-maven-plugin is not required. VS Code should automatically recognize this. Directories like target/generated-sources and target/generated-resources could be automatically added. Alternatively, an option to configure additional classpath folders per Maven module would be welcome.

@samba2
Copy link

samba2 commented Apr 9, 2019

Same here. We generate Pojos for XML schemas using the jaxb2-maven-plugin. By default does classes are placed in target/generated-sources/jaxb/com/mypackage/MyGeneratedClass.java

Is there a chance to add a classpath by hand in VC code?

@rfgamaral
Copy link

There seems to be support specifically for build-helper-maven-plugin. However, there are lots of plugins which generate sources and add them to the classpath, usually under target/generated-sources. In this case, build-helper-maven-plugin is not required. VS Code should automatically recognize this. Directories like target/generated-sources and target/generated-resources could be automatically added. Alternatively, an option to configure additional classpath folders per Maven module would be welcome.

@fbricon Any comments on the above?

I have this work project that places a few packages inside target/generated-sources and target/generated-resources and these are not being picked up by the plugin. Making it impossible for me to use VS Code with these Java projects.

@rmannibucau
Copy link

Hello,

Any hope this issue gets addressed? It prevents to use java-templating plugin, CXF plugins, and a bunch of other plugins.

Thanks a lot for the hard work,
Romain

@fbricon
Copy link
Collaborator

fbricon commented Jun 3, 2019

Sure, we'll investigate this in the near feature. Can't commit to a timeframe though.

@fbricon
Copy link
Collaborator

fbricon commented Jun 3, 2019

Guys, if you want to make sure your use case is covered eventually, please add some small sample projects using various maven plugins contributing source folders.

@rmannibucau
Copy link

@fbricon here it is https://github.com/rmannibucau/generated-sources-demo, just try to code/compile in Main.java through vscode (works in CLI), it will miss the two generated folder created by java-templating and wadl cxf plugin.

@fbricon
Copy link
Collaborator

fbricon commented Jun 3, 2019

@rmannibucau I cloned it, ran a CLI build, opened vscode, the source folders have been added to the classpath automatically:

<?xml version="1.0" encoding="UTF-8"?>
<classpath>
	<classpathentry kind="src" output="target/classes" path="src/main/java">
		<attributes>
			<attribute name="optional" value="true"/>
			<attribute name="maven.pomderived" value="true"/>
		</attributes>
	</classpathentry>
	<classpathentry kind="src" output="target/classes" path="target/generated-sources/java-templates">
		<attributes>
			<attribute name="optional" value="true"/>
			<attribute name="maven.pomderived" value="true"/>
		</attributes>
	</classpathentry>
	<classpathentry kind="src" output="target/classes" path="target/generated/src/main/java">
		<attributes>
			<attribute name="optional" value="true"/>
			<attribute name="maven.pomderived" value="true"/>
		</attributes>
	</classpathentry>
	<classpathentry kind="src" output="target/test-classes" path="src/test/java">
		<attributes>
			<attribute name="optional" value="true"/>
			<attribute name="maven.pomderived" value="true"/>
			<attribute name="test" value="true"/>
		</attributes>
	</classpathentry>
	<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8">
		<attributes>
			<attribute name="maven.pomderived" value="true"/>
		</attributes>
	</classpathentry>
	<classpathentry kind="con" path="org.eclipse.m2e.MAVEN2_CLASSPATH_CONTAINER">
		<attributes>
			<attribute name="maven.pomderived" value="true"/>
		</attributes>
	</classpathentry>
	<classpathentry kind="src" path="target/generated-sources/annotations">
		<attributes>
			<attribute name="optional" value="true"/>
			<attribute name="maven.pomderived" value="true"/>
			<attribute name="ignore_optional_problems" value="true"/>
			<attribute name="m2e-apt" value="true"/>
		</attributes>
	</classpathentry>
	<classpathentry kind="src" output="target/test-classes" path="target/generated-test-sources/test-annotations">
		<attributes>
			<attribute name="optional" value="true"/>
			<attribute name="maven.pomderived" value="true"/>
			<attribute name="ignore_optional_problems" value="true"/>
			<attribute name="m2e-apt" value="true"/>
			<attribute name="test" value="true"/>
		</attributes>
	</classpathentry>
	<classpathentry kind="output" path="target/classes"/>
</classpath>

@rmannibucau
Copy link

Hmm, does it mean it needs m2 lifecycle mapping plugin? Or do you use a dev version?
Can you also drop target/classes and give it another try?

@fbricon
Copy link
Collaborator

fbricon commented Jun 3, 2019

for the sources to be regenerated on incremental build, an m2e lifecycle mapping/connector would need to be required yes.
But if the sources are generated outside vscode (CLI build for instance), in theory we should be able to recover from the compilation errors by refreshing the compilation units on the server side. But those generated sources are not detected because of a hack we had to introduce to prevent nasty feedback loops between jdt.ls and vscode. jdt.ls would generate the sources automatically (from annotation processing), vscode detects the changes, sending change deltas back to the server, messing up the compilation units, causing weird error reports. So I guess we need to be smarter in that case.

@rfgamaral
Copy link

I seem to have a slightly different issue, but related, I think.

I'm not a Java developer and my Java/Maven knowledge is very limited. But my team inherited this Java project which we'll be working on the frontend side only. The project works fine with IntelliJ and we can use that to work on the project but I'm trying to setup this with VS Code cause it's our editor of choice for frontend.

The problem is that this Java project is configured with an internal Maven plugin that generates sources (so I can't post a sample project) and places them at target/generated-sources/java and this plugin is not picking that for the classpath, but IntelliJ does.

Maybe the issue here is that the generated sources come from a custom internal plugin and not something like templating-maven-plugin as in the sample project posted by @rmannibucau?

I was able to workaround it with something like this:

<plugin>
    <groupId>org.codehaus.mojo</groupId>
    <artifactId>build-helper-maven-plugin</artifactId>
    <version>3.0.0</version>
    <executions>
        <execution>
            <id>addSource</id>
            <phase>generate-sources</phase>
            <goals>
                <goal>add-source</goal>
            </goals>
            <configuration>
                <sources>
                    <source>${project.basedir}/target/generated-sources/java</source>
                </sources>
            </configuration>
        </execution>
    </executions>
</plugin>

But it would be much better if, somehow, this plugin could pick whatever is at ${project.basedir}/target/generated-sources/java by default and automatically since that seems to be a standard folder for generated sources?

@fbricon
Copy link
Collaborator

fbricon commented Jun 4, 2019

No it's not a standard folder. Multiple plugins generate different content in subdirectories of ${project.basedir}/target/generated-sources. Having 2 plugins writing content to the same directory (target/generated-sources/java) might cause some issues (one plugin overwriting the other one's output)

@rmannibucau
Copy link

This is a common default for annotation processors but not for generating sources plugin so nothing better than adding a source folder in vscode or supporting lifecycle mapping - but not sure it is that great to use eclipse here :s

@rfgamaral
Copy link

Having 2 plugins writing content to the same directory (target/generated-sources/java) might cause some issues (one plugin overwriting the other one's output)

Not sure what you mean by this, but I only have 1 plugin writing content to target/generated-sources/java, it's just not being picked up by vscode-java unless I make it aware with the build-helper-maven-plugin plugin configuration above.

@agsimeonov
Copy link

Similar issue here. We do a

<plugin>
    <groupId>org.codehaus.mojo</groupId>
    <artifactId>build-helper-maven-plugin</artifactId>
    <version>3.0.0</version>
    <executions>
        <execution>
            <id>add-integration-test-source</id>
            <phase>generate-test-sources</phase>
            <goals>
                <goal>add-test-source</goal>
            </goals>
            <configuration>
                <sources>
                    <source>src/integration-test/java</source>
                </sources>
            </configuration>
        </execution>
        <execution>
            <id>add-integration-test-resource</id>
            <phase>generate-test-resources</phase>
            <goals>
                <goal>add-test-resource</goal>
            </goals>
            <configuration>
                <resources>
                    <resource>
                        <directory>src/integration-test/resources</directory>
                    </resource>
                </resources>
            </configuration>
        </execution>
    </executions>
</plugin>

When trying to run/debug tests from within VSCode that fall under src/integration-test/java the tests won't run. Works just fine if I run them manually with maven in my terminal.

@ai-christianson
Copy link

Same issue with Apache NiFi: https://github.com/apache/nifi
It uses ANTLR to generate sources for its expression language DSL. It uses the ANTLR maven plugin:

            <plugin>
                <groupId>org.antlr</groupId>
                <artifactId>antlr3-maven-plugin</artifactId>
                <executions>
                    <execution>
                        <goals>
                            <goal>antlr</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>

It ends up putting generated sources in target/generated-sources/antlrv3 which do not get picked up by VSCode.

@andys8
Copy link

andys8 commented Jul 3, 2019

Have this in a project that is not working:

I was rereading the thread and found out, this was actually working for @rfgamaral. I looked more into it and noticed the error messages are looking more like this: #551. The actual issue was interference of a linting plugin, that wasn't aware of the generated sources. (Also I'm using the coc-java fork of this project). So it looks like build-helper-maven-plugin is working :)

            <plugin>
                <groupId>org.codehaus.mojo</groupId>
                <artifactId>build-helper-maven-plugin</artifactId>
                <executions>
                    <execution>
                        <id>generated-folder</id>
                        <goals>
                            <goal>add-source</goal>
                        </goals>
                        <configuration>
                            <sources>
                                <source>${basedir}/src-gen/main/java</source>
                            </sources>
                        </configuration>
                    </execution>
                </executions>
            </plugin>

@jackielii
Copy link

@fbricon Here is a grpc example: https://github.com/jackielii/grpc-java-example

The problem I see is not that the generated sources are not added in the .classpath, but the grpc files are not generated. Whenever I re-open the project, it removes the generated sources...

@jmartin127
Copy link

jmartin127 commented Aug 5, 2019

This issue is causing one of my team members to move off of VS Code as well. We are using the gRPC protobuf plugin which places generated files here: target/generated-sources/protobuf/java. These are picked up fine by Eclipse and IntelliJ just fine, but not by VS Code. Would love to see a fix for this.

@rory-ye-nv
Copy link

same here, with gradle google protobuf plugin, the generated folder is no way to recognized

@gombosg
Copy link

gombosg commented Sep 25, 2019

Same here with auto-generated jooq sources. Manually editing .classpath worked - but who knows how long this will last.

@lorthirk
Copy link

Hi all. I'm having the same issues this GWT, that generates some classes and puts it in ${project.build.directory}/generated-sources/gwt. I added the following execution in pom.xml:

<plugin>
    <groupId>org.codehaus.mojo</groupId>
    <artifactId>build-helper-maven-plugin</artifactId>
    <executions>
        <execution>
            <id>add-source</id>
            <phase>generate-sources</phase>
            <goals>
                <goal>add-source</goal>
            </goals>
            <configuration>
                <sources>
                    <source>${project.build.directory}/generated-sources/gwt</source>
                </sources>
            </configuration>
        </execution>
    </executions>
</plugin>

But apparently vscode doesn't add anything in the .classpath file.

A working demo can be found at https://github.com/lorthirk/kapua/tree/change-generatedSourcesMaven/console

@tim-hilt
Copy link

tim-hilt commented Apr 6, 2021

I experience the same problem, when generating sources for a GraphQL-project (via graphql-java-kickstart)! None of the generated sources are resolved and so my project hangs at around 650 errors :D Even though it runs successfully after I compiled the Maven-stuff.

@fbricon
Copy link
Collaborator

fbricon commented Apr 6, 2021

@tim-hilt please attach a sample project reproducing the issue

@wxw-matt
Copy link

wxw-matt commented May 21, 2022

Solved!

In my Gradle based project I was able to fix the problem that VS Code complains about a missing generated class by explicitly adding the directory of the generated classes to the source sets in the Gradle build script build.gradle:

sourceSets {
  main {
    java {
      srcDirs 'src/main/java'
      srcDirs 'build/generated/sources/annotationProcessor/java/main'
    }
  }
}

It is a great clue. However, the srcDirs 'build/generated/sources/annotationProcessor/java/main' does not work for me.
I just changed a bit to fix it. The following configuration works for me.
Note:

I used gradle init to create the project, so the src and build are under app directory. You may not have app, so you can remove it from the path.

sourceSets {
  main {
    java {
      srcDirs = ['app/build/generated/source/proto/main/java']
    }
  }
}

@mdgozza
Copy link

mdgozza commented Aug 22, 2022

Not to add clutter to this issue, but I also cannot come up with a workaround for my gradle project. I have one generated source code folder and I would like to add it as a one off, but I don't want to mess up any of the other auto class path generation. Lots of talk about Maven but not much about gradle :/

This is an existing intellij project that I really want to run in vs code because I love vs code 😭

@timvahlbrock
Copy link

Problem also occurs when using javaCC, even when m2e execution hint is added to pom.xml.

     <plugin>
        <groupId>org.codehaus.mojo</groupId>
        <artifactId>javacc-maven-plugin</artifactId>
        <version>3.0.1</version>
        <executions>
          <execution>
            <?m2e execute onConfiguration,onIncremental?>
            <goals>
              <goal>javacc</goal>
            </goals>
          </execution>
        </executions>
        <configuration>
          <!-- See usage on maven site from link above for details -->
        </configuration>
      </plugin>
      <plugin>
        <!-- a hint for IDE's to add the java sources to the classpath -->
        <groupId>org.codehaus.mojo</groupId>
        <artifactId>build-helper-maven-plugin</artifactId>
        <version>3.0.0</version>
        <executions>
            <execution>
            <?m2e execute onConfiguration,onIncremental?>
                <id>add-sources</id>
                <phase>generate-sources</phase>
                <goals>
                    <goal>add-source</goal>
                </goals>
                <configuration>
                    <sources>
                        <source>${project.build.directory}/generated-sources/javacc/</source>
                    </sources>
                </configuration>
            </execution>
            <execution>
              <?m2e execute onConfiguration,onIncremental?>
                <id>add-test-sources</id>
                <phase>generate-test-sources</phase>
                <goals>
                    <goal>add-test-source</goal>
                </goals>
                <configuration>
                    <sources>
                        <source>${project.build.directory}/generated-sources/javacc/</source>
                    </sources>
                </configuration>
            </execution>
        </executions>
      </plugin>

@davidivkovic
Copy link

Still completely broken

@jackieli-tes
Copy link

jackieli-tes commented Nov 21, 2022

@fbricon Here is a grpc example: https://github.com/jackielii/grpc-java-example

The problem I see is not that the generated sources are not added in the .classpath, but the grpc files are not generated or removed. Whenever I re-open the project, it removes the generated sources...

I found a workaround using this sample repo: https://github.com/jackielii/grpc-java-example. Using coc.nvim, in CocLocalConfig or global one, set:

"java.autobuild.enabled": false

This will disable initializationOptions.settings.java.autobuild.enabled in workspace initialisation. You can manually build it if it wasn't built before. More details in the README.md of this project

There should be a similar option in vscode-java as coc-java is forked from this.

@rgrunber rgrunber moved this to 📋 Backlog in IDE Cloudaptors Dec 14, 2022
@manuelserradev
Copy link

I'd like to reference this comment with a repro project.

The generated sources are correctly generated by vscode but cannot be referenced in user code.

image

@kopiro
Copy link

kopiro commented Jun 2, 2023

Same issue here - was using VScode just fine until a new dependency wrote to target/generated-sources/xyz and VsCode is not picking up the classes from there.

@pythonpadawanEXE
Copy link

pythonpadawanEXE commented Sep 7, 2023

The main thing i wanted to resolve was getting the tests to be able to run individually within the vscode ide
I solved it by modifying the setting.json per the below code
note only the source paths key was necessary
Settings.json

{
    "java.compile.nullAnalysis.mode": "automatic",
    "java.configuration.updateBuildConfiguration": "interactive",
    "java.project.sourcePaths": [
        "Api/src","Api/target/generated-sources/swagger/src/main/java"
    ],
}

I found this helpful too, I think it helps with some vs-code server logic with working out how to package the classes in generated-sources with a snippet from pom
Pom.xml

<plugin>
					<!-- a hint for IDE's to add the java sources to the classpath -->
					<groupId>org.codehaus.mojo</groupId>
					<artifactId>build-helper-maven-plugin</artifactId>
					<version>3.4.0</version>
					<executions>
					<execution>
						<?m2e execute onConfiguration,onIncremental?>
						<id>add-source</id>
						<phase>generate-sources</phase>
						<goals>
						<goal>add-source</goal>
						</goals>
						<configuration>
						<sources>
							<source>target/generated-sources/swagger/src/main/java</source>
						</sources>
						</configuration>
					</execution>
					</executions>
				</plugin>

This was a useful resource to collate the discussion topics on this issue
https://github.com/redhat-developer/vscode-java/blob/master/document/_java.notCoveredExecution.md
Realistically the class paths needs to be setup correctly on vscode with the java extension pack and should be shown correctly on the configure java path settings page
image

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests