Mick F
Mick F

Reputation: 7439

Maven fails my unit test because of encoding issues

I have an encoding based unit test in my project. The test passes in Eclipse but fails with Maven.

All my files are UTF-8 encoded and I added the 2 following lines in my pom.xml but the test keeps failing:

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

Here is the interesting part of the test. Credentials is a simple bean storing the password as a String with getter/setter (no other code there).

AuthentificationHelper helper = new AuthentificationHelper();
// ...
String password = ":&=/?é$£";
String base64Hash = Base64.encodeString(login + ":" + password);
final String authHeader = "Basic " + base64Hash;
// ...
Credentials credentials = helper.credentialsWithBasicAuthentication(request);
assertEquals(password, credentials.getPassword());

The credentialsWithBasicAuthentication does the reverse operation of what's being done here:

StringTokenizer st = new StringTokenizer(authHeader);
//...
String credentials = new String(Base64.decodeBase64(hashedCredentials), "UTF-8");
int p = credentials.indexOf(":");
//...
String password = credentials.substring(p + 1).trim();
return new Credentials(login, password);

Here is Maven's output:

Failed tests: 
   testCredentialsWithBasicAuthentication: expected:<:&=/?[?$?]> but was:<:&=/?[?$?]>

(not sure if this is relevent but my log4j appender is also configured to output data in UTF-8)

Any idea what's wrong? (the surprising part being that the console output is not displayed properly either)

SOLUTION (embarassing)

The Base64 class I was using was not the one provided by Apache Commons but a random one.

Replacing:

import random.bla.bla.Base64;
// ...
String base64Hash = Base64.encodeString(login + ":" + password);

by

import org.apache.commons.codec.binary.Base64;
// ...
String base64Hash = Base64.encodeBase64String(new String(login + ":" + password).getBytes("UTF-8"));

solved the problem.

Cough, cough, tumbleweed.

Upvotes: 0

Views: 2537

Answers (2)

artbristol
artbristol

Reputation: 32437

Base64.encodeString(login + ":" + password) is implicitly using a character encoding (the platform default, which could conceivably be different between Maven and Eclipse), because it has to convert the string to a byte array before it can hash it. You should specify it explicitly - presumably ISO-8859-1, see this question What encoding should I use for HTTP Basic Authentication?.

It's also possible that Eclipse has a different idea of the source file's encoding than Maven (you can check by right clicking the file and doing Properties). Usually m2e sorts that out for you.

An aside - why are you writing code to deal with HTTP authentication? You should use a library.

Upvotes: 2

Markus Mensinger
Markus Mensinger

Reputation: 46

I think the workaround is to escape the characters like

String password = ":&=/?\u00e9$\u00a3";

Upvotes: 2

Related Questions