Over a million developers have joined DZone.
{{announcement.body}}
{{announcement.title}}

Forbidden APIs of Java

DZone's Guide to

Forbidden APIs of Java

Dealing with locale settings and APIs can be hazardous. Read on to find out how to deal with this situation!

· Java Zone
Free Resource

Are you joining the containers revolution? Start leveraging container management using Platform9's ultimate guide to Kubernetes deployment.

Software developers try to take care of many cases when they develop software. They make checks for null comparisons, checking for a 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 where it will be run.

However, there may be still huge problems which haven’t been detected. Do you make case insensitive String comparisons in Java? Consider this:

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, the 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 a 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 this, but what if English character set changes in the future? We should find a generic solution: 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.

Moving towards a private or Hybrid cloud infrastructure model? Get started with our OpenStack Deployment Models guide to learn the proper deployment model for your organization.

Topics:
software ,developers ,java ,api

Published at DZone with permission of Furkan Kamaci, DZone MVB. See the original article here.

Opinions expressed by DZone contributors are their own.

THE DZONE NEWSLETTER

Dev Resources & Solutions Straight to Your Inbox

Thanks for subscribing!

Awesome! Check your inbox to verify your email so you can start receiving the latest in tech news and resources.

X

{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}