Using guava-gwt copy package java.nio.charset in folder build/classes/main

Hi,

I have a important issue when I use the guava-gwt dependency.

if I import the project guava-gwt in my project :

dependencies {
     compile "com.google.guava:guava-gwt:17.0"
}

And I import java.nio.charset classes in a java file :

import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;

then java.nio.charset package is copied in folder build/classes/main when I launch command :

gradle clean classes
build/classes/main
├── java
│   └── nio
│  
   └── charset
│  
       ├── Charset$1.class
│  
       ├── Charset.class
│  
       ├── IllegalCharsetNameException.class
│  
       └── UnsupportedCharsetException.class
└── org
    └── gradle
        └── Launch.class

second point : If i use the java.nio.charset.Charset classes, I have a compilation error :

package org.gradle;
  import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
  public class Launch {
   public static void main(String[] args) {
  System.out.println("=========== main started =============");
  final Charset charset = Charset.forName("ISO-8859-1");
  Charset s = StandardCharsets.UTF_8;
  System.out.println(charset.displayName());
  System.out.println(s.displayName());
    System.out.println("=========== main stop =============");
   }
  }

and the compilation error message

/home/jguidoux/workspace-cleancode_corrections/bug-gradle-charset/src/main/java/org/gradle/Launch.java:12: error: cannot find symbol
  System.out.println(charset.displayName());
                            ^
  symbol:
 method displayName()
  location: variable charset of type Charset
/home/jguidoux/workspace-cleancode_corrections/bug-gradle-charset/src/main/java/org/gradle/Launch.java:13: error: cannot find symbol
  System.out.println(s.displayName());
                      ^
  symbol:
 method displayName()
  location: variable s of type Charset
2 errors
1 warning

we can notice that just before the error message, these lines :

Executing task ':compileJava' (up-to-date check took 0.023 secs) due to:
  Output file /home/jguidoux/workspace-cleancode_corrections/bug-gradle-charset/build/classes/main has changed.
  Output file /home/jguidoux/workspace-cleancode_corrections/bug-gradle-charset/build/dependency-cache has changed.
  Output file /home/jguidoux/workspace-cleancode_corrections/bug-gradle-charset/build/classes/main/java/nio/charset/Charset.class has been removed.
All input files are considered out-of-date for incremental task ':compileJava'.

the line

Output file /home/jguidoux/workspace-cleancode_corrections/bug-gradle-charset/build/classes/main/java/nio/charset/Charset.class has been removed.

is maybe important.

I think the problem is because in guava-gwt the is a package ‘java.nio.charset’ which contain a file ‘Charset.gwt.xml’ with these contents :

<module>
 <source path=""/>
 <inherits name="java.nio.charset.Charset"/>
</module>

If I remove the ‘guava-gwt’ dependency, my class compile.

Third point :This problem can be a blocker issue. I a more complex configuration I create a groovy script which use as transitive dependency guava-gwt. In these case, I can’t launch my script. I Had this message :

Caught: java.lang.SecurityException: Prohibited package name: java.nio.charset
java.lang.SecurityException: Prohibited package name: java.nio.charset

I try to reproduce the problem by create a project maven and gradle which contain the package java.nio.charset with the file Charset.gwt.xml inside with the same content. But I was not able to reproduce the problem.

If I do the same thinks with a maven project which contain the guava-gwt dependency ans the same java class.

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
 <modelVersion>4.0.0</modelVersion>
 <groupId>org.gradle</groupId>
 <artifactId>test-charset</artifactId>
 <version>0.0.1-SNAPSHOT</version>
   <dependencies>
  <dependency>
   <groupId>com.google.guava</groupId>
   <artifactId>guava-gwt</artifactId>
   <version>17.0</version>
  </dependency>
 </dependencies>
</project>
package org.gradle;
  import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
  public class Launch {
   public static void main(String[] args) {
  System.out.println("=========== main started =============");
  final Charset charset = Charset.forName("ISO-8859-1");
  Charset s = StandardCharsets.UTF_8;
  System.out.println(charset.displayName());
  System.out.println(s.displayName());
    System.out.println("=========== main stop =============");
   }
  }

when I launch the command :

mvn clean install

everything work :

[INFO]
 [INFO] --- maven-jar-plugin:2.3.2:jar (default-jar) @ test-charset ---
[INFO] Building jar: /home/jguidoux/workspace-cleancode_corrections/test-charset/target/test-charset-0.0.1-SNAPSHOT.jar
[INFO]
 [INFO] --- maven-install-plugin:2.3.1:install (default-install) @ test-charset ---
[INFO] Installing /home/jguidoux/workspace-cleancode_corrections/test-charset/target/test-charset-0.0.1-SNAPSHOT.jar to /home/jguidoux/LocalRepository/org/gradle/test-charset/0.0.1-SNAPSHOT/test-charset-0.0.1-SNAPSHOT.jar
[INFO] Installing /home/jguidoux/workspace-cleancode_corrections/test-charset/pom.xml to /home/jguidoux/LocalRepository/org/gradle/test-charset/0.0.1-SNAPSHOT/test-charset-0.0.1-SNAPSHOT.pom
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 3.093s
[INFO] Finished at: Tue Nov 18 11:08:17 CET 2014
[INFO] Final Memory: 11M/118M
[INFO] ------------------------------------------------------------------------
target
├── classes
│   └── org
│  
   └── gradle
│  
       └── Launch.class
├── maven-archiver
│   └── pom.properties
├── surefire
├── test-charset-0.0.1-SNAPSHOT.jar
└── test-classes

So I think this is a real Gradle issue. I tries with gradle 1.8, 2.0, 2.1 and 2.2 and I always have the same issue.

Sorry for my bad english. I hop my post is enought precise to fix this bug.

Thanks

Jeremie Guidoux

Sounds like guava-gwt contains Java sources, in which case javac will compile them by default. You should find similar posts here and on Stack Overflow that explain how to prevent that (search for “source path”).

Yes, I look into the gwava-gwt.jar and I see a package java.nio.Charset which contain these files :

  • Charset.gwt.xml - Charset.java - IllegalCharsetNameException.java - UnsupportedCharsetException.java

I had these lines in my build.gradle

tasks.withType(JavaCompile) {
    options.compilerArgs += ["-sourcepath", ""]
}

and now it works,

It seems that Gradle compile all *.java file which are in this classpath.

I think it is a bug. Maven don’t do that. And I don’t think it is a good idea to compile files which come from dependencies (and sometimes transitive dependencies) . Gradle do some stuff that user not expect. Sometimes it can have ugly effect like the one I described in this post.

This is the default behavior of javac, and Gradle doesn’t change it. Of course you could argue that it should.

Oki, I now understand the problem. Javac with only the option ‘- classpath’ compile all sources which are in the classpath. If you want javac compile sources which are only in a folder, you have to use the ‘-sourcepath’ options. But ‘-sourcepath’ is an optional option.

Do Gradle must use by default the ‘-sourcepath’ option. Me, I think that he should because Gradle users can have the same problem that I had and it was really difficult to find the root

cause.

I think, it will be interesting to create a discussion about this. Maven seem to had chosen to compile with the ‘-sourcepath’ option

To finish, really thank you to answer so fast :slight_smile:

Jérémie