Vscode-java: Stop creating files in bin directory

Created on 11 Sep 2018  路  42Comments  路  Source: redhat-developer/vscode-java

Random files begin to appear in my bin directory after I generated a lot of code by using my custom code generator. I spent a lot of time debugging where these files are being created, who and why makes them, and I don't want my project polluted with completely useless copies of the project files.

Environment
  • Operating System: macOS 10.13
  • JDK version: multiple
  • Visual Studio Code version: Version 1.27.1 (1.27.1)
  • Java extension version: 0.30.0
Steps To Reproduce
  1. Open any kind of project, even non-java ones (mixed), click on any .java file
  2. Watch .class files being generated in your bin directory, kotlin files being copied there as-is (which doesn't make any sense), other resources being copied there without any reason.
Current Result

Many files are copied to ./bin/ without any reason to do so.

Expected Result

No files are created, compiled, copied without developer's consent!

Additional Informations

The extension uses jdt_ws which creates these files. I don't want these files to be there, because:

1) I use docker.
2) I don't use vscode for java, I use it for other parts of the project.
3) I compile the java and kotlin files using gradle, to build folder, with multiple other build configuration options not reflected by vscode-java or jdt_ws.
4) The generated files are useless.
5) This extra compilation step burdens battery life and SSD wear.
6) It just doesn't make any sense.

I didn't even know that I have vscode-java installed and it took a LOT of digging to find out WHY and WHO creates these files!

Please consider removing them altogether, OR make this extra compilation step optional (opt-in) with explicit configuration where these files should be created.

If I would change the target directory to "build" or "target", then vs code would be randomly overwriting files compiled by docker/IDEA/gradle.

They might even be compiled with different version of Java (and JDK)!

Most helpful comment

@fbricon this appears to still be an issue, can this be reopened?

All 42 comments

Don't get me wrong. I'm glad that this extension exists, it surely looks useful. But it was activated by default and this default "bin behavior" is totally unexpected and uwanted.

@eskibear please take a look as a part of the effort of handling temp files.

I've been using this extension for about 9 months full time. A week or two ago these bin directories started popping up. We usually move all of Eclipse's gradle stuff over to a directory that we've gitignored. I'm not sure what has broken, but these bin directories are overwriting directories where we put things and breaking normal gradle runs. At this point the plugin I just have to uninstall the plugin.

A week or two ago

I suspect me seeing this issue late might have something to do with not upgrading very quickly. I'm not sure though.

right click pom.xml and update project configuration

this will generate the .project .classpath .settings files. it seems that the latest version will only generate .project by default. the class file will output to bin folder if there's no .classpath file

I solved this issue on Ubuntu by editing the .classpath XML file, replacing all bin/ with build/temp/ (just to use an example that was already gitignored for my convenience). Before doing that, having this extension enabled would make complete copies of Kotlin source files from the src/ folder to the bin/ folder upon saving. Oddly enough, after changing the .classpath file, it copies the folder structure and no Kotlin source files into build/temp/.

I'm a complete beginner to the Java ecosystem, so I don't know what effects this has long-term, but it works for me. Maybe it's worth exploring automatically editing that file to ensure that it no longer tampers with bin/.

The behavior on my setup contradicts tonny008's experience; I think this is due to using Kotlin and the Kotlin Language Server extension which has its own set of issues regarding dependency resolution. Upon starting VS Code, the plugin would re-create the .classpath, .project files and .settings folder, and also pollute the bin/ folder, and I am running the latest extension version. Even while the .classpath file was present and unmodified, it would still pollute the bin folder. As described previously, I edited the .classpath file in an attempt to make it pollute a different folder, and it worked.

one more facing this problem. I found whenever I did "mvn eclipse:clean" "mvn eclipse:eclipse" to regenerate the .project and .classpath, then vscode will create a bin folder with all my project's sub folders and files moved under a new created bin folder and build output. Deleting the .factorypath file also has this effect. My .classpath file has no bin/ path at all. output attributes in .classpath are output="target/test-classes" or output="target/classes"

Same issue here. From observation I think the main problem may be that when you don't have a .classpath, the plugin doesn't import the pom.xml/build.gradle first, but starts building the class files to the default output directory, which happens to be bin.

Making it configurable would be great thing todo

Reproduced the issue.

  1. Use VS Code to open a maven project.
  2. Wait the Java Language Server is ready. (:thumbsup: appears at the right bottom status bar)
  3. Manually delete .classpath file, then a new bin folder is automatically created at the root folder, and all non java files are copied there.

Looks like if the .classpath doesn't exists, the Java projects loaded by jdt.ls will take bin as the default output folder. And the build process will take any files it doesn't know how to compile as resources, and copy them to the output folder.

Same issue. I don't understand. Maven project do not use anything from bin.
How do I avoid this from happening? it messes up my git.

Any update on this issue? Seems like my scons build rules are finding multiple copies of themselves and conflicting!

I think this is a serious issue, and unfortunately the only solution for me right now is to use idea. sorry VSCODE-JAVA

Agreed. Until this stops, this extension is basically unusable.

This is gross. Removed the extension immediately. Not only it makes Java for Code unusable, it also ruins the reputation of the Code.

Any update on this almost 1 year old issue? I've resorted to @ewired suggestion above

I get this often and it's annoying as (#*$&#(# - esp. since it also copies .git folders into bin which REALLY mess up some tooling.

@acohen716 the problem with @ewired's "solution" is you'd need to commit those .classpath files for those changes to persist. That's a worse sin in my book.

take bin as the default output folder. And the build process will take any files it doesn't know how to compile as resources, and copy them to the output folder.

Based on hypothesis mentioned in https://github.com/redhat-developer/vscode-java/issues/634#issuecomment-489916039 above, I'm wondering if it would be a good solution that:

  • If language server doesn't know how to compile as resources, stop doing further unexpected actions, simply notify the client (VSCode) about it.
  • Then the client can prompt with the error, providing users a shortcut/guidance to fix the issues (e.g. to re-generate a .classpath file)

Here's another scenario blocked by the issue. I was working on a nodejs project in my workspace, then I dragged a HelloWorld.java in, pressed F5, and it just stuck on "compile workspace" for a long time (making no sense for the single .java file). Soon I realized it was copying the huge node_modules folder into the jdt_ws/<workspace>/bin folder.

Just FYI that this issue might be more severe than I thought before, especially for polyglot programmers.

Extension is very promising but this issue is a big blocker for me as well.

I was quite hopeful of VSCode's remote ability. Since most of my work is on Java + Python it would have been the ideal solution. This aspect of unwanted files in the bin directory is an issue for me as well.

Here's another scenario blocked by the issue. I was working on a nodejs project in my workspace, then I dragged a HelloWorld.java in, pressed F5, and it just stuck on "compile workspace" for a long time (making no sense for the single .java file). Soon I realized it was copying the huge node_modules folder into the jdt_ws/<workspace>/bin folder.

Just FYI that this issue might be more severe than I thought before, especially for polyglot programmers.

Currently JavaBuilder provides an option CORE_JAVA_BUILD_RESOURCE_COPY_FILTER to exclude the specified resources. It supports a file name pattern (* and ? wild-cards allowed) or the name of a folder which ends with '/'. For polyglot projects, you need list all possibles to exclude, it will be a burden.

Another idea is to add a new option (e.g. CORE_JAVA_BUILD_NO_RESOURCE_COPY) in the jdt core, if it's enabled, stop the copy behavior.

Any updates @snjeza ? Thanks.

@donraj check out https://github.com/eclipse/eclipse.jdt.ls/pull/1108 for updates on fix

Please fix this, it's very frustrating having my text editor create random files for me polluting my source control information - this is going to cause me to accidentally commit rogue files. Very dangerous, why does this happen?

Please fix this, it's very frustrating having my text editor create random files for me polluting my source control information - this is going to cause me to accidentally commit rogue files. Very dangerous, why does this happen?

@esr360 could you provide a project example (or the .project, .classpath, pom.xml, build.gradle files)?

@snjeza I'm not too sure exactly what you're after but within my project I can see a pom.xml file with these contents: https://gist.github.com/esr360/b03fc562102f49d1a696bf520d83fb16

It should be noted I only write CSS - I have no interest in Java, whilst I would love a separate front-end repo for my project it is not the case, so seeing a bunch of new files show up makes me extremely uneasy as I have no idea what any of them are - I just want to edit some CSS.

I have no interest in Java

You can add the following property to your settings.json:

"java.import.maven.enabled": false
  • remove the .project, .classpath files and the .settings directory
  • call Java : Clean the Java language server workspace

@snjeza cheers for that. I'd prefer to see this be an opt-in feature - this has happened to me on at least two totally separate projects (in two different countries for two different companies) so I find it difficult to believe there is good justification to having it enabled by default, unless my circumstances are just extremely unfortunate.

We've pushed a tentative fix that should help prevent copying the content of the workspace to the bin/ directory when users delete .classpath. Let's see how it works in the real world, once vscode-java 0.49.0 is out (soon)

I'm using vscode-java 0.50, but bin directory is still created...

We've pushed a tentative fix that should help prevent copying the content of the workspace to the bin/ directory when users delete .classpath. Let's see how it works in the real world, once vscode-java 0.49.0 is out (soon)

@anyflow could you provide a project example?

I ended with this configuration in my build.gradle so gradle build on "build/gradle" and eclipse on "build/eclipse":

buildDir = "build/gradle"
apply plugin: 'java'
apply plugin: 'eclipse'
eclipse {
  classpath {
    defaultOutputDir = file('build/eclipse')
    file.whenMerged {
      entries.each { entry ->
        if (entry.kind == 'src' && entry.hasProperty('output')) {
          entry.output = entry.output.replace('bin/', "build/eclipse/")
        }
      }
    }
  }
}

Making it configurable would be great thing todo

I second this. Typically, i am using gradle to build the source codes, which will output to build folder. Now I see both folders, can easily get confuse.

The annoying thing for me about this bin folder is the file search shows results from the bin, so if I look at the file name only, several times I open and start modifying the file under bin and not the real file. This takes extra time of debugging to know WTF is going on the open the right file from the project source.

@fbricon this appears to still be an issue, can this be reopened?

Just installed the plugin using Visual Studio Code 1.47.2: the ./bin/ folder is still created upon project build.

Why was this issue closed? What was the resolution?

This just happened to me as well on Visual Studio Code 1.47.3 when deleting .classpath, running extension version 0.65.0. I've also encountered @ppazos 's issue regarding file search pulling from the ./bin/ folder. Could this be reopened and looked into?

I found the folder bin is defined at .classpath.<classpathentry ...>, .classpath is generated by this plugin automatically. Actually, I don't think bin is a good name for plugin temp folder, lots of projects use bin to store script files, so we can't roughly exclude bin in .gitignore. I wonder if there is possible to change the default folder name to widely used or some words start with ., like temp, build, .bin?
At least, please provide a property to overwrite it in settings.json.

Same here. We're using the bin folder for something else in the project. It would be great to override option for the name

While I haven't found a way to change how vscode creates the initial config, after 2 days of trawling through https://docs.gradle.org/current/userguide/eclipse_plugin.html I have found a hacky way to reconfigure the buildship plugin output paths. Assuming you are also using build/ as your build output path (if you're using target/ then edit the following accordingly):

// build.gradle
eclipse.classpath {
  defaultOutputDir = file("build/default")
  file.whenMerged { cp ->
    cp.entries.forEach { cpe ->
      if (cpe instanceof org.gradle.plugins.ide.eclipse.model.SourceFolder) {
        cpe.output = cpe.output.replace "bin/", "build/classes/java/"
      }
      if (cpe instanceof org.gradle.plugins.ide.eclipse.model.Output) {
        cpe.path = cpe.path.replace "bin/", "build/"
      }
    }
  }
}

What the preceding does is rewrite the existing buildship config. You may need to run gradle eclipseClasspath to run it, but the expected result is that any instance of

<classpathentry kind="src" output="bin/..." ...>

becomes

<classpathentry kind="src" output="build/classes/java/..." ...>

in the .classpath files, and you can remove any of the bin/ folders that buildship has created.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

danielcalvogonzalez picture danielcalvogonzalez  路  3Comments

xriu picture xriu  路  4Comments

jcjolley picture jcjolley  路  3Comments

roben picture roben  路  4Comments

sfariaNG picture sfariaNG  路  3Comments