Bagaimana cara mengkonfigurasi penyandian di Maven?

375

Ketika saya menjalankan maven installproyek multi-modul maven saya, saya selalu mendapatkan output berikut:

[WARNING] File encoding has not been set, using platform encoding UTF-8, i.e. build is platform dependent!

Jadi, saya mencari sedikit di Google, tetapi yang bisa saya temukan adalah saya harus menambahkan:

<properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>

... ke pom.xml saya. Tapi itu sudah ada di sana (pada orang tua pom.xml).

Mengkonfigurasi <encoding>untuk maven-resources-plugin atau maven-compiler-plugin juga tidak memperbaikinya.

Jadi apa masalahnya?

Ethan Leroy
sumber
1
Hati-hati bahwa pengkodean UTF-8 adalah apa yang sebenarnya ingin Anda tentukan sebagai pengkodean. Anda mungkin lebih baik menggunakan pengkodean yang lebih sederhana seperti ISO-8859-1 (alias Latin-1) atau bahkan US-ASCII.
rmp
40
"Anda mungkin lebih baik menggunakan pengkodean yang lebih sederhana seperti ..." yeah, dan pengguna akhir bug, serta pengembang lain ... Saat ini yang terbaik adalah mencoba menggunakan UTF-8 sebanyak mungkin dan peduli tentang yang lain mengkodekan hanya ketika persyaratan aplikasi multi-encoding dilemparkan kepada Anda. Di sini, kita berbicara kebanyakan tentang pengkodean file sumber dan konfigurasi, pengkodean input pengguna dikelola secara berbeda (dengan 'java -Dfile.encoding ...' dan dengan banyak upaya pemrograman yang menyakitkan).
zakmck
Saya pribadi memutuskan bahwa masalah penyandian sangat sulit dipahami sehingga saya pergi untuk menyandikan ASCII di pom.xml dan kemudian mengambil masalah penyandian di muka. Ini secara alami didorong oleh memiliki karakter non-ASCII dalam nama saya yang memberikan masalah mulai hari 1 :)
Thorbjørn Ravn Andersen
Pengkodean apa yang diatur dalam parent pom.xml?
Ripon Al Wasim

Jawaban:

535

Oke, saya menemukan masalahnya.

Saya menggunakan beberapa plugin pelaporan. Dalam dokumentasi failafe-maven-plugin ( http://maven.apache.org/plugins/maven-failsafe-plugin/integration-test-mojo.html ) Saya menemukan, bahwa <encoding>konfigurasi - tentu saja - menggunakan ${project.reporting.outputEncoding}secara default . Jadi saya menambahkan properti sebagai elemen anak dari projectelemen dan semuanya baik-baik saja sekarang:

<properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
</properties>

Lihat juga http://maven.apache.org/general.html#encoding-warning

Ethan Leroy
sumber
Jadi saya mengalami masalah ini dan saya menambahkan properti dari atas seperti ini: <profile> <profile> <activation> <activeByDefault> true </activeByDefault> </activation> <id> local </id> <properties> <url> earneventapi.intra1.e1.v2.epaas.aexp.com </ url > <project.build.sourceEncoding> UTF-8 </project.build.sourceEncoding> <project.reporting.outputEncoding> UTF-8 </project.reporting .outputEncoding> </properties> </profile>
Bob Small
Tidak, satu-satunya pengaturan pengkodean global harus dilakukan oleh env. variabel: stackoverflow.com/a/9976788/715269
Gangnus
Ini berfungsi seperti yang diharapkan sambil menambahkan 2 properti ke blok properti file pom.xml. Terima kasih.
Jean Paul Ruiz
47

Ini akan menjadi tambahan dari sebelumnya, jika seseorang menemui masalah dengan huruf skandik yang tidak diselesaikan dengan solusi di atas.

Jika file sumber java mengandung huruf skandis, mereka harus ditafsirkan dengan benar oleh Java yang digunakan untuk kompilasi . (mis. huruf skandik yang digunakan dalam konstanta)

Walaupun file disimpan dalam UTF-8 dan Maven dikonfigurasi untuk menggunakan UTF-8, System Java yang digunakan oleh Maven masih akan menggunakan standar sistem (mis. Pada Windows: cp1252).

Ini akan terlihat hanya menjalankan tes melalui pakar (mungkin mencetak nilai-nilai konstanta ini dalam tes. Huruf-huruf skandik yang dicetak akan menunjukkan sebagai '<?>') Jika tidak diuji dengan benar, ini akan merusak file kelas sebagai hasil kompilasi dan menjadi dibiarkan tanpa disadari.

Untuk mencegah hal ini, Anda harus mengatur Java yang digunakan untuk kompilasi untuk menggunakan pengkodean UTF-8. Tidak cukup untuk memiliki pengaturan penyandian di maven pom.xml, Anda perlu mengatur variabel lingkungan: JAVA_TOOL_OPTIONS = -Dfile.encoding = UTF8

Juga, jika menggunakan Eclipse di Windows, Anda mungkin perlu mengatur pengkodean yang digunakan selain ini (jika Anda menjalankan tes individu melalui eclipse).

Ville Myrskyneva
sumber
Tidak yakin apakah ada cara pakar untuk melakukan ini, karena ini adalah pengaturan JVM, bukan Maven.
Ville Myrskyneva
4
Saya pikir Anda mencampuradukkan hal-hal. Anda hanya perlu mengatur -Dfile.encodingapakah Anda menggunakan I / O di Java tanpa secara eksplisit menentukan suatu pengkodean (yang tidak disarankan). Saya tidak melihat apa hubungannya dengan huruf skandik dalam file sumber Java. Non-ASCII dalam file sumber Java berfungsi dengan Maven saat project.build.sourceEncodingdiatur dengan benar, seperti yang dijelaskan dalam jawaban Ethan Leroy.
sleske
@sleske Saya akan menganggap hal yang sama akan cukup, tetapi ketika saya pertama kali berakhir di sini dan melakukan perubahan pom.xml, itu tidak memperbaiki masalah saya. Setelah pencarian lebih lanjut dan setelah coba-coba solusi yang dijelaskan bekerja. Saya berpikir bahwa alasan untuk apa yang terjadi adalah karena maven memanggil javac dari JDK yang diinstal / dirujuk yang pada gilirannya menggunakan pengkodean O / S sebagai default. Jika seseorang mengetahui cara untuk menentukan pengkodean untuk panggilan javac di pom.xml akan menyelesaikan masalah ini dalam "maven way".
Ville Myrskyneva
4
@VilleMyrskyneva: Ketika Maven memanggil javac, itu akan melewati pengkodean yang ditetapkan oleh project.build.sourceEncoding(Anda dapat memeriksa menggunakan mvn -X), jadi saya tidak melihat bagaimana apa yang Anda uraikan diperlukan. Jika Anda masih mendapatkan masalah penyandian dalam proyek Anda, pertimbangkan untuk menanyakannya sebagai pertanyaan terpisah - sepertinya Anda mengalami masalah yang berbeda. Idealnya, pasang test case yang dapat direproduksi.
sleske
@sleske Saya punya project.build.sourceEncoding di pom.xml, tetapi mvn test masih memiliki masalah dengan encoding. sementara itu -Dfile.encoding = UTF8 menyelesaikannya. Saya tidak mengerti mengapa. stackoverflow.com/questions/42990644/…
Tiina
41

Jika Anda menggabungkan jawaban di atas, akhirnya pom.xml yang dikonfigurasi untuk UTF-8 akan tampak seperti itu.

pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<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>YOUR_COMPANY</groupId>
    <artifactId>YOUR_APP</artifactId>
    <version>1.0.0-SNAPSHOT</version>

    <properties>
        <project.java.version>1.8</project.java.version>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
    </properties>

    <dependencies>
        <!-- Your dependencies -->
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.7.0</version>
                <configuration>
                    <source>${project.java.version}</source>
                    <target>${project.java.version}</target>
                    <encoding>${project.build.sourceEncoding}</encoding>
                </configuration>
            </plugin>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-resources-plugin</artifactId>
                <version>3.0.2</version>
                <configuration>
                    <encoding>${project.build.sourceEncoding}</encoding>
                </configuration>
            </plugin>
        </plugins>
    </build>
</project>
bhdrk
sumber
1
defaultnya tampaknya $ {project.build.sourceEncoding}, jadi Anda tidak perlu mendefinisikannya secara eksplisit untuk plugin maven-resources-plugin (lihat maven.apache.org/plugins/maven-resources-plugin/examples/… , maven.apache.org/plugins/maven-resources-plugin/… , maven.apache.org/general.html#encoding-warning )
George Birbilis
Tidak, satu-satunya pengaturan pengkodean global harus dilakukan oleh env. variabel: stackoverflow.com/a/9976788/715269
Gangnus
7

Tampaknya orang-orang mencampur encoding konten dengan encoding file / sumber daya yang dibangun. Memiliki sifat maven saja tidak cukup. Setelah -Dfile.encoding=UTF8tidak efektif. Untuk menghindari masalah dengan penyandian, Anda harus mengikuti aturan sederhana berikut ini

  1. Setel pengkodean pakar, seperti dijelaskan di atas:
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
  1. Selalu atur penyandian secara eksplisit, saat bekerja dengan file, string, IO dalam kode Anda. Jika Anda tidak mengikuti aturan ini, aplikasi Anda bergantung pada lingkungan. The -Dfile.encoding=UTF8persis bertanggung jawab untuk konfigurasi lingkungan run-time, tapi kita tidak harus bergantung padanya. Jika Anda memiliki ribuan klien, diperlukan lebih banyak upaya untuk mengonfigurasi sistem dan menemukan masalah karenanya. Anda hanya memiliki ketergantungan tambahan padanya yang dapat Anda hindari dengan mengaturnya secara eksplisit. Sebagian besar metode di Jawa yang menggunakan pengkodean default ditandai sebagai usang karena itu.

  2. Pastikan konten yang Anda kerjakan, juga dalam pengkodean yang sama, yang Anda harapkan. Jika tidak, langkah-langkah sebelumnya tidak masalah! Misalnya file tidak akan diproses dengan benar, jika penyandiannya bukan UTF8 tetapi Anda mengharapkannya. Untuk memeriksa penyandian file di Linux:

$ file --mime F_PRDAUFT.dsv

  1. Memaksa klien / server mengatur pengkodean secara eksplisit dalam permintaan / tanggapan, berikut adalah contohnya:
@Produces("application/json; charset=UTF-8")
@Consumes("application/json; charset=UTF-8")

Semoga ini bermanfaat bagi seseorang.

Alexandr
sumber
Tidak, satu-satunya pengaturan pengkodean global harus dilakukan oleh env. variabel: stackoverflow.com/a/9976788/715269
Gangnus
6

Coba ini:

<project>
  ...
  <build>
    <plugins>
      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-resources-plugin</artifactId>
        <version>2.7</version>
        <configuration>
          ...
          <encoding>UTF-8</encoding>
          ...
        </configuration>
      </plugin>
    </plugins>
    ...
  </build>
  ...
</project>
fsimon
sumber
Terutama penting, kita tidak boleh lupa bahwa tidak hanya sumber, tetapi juga sumber daya memerlukan pengaturan penyandian ini.
peterh