Compiler warning: Non-exernalized string literal; it should be followed by //$NON-NLS-<n>

R

Rhino

I'm trying to clean up all of the compiler warnings in my projects but I'm
getting a few I don't understand. I'll post each one in a separate thread.
I've cited the first of these warnings in my Subject line.

What does this warning mean and how do I get rid of it?

A typical line which generates this message is:

static final String OUTPUT_FILE_PATH = "pdf/";

I tried taking the message literally and amended the line so that it said
this:

static final String OUTPUT_FILE_PATH = "pdf/"+"//NON-NLS-<n>$";

but the warning did not go away.

I'm not really surprised - I assumed that "//NON-NLS-<n>$" is not really a
literal that I am supposed to append to the String in question - but I don't
know the correct way of resolving this warning.

Can anyone enlighten me?

I'm using Eclipse 3.1.1 with all compiler conditions set to either 'Error'
or 'Warning'; nothing is set to 'Ignore'.
 
C

Chris Smith

Rhino said:
A typical line which generates this message is:

static final String OUTPUT_FILE_PATH = "pdf/";

I tried taking the message literally and amended the line so that it said
this:

static final String OUTPUT_FILE_PATH = "pdf/"+"//NON-NLS-<n>$";

but the warning did not go away.

What you want is:

static final String OUTPUT_FILE_PATH = "pdf/"; //$NON-NLS-1$

The comment at the end just serves to inform the part of Eclipse that
generates these warnings that you don't intend to externalize that
particular String. That's fine, because it's a path name. Only Strings
that will be user-visible should be externalized.

Incidentally, if that were the second string on the line, you would use
NON-NLS-2 instead. That's what <n> means.

--
www.designacourse.com
The Easiest Way To Train Anyone... Anywhere.

Chris Smith - Lead Software Developer/Technical Trainer
MindIQ Corporation
 
R

Rhino

Chris Smith said:
What you want is:

static final String OUTPUT_FILE_PATH = "pdf/"; //$NON-NLS-1$

The comment at the end just serves to inform the part of Eclipse that
generates these warnings that you don't intend to externalize that
particular String. That's fine, because it's a path name. Only Strings
that will be user-visible should be externalized.

Incidentally, if that were the second string on the line, you would use
NON-NLS-2 instead. That's what <n> means.
Thank you, that was very helpful.

Just a followup question or two to make sure I understand this properly....

Am I correct in understanding that 'externalize' means that the String
should in a ResourceBundle if it is meant to be viewed by users? That would
make perfect sense to me since it means you can use i18n/l10n to easily
supply support for multiple languages and locales.

However, I'm a bit perplexed by why I get these messages in files that _are_
resource bundles. Am I really supposed to hand-code the "NON-NLS-<n>"
comment on each and every line of my resource bundles that contain Strings?

Eclipse is a pretty smart IDE; is it really unable to determine that a
String is already in a resource bundle and therefore shouldn't have this
message generated for Strings in this bundle?

Rhino
 
R

Rhino

Chris Smith said:
What you want is:

static final String OUTPUT_FILE_PATH = "pdf/"; //$NON-NLS-1$

The comment at the end just serves to inform the part of Eclipse that
generates these warnings that you don't intend to externalize that
particular String. That's fine, because it's a path name. Only Strings
that will be user-visible should be externalized.

Incidentally, if that were the second string on the line, you would use
NON-NLS-2 instead. That's what <n> means.
Another followup question: I tried putting //$NON-NLS-1$ at the end of the
line containing my first non-externalized String and saved the revised file;
the compiler warning for this line went away.

However, the warning has NOT gone away on any of the subsequent
non-externalized Strings in the class, even though I used ascending numbers
in the comments. What do I need to do differently when there are multiple
non-externalized Strings in a Class?

Here is a fragment to illustrate my problem:

public class GenerateHelloPdf {

/**
* The path to the PDF output directory relative to the Eclipse
workspace.
*/
static final String OUTPUT_FILE_PATH = "pdf/"; //$NON-NLS-1$

/**
* The main() method creates the application.
*/
public static void main(String[] args) {

new GenerateHelloPdf();
System.exit(0);
}

public GenerateHelloPdf() {

/* Write "Hello, World" in PDF format. */
writeHelloPdf();

}

private void writeHelloPdf() {

/* Identify the output file. */
String strOutfile = OUTPUT_FILE_PATH + "HelloWorld.pdf";
//$NON-NLS-2$

/* Set the document properties and open the document. */
document.addTitle("Hello World"); //$NON-NLS-3$
document.addAuthor("Rhino"); //$NON-NLS-4$
document.addSubject("Sandbox for trying iText experiments");
//$NON-NLS-5$
document.addKeywords("Rhino, sandbox"); //$NON-NLS-6$
document.addCreator(this.CLASS_NAME + " using iText"); //$NON-NLS-7$
document.open();
}
}

Curiously, if I change the comments so that they all say //$NON-NLS-1$ the
warnings go away even though there are now several occurrences of that exact
comment throughout the program now.

Hmmm....

I just did some digging in the Eclipse help and discovered the Externalize
Strings facility. I used it on the same class and it used //$NON-NLS-1$ for
all lines that contained only a single non-externalized String. If the line
contained _two_ non-externalized Strings, it put //$NON-NLS-1 //$NON-NLS-2
on the line.

Okay, I get it now:
1. The sequence number of the first non-externalized String on the line is
always 1.
2. The sequence number only needs to be incremented if there are multiple
non-externalized Strings on the same line.
3. The Source/Externalize Strings facility should be used to generate the
comments for any Strings which shouldn't be externalized and to externalize
the Strings that should be externalized.

I understand the sequence number thing now; I just wrote all this down in
case someone in the future is researching the same issue via a Google Groups
search.

Rhino
 
T

Thomas Weidenfeller

Rhino said:
I'm trying to clean up all of the compiler warnings in my projects but I'm
getting a few I don't understand. I'll post each one in a separate thread.

Please not. What about first of all RTFM?

http://help.eclipse.org/help31/index.jsp

HINT: The search function on that page is very useful.
I've cited the first of these warnings in my Subject line.

What does this warning mean and how do I get rid of it?

That you turned on a warning without knowing what you are doing. That
particular warning is for supporting you in internationalizing your
application. Do you plan to internationalize your application? If not,
turn the warning off. If yes, then that string should either be moved to
a resource bundle (externalized) or similar, or marked as a string which
is not supposed to be internationalized. That marking is done with an
Eclipse-specific comment - yes, the "//" in the warning message mean
comment.

Please RTFM to figure out the format of the comment.
Can anyone enlighten me?

Read the documentation. It is not that hard.

/Thomas
 
R

Rhino

Thomas Weidenfeller said:
Please not. What about first of all RTFM?

http://help.eclipse.org/help31/index.jsp

HINT: The search function on that page is very useful.
I'm well aware of the Help manual and the search function. However, I didn't
know what to use for a search string.
That you turned on a warning without knowing what you are doing. That
particular warning is for supporting you in internationalizing your
application. Do you plan to internationalize your application? If not,
turn the warning off. If yes, then that string should either be moved to a
resource bundle (externalized) or similar, or marked as a string which is
not supposed to be internationalized. That marking is done with an
Eclipse-specific comment - yes, the "//" in the warning message mean
comment.
In a previous thread that I initiated yesterday, I asked people how many
warnings are acceptable in a program and which conditions should be set to
'ignore' in the compiler settings: several people suggested that _no_
conditions should be ignored and that no warnings should be allowed to exist
within the program. I found their views persuasive and set all conditions
that had previously been 'ignore' to 'warning'. In other words, I realize I
can make the message go away by setting that condition to 'ignore' but I am
choosing not to do so: I wanted to find the way to make the message stop by
cleaning up the code.
Please RTFM to figure out the format of the comment.


Read the documentation. It is not that hard.
Actually, I *do* RTFM: that's why you don't see any further questions about
compiler warnings from me in this newsgroup: I figured out the remaining
ones from the help manuals and, of course, from my own knowledge of Java.

Rhino
 
C

Chris Smith

Rhino said:
I understand the sequence number thing now; I just wrote all this down in
case someone in the future is researching the same issue via a Google Groups
search.

You might have noted that earlier. I just spent five minutes writing
you a detailed explanation of what you already knew.

--
www.designacourse.com
The Easiest Way To Train Anyone... Anywhere.

Chris Smith - Lead Software Developer/Technical Trainer
MindIQ Corporation
 
C

Chris Smith

Rhino said:
Eclipse is a pretty smart IDE; is it really unable to determine that a
String is already in a resource bundle and therefore shouldn't have this
message generated for Strings in this bundle?

Eclipse is only able to do what it contains code to do... so yes, it is
unable to recognize that.

As for an explanation, simplicity is a valuable goal. Instead of
creating somewhat complex rules for when you do or don't need a NON-NLS
comment, the designers just decided that you always do. That makes
sense, and it makes it more predictable when you'll get diagnostics from
the compiler.

--
www.designacourse.com
The Easiest Way To Train Anyone... Anywhere.

Chris Smith - Lead Software Developer/Technical Trainer
MindIQ Corporation
 
C

Chris Smith

Rhino said:
In a previous thread that I initiated yesterday, I asked people how many
warnings are acceptable in a program and which conditions should be set to
'ignore' in the compiler settings: several people suggested that _no_
conditions should be ignored and that no warnings should be allowed to exist
within the program. I found their views persuasive and set all conditions
that had previously been 'ignore' to 'warning'.

I strongly suggest that you reconsider being persuaded. If you continue
this way, you will spend a lot of time solving pseudo-problems that
aren't actually worthy of your time or attention. By all means
understand all of those warnings, but turning some on will do more harm
than good to your code. See else-group for specific examples.

--
www.designacourse.com
The Easiest Way To Train Anyone... Anywhere.

Chris Smith - Lead Software Developer/Technical Trainer
MindIQ Corporation
 
R

Rhino

Chris Smith said:
You might have noted that earlier. I just spent five minutes writing
you a detailed explanation of what you already knew.
I noted it as soon as I figured it out - literally. I don't see how I could
have done it sooner.

Rhino
 
R

Rhino

Chris Smith said:
I strongly suggest that you reconsider being persuaded. If you continue
this way, you will spend a lot of time solving pseudo-problems that
aren't actually worthy of your time or attention. By all means
understand all of those warnings, but turning some on will do more harm
than good to your code. See else-group for specific examples.
Actually, there were only a few basic categories of errors - although the
quantity of each type was substantial in some cases - and all of them leant
themselves to fairly simple resolutions. My warnings are all gone now and I
like the fact that none of the compiler conditions are set to 'ignore' any
more: I have no warnings because I have no bad code. (That is not to say
that my code is suddenly great, just that it is better than it was.)

I don't understand your last sentence: what is 'else-group' and where do I
find it to look at the examples you cite?

Rhino
 
C

Chris Smith

Rhino said:
I noted it as soon as I figured it out - literally. I don't see how I could
have done it sooner.

Sorry to be confusing. I meant earlier in the message.

--
www.designacourse.com
The Easiest Way To Train Anyone... Anywhere.

Chris Smith - Lead Software Developer/Technical Trainer
MindIQ Corporation
 
C

Chris Smith

Rhino said:
Actually, there were only a few basic categories of errors - although the
quantity of each type was substantial in some cases - and all of them leant
themselves to fairly simple resolutions. My warnings are all gone now and I
like the fact that none of the compiler conditions are set to 'ignore' any
more: I have no warnings because I have no bad code. (That is not to say
that my code is suddenly great, just that it is better than it was.)

That's great, if your code really is better.

However, if you went through and changed all your anonymous inner
classes to avoid accessing private members of their containing class,
then I would classify that as worse code -- more syntax to accomplish
the same thing, making it harder to modify and harder to understand
what's going on.

Same thing if you remove all your boxing and unboxing conversions. The
conversions are obvious and they make code that performs calculations in
conjunction with Collections API objects much clearer and easier to
understand. By removing them, you will write worse code.

Serialization is designed to fail deterministically and obviously if you
modify the internal representation of a class without going out of your
way to indicate that you've kept it compatible... and there are good
reasons for that. But if you add serialVersionUID fields just because
Eclipse tells you to and you don't make the committment to keep the
serializable form of those classes compatible, then you are turning what
would have been an obvious easy-to-find bug into a nondeterministic
logic error of the type that creeps up at the worst possible moment.
Hardly better code.

If you insist on being warned about using deprecated APIs from the
implementation of other deprecated code, then you're just making things
difficult. Either you will just ignore the warnings that Eclipse
produces, or you'll end up modifying old code for no other reason than
to prevent warnings, and risk introducing new bugs into stable code.

If you insist on removing "unnecessary" checked exceptions from the
signatures of public API classes, you will end up being very restrictive
on others who subclass your classes. They will often end up forced to
throw unchecked exceptions because you never bothered to give them the
option to throw something reasonable and checked.

If you insist on removing "unnecessary" method parameters, you will
similarly restrict your own ability to provide the necessary information
for flexible subclasses to use for implementing what they need. They
will either be unable to accomplish their goals, or be forced to
artifically maintain long-term state that is redundant, and thus add a
new opportunity for bugs due to inconsistency.

Those are the warnings as of Eclipse 3.2M3 that can obviously decrease
the quality of your code or prevent you from being productive as a
developer.

("else-group" just meant "in other threads in this group".)

--
www.designacourse.com
The Easiest Way To Train Anyone... Anywhere.

Chris Smith - Lead Software Developer/Technical Trainer
MindIQ Corporation
 
R

Rhino

Chris Smith said:
That's great, if your code really is better.

However, if you went through and changed all your anonymous inner
classes to avoid accessing private members of their containing class,
then I would classify that as worse code -- more syntax to accomplish
the same thing, making it harder to modify and harder to understand
what's going on.

Same thing if you remove all your boxing and unboxing conversions. The
conversions are obvious and they make code that performs calculations in
conjunction with Collections API objects much clearer and easier to
understand. By removing them, you will write worse code.

Serialization is designed to fail deterministically and obviously if you
modify the internal representation of a class without going out of your
way to indicate that you've kept it compatible... and there are good
reasons for that. But if you add serialVersionUID fields just because
Eclipse tells you to and you don't make the committment to keep the
serializable form of those classes compatible, then you are turning what
would have been an obvious easy-to-find bug into a nondeterministic
logic error of the type that creeps up at the worst possible moment.
Hardly better code.

If you insist on being warned about using deprecated APIs from the
implementation of other deprecated code, then you're just making things
difficult. Either you will just ignore the warnings that Eclipse
produces, or you'll end up modifying old code for no other reason than
to prevent warnings, and risk introducing new bugs into stable code.

If you insist on removing "unnecessary" checked exceptions from the
signatures of public API classes, you will end up being very restrictive
on others who subclass your classes. They will often end up forced to
throw unchecked exceptions because you never bothered to give them the
option to throw something reasonable and checked.

If you insist on removing "unnecessary" method parameters, you will
similarly restrict your own ability to provide the necessary information
for flexible subclasses to use for implementing what they need. They
will either be unable to accomplish their goals, or be forced to
artifically maintain long-term state that is redundant, and thus add a
new opportunity for bugs due to inconsistency.

Those are the warnings as of Eclipse 3.2M3 that can obviously decrease
the quality of your code or prevent you from being productive as a
developer.
Okay, I hear you. Most of the conditions you meant didn't pertain to this
batch of code but may crop up more as I incorporate more of the 1.5
features. I'm just starting to use those features this week so I don't have
much code in that category yet. Also, I've only cleaned up one medium-sized
project so far - kind of a pilot project - so some of the situations you
mention may be present in the projects I haven't cleaned up yet. I'll try to
keep your suggestions in mind.
("else-group" just meant "in other threads in this group".)
Thanks for the clarification; I really didn't understand what you meant.

Rhino
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,769
Messages
2,569,581
Members
45,057
Latest member
KetoBeezACVGummies

Latest Threads

Top