furkankamaci

Imported from Furkan KAMACI’s blog: www.furkankamaci.com

Follow publication

Forbidden APIs of Java

--

Software developers try to take care of many cases when they develop a software. They make checks for null comparisons, checking to be negative for a function variable which should be positive, etc. They also want to write generic software which can run on Windows, Linux, etc. cause they do not know at where it will be run.
However, there may be still huge problems which haven’t detected. Do you make case insensitive String comparisons at Java? Consider that:

String city = "istanbul";
System.out.println(city.toUpperCase());

You may accept that result will be:

ISTANBUL

On the other hand if you run it at a Turkish locale result will be:

İSTANBUL

This may break your really well designed software! When you upper case an ‘i’ it will be ‘İ’ and when you lower case an ‘I’ it will be ‘ı’ in Turkish. You can see a similar effect for:

getBytes()

method when you pass different character sets into it.

Problem:

Bear in mind that: Do not use default locale, character sets etc.! OK, but how we can detect such cases? There is a plugin for it: forbiddenapis Add it to your project as described at forbiddenapis wiki. When you run it you will probably have such errors:

Forbidden method invocation: java.text.DecimalFormat#(java.lang.String) [Uses default locale]
Forbidden method invocation: java.lang.String#toLowerCase() [Uses default locale]
Forbidden method invocation: java.util.Scanner#(java.io.InputStream) [Uses default charset]
Forbidden class/interface use: java.io.FileReader [Uses default charset]
Forbidden method invocation: java.text.SimpleDateFormat#(java.lang.String) [Uses default locale]
Forbidden method invocation: java.text.MessageFormat#format(java.lang.String,java.lang.Object[]) [Uses default locale]

Solution:
As I mentioned, do not use default Locale, character sets etc. However, which Locale should we use if we won’t use default Locale. Using Locale.ENGLISH may seem a solution for it but what if English character set changes in the future? We should find a generic solution for it as like the approach we develop software. There is a solution for it: using Locale.ROOT. These are examples of fixing such errors:

-  return MessageFormat.format("Stopping in {0} seconds.", DELAY_SEC);
+ return new MessageFormat("Stopping in {0} seconds.", Locale.ROOT).format(DELAY_SEC);
- return new FileWriter(seedFile);
+ return new OutputStreamWriter(new FileOutputStream(seedFile), StandardCharsets.UTF_8));
- SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
+ SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss", Locale.ROOT);
- value.getBytes();
+ value.getBytes(StandardCharsets.UTF_8);
- new FileReader(arg[0]);
+ new InputStreamReader(new FileInputStream(arg[0]), StandardCharsets.UTF_8));
- strValue.toLowerCase();
+ strValue.toLowerCase(Locale.ROOT);
- DateFormat df = DateFormat.getDateTimeInstance();
+ DateFormat df = DateFormat.getDateTimeInstance(DateFormat.MEDIUM, DateFormat.MEDIUM, Locale.ROOT);

Conclusion:
As a result, you should not trust default Locale and character sets to avoid such problems. You should find and fix such API calls.

Sign up to discover human stories that deepen your understanding of the world.

Free

Distraction-free reading. No ads.

Organize your knowledge with lists and highlights.

Tell your story. Find your audience.

Membership

Read member-only stories

Support writers you read most

Earn money for your writing

Listen to audio narrations

Read offline with the Medium app

--

--

furkankamaci
furkankamaci

Published in furkankamaci

Imported from Furkan KAMACI’s blog: www.furkankamaci.com

Furkan KAMACI
Furkan KAMACI

Written by Furkan KAMACI

Software engineer who works on AI and distributed systems and a member of the Apache Software Foundation.

No responses yet

Write a response