Reputation: 7439
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)
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
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
Reputation: 46
I think the workaround is to escape the characters like
String password = ":&=/?\u00e9$\u00a3";
Upvotes: 2