Over a million developers have joined DZone.

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

Microservices! They are everywhere, or at least, the term is. When should you use a microservice architecture? What factors should be considered when making that decision? Do the benefits outweigh the costs? Why is everyone so excited about them, anyway?  Brought to you in partnership with IBM.

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";

You may accept that result will be:


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


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.


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]


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);


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

Discover how the Watson team is further developing SDKs in Java, Node.js, Python, iOS, and Android to access these services and make programming easy. Brought to you in partnership with IBM.

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 best of DZone straight to your inbox.

Please provide a valid email address.

Thanks for subscribing!

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

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

{{ parent.tldr }}

{{ parent.urlSource.name }}