当前位置: 首页 > 知识库问答 >
问题:

Gradle项目中的IntelliJ IDEA编码问题

寇坚成
2023-03-14

通常情况下,我不会在这里问问题,但我面对的问题太可怕了,我再也无法独自应对了,我已经筋疲力尽了。无论如何,我要描述我所发现的一切,我发现了许多有趣的事情,我想相信这些事情会帮助别人帮助我。

软件版本:-OS: Windows 10 Pro version: 1909 build: 18363.720-IntelliJ IDEA: 2019.2.4 Ultime-Gradle包装版本: 5.2.1-all-jdk: 8

问题在于编码,特别是Gradle项目中的控制台输出。

这是我的身材。渐变文件:

plugins {
    id 'java'
    id 'idea'
    id 'application'
}

group 'com.diceeee.mentoring'
version 'release'

sourceCompatibility = 1.8
application.mainClassName('D')
compileJava.options.encoding = 'utf-8'

tasks.withType(JavaCompile) {
    options.encoding = 'utf-8'
}

repositories {
    mavenCentral()
    jcenter()
}

dependencies {
    testCompile group: 'junit', name: 'junit', version: '4.12'
}

我的源代码是使用CRLF的UTF-8编码,所以在build.gradle我设置了源代码应该使用utf-8编码来编译,而不是我的系统默认的windows 1251编码。

这里是D. java:

import java.io.FileWriter;
import java.io.IOException;

public class D {
    public static void main(String[] args) throws IOException {
        System.out.println(System.getProperty("file.encoding"));

        String testLine = "Проверка работоспособности И Ш";
        System.out.println(testLine);

        FileWriter writer = new FileWriter("D:\\test.txt");
        writer.write(testLine);
        writer.close();
    }
}

我还有格拉德尔。具有一行的属性:

org.gradle.jvmargs=-Dfile.encoding=utf-8

我检查了它是否有效,并向自己保证它有效,对系统中的编码器进行编码。我们真的改成了utf-8。

当我运行我的gradle项目时,我得到了这个:

21:04:53: Executing task 'D.main()'...

> Task :compileJava UP-TO-DATE
> Task :processResources NO-SOURCE
> Task :classes UP-TO-DATE

> Task :D.main()
UTF-8
�������� ����������������� � �

Deprecated Gradle features were used in this build, making it incompatible with Gradle 6.0.
Use '--warning-mode all' to show the individual deprecation warnings.
See https://docs.gradle.org/5.2.1/userguide/command_line_interface.html#sec:command_line_warnings

BUILD SUCCESSFUL in 0s
2 actionable tasks: 1 executed, 1 up-to-date
21:04:54: Task execution finished 'D.main()'.

还有更多信息。1) 我将输出以代码形式留在文件中并不是巧合。如果我们尝试查看文件,我们可以看到:

Проверка работоспособности И Ш

我不确定它是否正确,但我已经得出结论,这个问题是在控制台的某个地方,因为如果默认编码有问题,文件编写器对文件使用了错误的编码,输出将是相等的。但这并没有发生。

2) 我调试了PrintStream、OutputStreamWriter和StreamnCoder类的内部结构。StreamEncoder实际上使用了utf-8字符集,它还将utf-8文本编码到了正确的字节序列:String testLine=“ППааааааааааааааа;每个西里尔字母是2个字节,空格是1个字节,如果我们计算所有字母,我们得到57个。

现在,看这里:编码器调试屏幕与结果字节

因此,正如我们所看到的,我们得到了前57个字节(其他来自其他输入,缓冲区使用限制):

[-48, -97, -47, -128, -48, -66, -48, -78, -48, -75, -47, -128, -48, -70, -48, -80, 32, -47, -128, -48, -80, -48, -79, -48, -66, -47, -126, -48, -66, -47, -127, -48, -65, -48, -66, -47, -127, -48, -66, -48, -79, -48, -67, -48, -66, -47, -127, -47, -126, -48, -72, 32, -48, -104, 32, -48, -88, 91]

看起来不错,西里尔字母编码像[-48,-97],-47,-128]和其他两个字节的组,所以看起来不错,空格也匹配。编码器做得很好,很有效,但接下来会发生什么呢?我不知道。认真地但还有更多信息。如果这看起来不令人兴奋,我已经为你准备了别的东西。

我创建了一个干净的Java项目,没有任何gradle/maven等,只有我自己的jdk,仅此而已。程序是一样的:

package com.company;

import java.io.FileWriter;
import java.io.IOException;

public class Main {

    public static void main(String[] args) throws IOException {
        System.out.println(System.getProperty("file.encoding"));

        String testLine = "Проверка работоспособности И Ш";
        System.out.println(testLine);

        FileWriter writer = new FileWriter("D:\\test.txt");
        writer.write(testLine);
        writer.close();
    }
}

我运行它,我得到了什么?

"C:\Program Files\Java\jdk1.8.0_181\bin\java.exe" "-javaagent:C:\Program Files\JetBrains\IntelliJ IDEA 2019.2.4\lib\idea_rt.jar=58901:C:\Program Files\JetBrains\IntelliJ IDEA 2019.2.4\bin" -Dfile.encoding=UTF-8 -classpath "C:\Program Files\Java\jdk1.8.0_181\jre\lib\charsets.jar;C:\Program Files\Java\jdk1.8.0_181\jre\lib\deploy.jar;C:\Program Files\Java\jdk1.8.0_181\jre\lib\ext\access-bridge-64.jar;C:\Program Files\Java\jdk1.8.0_181\jre\lib\ext\cldrdata.jar;C:\Program Files\Java\jdk1.8.0_181\jre\lib\ext\dnsns.jar;C:\Program Files\Java\jdk1.8.0_181\jre\lib\ext\jaccess.jar;C:\Program Files\Java\jdk1.8.0_181\jre\lib\ext\jfxrt.jar;C:\Program Files\Java\jdk1.8.0_181\jre\lib\ext\localedata.jar;C:\Program Files\Java\jdk1.8.0_181\jre\lib\ext\nashorn.jar;C:\Program Files\Java\jdk1.8.0_181\jre\lib\ext\sunec.jar;C:\Program Files\Java\jdk1.8.0_181\jre\lib\ext\sunjce_provider.jar;C:\Program Files\Java\jdk1.8.0_181\jre\lib\ext\sunmscapi.jar;C:\Program Files\Java\jdk1.8.0_181\jre\lib\ext\sunpkcs11.jar;C:\Program Files\Java\jdk1.8.0_181\jre\lib\ext\zipfs.jar;C:\Program Files\Java\jdk1.8.0_181\jre\lib\javaws.jar;C:\Program Files\Java\jdk1.8.0_181\jre\lib\jce.jar;C:\Program Files\Java\jdk1.8.0_181\jre\lib\jfr.jar;C:\Program Files\Java\jdk1.8.0_181\jre\lib\jfxswt.jar;C:\Program Files\Java\jdk1.8.0_181\jre\lib\jsse.jar;C:\Program Files\Java\jdk1.8.0_181\jre\lib\management-agent.jar;C:\Program Files\Java\jdk1.8.0_181\jre\lib\plugin.jar;C:\Program Files\Java\jdk1.8.0_181\jre\lib\resources.jar;C:\Program Files\Java\jdk1.8.0_181\jre\lib\rt.jar;C:\Users\<my_removed_name>\IdeaProjects\test\out\production\test" com.company.Main
UTF-8
Проверка работоспособности И Ш

Process finished with exit code 0

在那之后,我就死了。Wtf正在发生什么???回到gradle项目上来。我做了一些修改:

import java.io.FileWriter;
import java.io.IOException;
import java.nio.charset.StandardCharsets;

public class D {
    public static void main(String[] args) throws IOException {
        System.out.println(System.getProperty("file.encoding"));

        String testLine = new String("Проверка работоспособности И Ш".getBytes(StandardCharsets.UTF_8), "windows-1251");
        System.out.println(testLine);

        FileWriter writer = new FileWriter("D:\\test.txt");
        writer.write(testLine);
        writer.close();
    }
}

现在的输出是:

21:43:06: Executing task 'D.main()'...

> Task :compileJava
> Task :processResources NO-SOURCE
> Task :classes

> Task :D.main()
UTF-8
Проверка работоспособности �? Ш

Deprecated Gradle features were used in this build, making it incompatible with Gradle 6.0.
Use '--warning-mode all' to show the individual deprecation warnings.
See https://docs.gradle.org/5.2.1/userguide/command_line_interface.html#sec:command_line_warnings

BUILD SUCCESSFUL in 0s
2 actionable tasks: 2 executed
21:43:06: Task execution finished 'D.main()'.

在文件中:

Проверка работоспособности � Ш

此外,控制台中的这个输出是推动我确定出了什么问题的第一件事,我只是在编码,发现西里尔字母“”真的有问题。我试图解决它,一次又一次...现在我在这里,因为我在死胡同,我尝试了我在类似的问题和主题中找到的所有关于编码问题的问题,我红色了一些关于java中默认编码的文章,Windows在控制台使用cp866编码,windows 1251编码为默认编码,我们需要用-Dfile.encoding=UTF-8显式地确定编码,没有任何帮助,我甚至不知道寻找什么来找到问题。我以为gradle不识别属性,charset仍然是windows 1251,但是调试显示我错了。

好吧,这里有一个我试图解决问题的完整列表: 1)在idea.exe.vmoptions中设置-Dfile.encoding=UTF-8,重启时idea64.exe.vmoptions。没用。2)在IntelliJ IDEA中设置UTF-8-

我不确定gradle有什么问题,因为没有gradle的清洁项目效果很好,控制台输出也很好。但是对于gradle,西里尔符号是不正确的。此外,我试图用getBytes(charset)和新的String(byte[],charset)方法/构造函数来纠正控制台的输出,我尝试了这些变体:

String testLine = new String("Проверка работоспособности И Ш".getBytes(StandardCharsets.UTF_8), "windows-1251");

Output:
Проверка работоспособности �? Ш

没用。

String testLine = new String("Проверка работоспособности И Ш".getBytes(StandardCharsets.UTF_8), "cp866");

Output:
?�?�???????�???? ?�???????�???�?????�?????????�?�?? ?� ?�

没用。

String testLine = new String("Проверка работоспособности И Ш".getBytes(StandardCharsets.UTF_8), "utf-8");

Output:
�������� ����������������� � �

我们得到的结果没有任何转换。

此外,我还尝试了一件事,那就是系统。out wrapper设置另一个控制台编码。

public class D {
    public static void main(String[] args) throws IOException {
        System.out.println(System.getProperty("file.encoding"));

        System.setOut(new PrintStream(System.out, true, "utf-8"));
        String testLine = "Проверка работоспособности И Ш";
        System.out.println(testLine);

        FileWriter writer = new FileWriter("D:\\test.txt");
        writer.write(testLine);
        writer.close();
    }
}

我们仍然没有任何产出,甚至没有改变:

> Task :D.main()
UTF-8
�������� ����������������� � �

根据所有这些信息,我认为控制台本身确实不太好,因为即使是上面代码的最后一次执行,文件中也有这样的输出:

Проверка работоспособности И Ш

它在utf-8编码中,是正确的输出。但是System.out.println在控制台中打印了一些不合理的东西,即使编码器工作得很好。我不知道这是怎么回事(sry为肮脏的谈话),如果问题真的在gradle中,如何检查它?或者如何让gradle为控制台输出使用另一种编码?或者即使没有gradle的项目中的输出是正确的,它仍然是IntelliJ IDEA的东西?

我觉得自己像个侦探,但我已经停滞不前,被困在那个案子里了。如果有人帮我,我很感激。

共有3个答案

艾仲渊
2023-03-14

将字体更改为能够正确显示设置(macOS上的首选项)|编辑器|字体|字体设置中的所有字符。

郗浩
2023-03-14

我遇到了一个类似的问题。这是一个Gradle-IntelliJ-on-non-ascii语言版本的Windows特定问题。

我用以下方法解决了这个问题:

  • 设置systemProp。文件在gradle中编码=utf-8。属性项目中的文件
  • 在IntelliJ上,转到设置-

shell路径应该是cmd。默认情况下,exe

属性文件中的属性值有助于在IntelliJ上使用Gradle工具构建工作,外壳路径设置解决集成终端上的编码问题。

如果您在IntelliJ外部使用cmd,而不是在IntelliJ的集成终端上使用cmd,只需在控制台上调用chcp 65001。这将在cmd控制台上设置字符编码UTF-8

林鸿飞
2023-03-14

运行\编辑配置,选择您的运行配置并写入-Dfile。编码=UTF-8VM选项字段中。这为我解决了问题。

 类似资料:
  • 我正在Windows 7上与IntelliJ IDEA 14.1.2合作。我的项目使用Gradle 2.5。每次我用打开一个项目,我的所有文件都会被设置为windows-1252编码。是否有一种简单的方法可以将文件,以便IntelliJ自动使用此设置? 即使将设置为UTF-8,文件仍以windows-1252打开。 可以进入设置并为每个文件手动设置编码(通过将其应用于项目根),但这并不理想,因为每

  • 我看了看样品,然后跟着它走 (渐变版本为6.8.3) https://docs.gradle.org/6.8.3/samples/sample_building_java_applications_multi_project.html 我只是附加了插件io。Spring演示中的依赖关系管理。java常见约定。gradle文件。 然后运行gradle生成,出现以下错误。 错误:插件请求无效[id:“

  • 我在gradle运行junit测试时遇到了一个问题。从stacktrace来看,这似乎是一个编码问题。 我已将编码设置为 谢谢

  • 我尝试使用build.gradle文件在我的应用程序中包含httpmime,所有的东西都编译得很好。相反,当应用程序尝试实际使用MultipartEntityBuilder类时,日志上有一堆警告级消息表示存在问题。 以下是我的build.gradle中关于依赖关系的节选: 以下是错误: Java班: [编辑]根据答案更正依赖项 [第二次编辑]仍然有问题-现在是这些其他缺失的位,但可能是后端的问题:

  • 我正在尝试使用gradle编译一个war文件以部署到JBoss 7.1 AS,但编译失败(找不到ServletContext)…… gradle.build.见下文 错误: /workspace/agile runner/src/main/Java/com/agile runner/web/config/agilerunnerapplicationinitializer . Java:20:找不到

  • 无法修复项目,android studio新手,需要帮助修复gradle我的gradle文件,从eclipse导入项目时发生,导出完成 我得到的错误是 更改代码\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\