Set System Property for an RCP Program - java

I have an RCP/Eclipse program and I want to provide it in 2 different flavors. Which flavor it is should be sort of hardcoded or provided as a conf setting that cannot be changed at runtime.
I was first thinking of having one specific class in my plugin duplicated and code the logic of the second flavor into that class and package it somehow as a second RCP program. Then I thought I can simple code the 2 different flavors in one class in the same plugin and differentiate by system property whether logic 1 or logic 2 is executed. Then I could've simply duplicated the RCP package and deliver one with an additional parameter in launcher.ini and the other without that parameter.
Problem is that I can't get a simple Java System Property set in an RCP program. I have tried launcher.exe -Dpropname=propvalue, I have tried adding it to launcher.ini, I have googled the web back and forth. There are lots of documents on the web explaining all the various configuration settings that you can provide as system property or as property to launcher.ini but none explains how to set custom properties.
Does anybody have an idea?
Many thanks,
Kai

go to the run configuration, you will get the arguments tab, there in VM Arguments block you can provide -Dpropname=propvalue. If you have more values you can enter with space or newline separating them.

Related

M2Eclipse: how define the Program Arguments such as the VM Arguments?

I have a clear understanding about the difference between:
VM arguments
Program arguments
And how define them through the console/terminal and how retrieve them through the Main class.
Until here I am ok
But through Eclipse or STS, the things are different.
For a simple Java application is possible define them as follows:
From above, is clear and straightforward where define these two sets or groups of values, again - until here I am ok too.
The situation is for a Java application working with Maven and therefore through m2Eclipse as follows:
From above, just playing or experimenting, I confirmed the following:
The VM arguments can be defined in two ways: either directly the Goals text field
or through the Parameter Name/Value area located in the bottom. Of course, better is the latter due presentation advantages and considering the scenario if exists many parameters/values to define
The problem is about Program arguments, only is possible define them through the Goals text field, therefore working with:
-Dexec.args="arg1 arg2 arg3"
I could not find, through the other tabs, a similar support how exists for the VM arguments
Am I missing something?
Perhaps exists other plugin or patch that complements this case?
or is totally mandatory work around -Dexec.args="arg1 arg2 arg3"?
The problem is when many Program arguments are need it.
By the moment I am using the Goals text field.

Is it correct for Java system properties to be used to set and get arbitrary program parameters?

It is possible using -Dproperty=value arguments to set arbitrary system properties (not some fixed set of system properties actually used by the JVM) and a program can get these properties later using System.getProperty("property"). Is it correct to do this?
I haven't found an authoritative answer on this, so that's why I'm asking here. It seems to me that program parameters should be set through command line arguments to the program, not to the JVM. However, perhaps this is an accepted practice that just isn't documented anywhere I've looked so far. I'd like to be sure. Thanks.
I think Java system properties are used to pass values from command line to libraries or plugins inside the execution. It is, that insider component has no direct way to receive the parameter from the main program that's executing it. So it reads it from a "context" that Java system properties are.
If we look at it as layers, command line arguments would be parameters for the inmediate lower layer, and system java properties are context for all the lower layers.
command line: arguments + properties
main program: uses arguments
some library/plugin: uses properties from context
If it's not this way the main program should have to carry all the parameters that user could set to the lower layers and it can be very cumbersome.
I don't like to depend on contextual properties so if I design a program I'd try to pass over all the properties in some non-global way. But it can be very handy some times (and using namespacing it's not probable they collide).
In my opinion this is not "incorrect" and there are programs and libraries that do use their own system properties for configuration.
However, it is probably more practical to put configuration parameters for your software in a configuration file (in whatever format you think is suitable - a .properties file, an XML file, or something else). It is cumbersome, especially if you have many configuration parameters, to have to put all those parameters on the command line with -Dname=value options.
You can use this method to set some of your application settings. I think of settings as a contrast to program arguments. For example. Let's think abount some file converter. It converts file A to B. So files A and B should be command line params. If you converter needs some temporary folder you can make id settable by -Dmy.package.tempfolder=\my\tmp\folder. But there should be a default setting for that and the program should work without this setting.
Think about it as an alternative to .properties file. .properties file will be more convinient of course.
You just have to know what you're doing. If your application is a standalone application, system properties provide an easy to use way to pass named arguments, in any order, to the program, and I don't see anything intrinsically bad in using them.
If your app is a webapp that must be deployed in a app server shared by multiple webapps, then it might not be a good idea, especially if you aren't allowed to change how the server is started, or if you have to deploy multiple versions of the same application.
From http://docs.oracle.com/javase/tutorial/essential/environment/sysprop.html:
For example, the following invocation of getProperty looks up the
System property called subliminal.message. This is not a valid system
property, so instead of returning null, this method returns the
default value provided as a second argument: "Buy StayPuft
Marshmallows!"
System.getProperty("subliminal.message",
"Buy StayPuft Marshmallows!");
This implies that properties other than those used by the JVM are "invalid". However, later in the same document, it gives the example of loading a properties file containing the same property setting.
subliminal.message=Buy StayPuft Marshmallows!
It only advises "In general, be careful not to overwrite system properties."
So it seems that this is a supported use of System Properties. It looks like a case of misleading naming. When I hear "System Properties" I think "properties of the JVM" where the JVM is the system. While the properties are used for this, they can also be used for application settings. I think I'll make a mental note to think of this as "System and Application Properties".
Does anyone disagree with this?

How to tell if a system property comes from human operator, not from default?

I have a JAR-packaged standalone application that, when executed, unpacks itself into a temporal directory and spawns a child process within that directory. The reason being some third-party code and configuration assumes data files are found relative to current working directory, and java has no chdir() method, so the only way is to switch the working dir for a child process.
All works fine, except for the system properties. An operator may decide to specify some system properties in the command line, both standard ones and ones related to the third-party configuration:
java -Djava.io.tmpdir=/temp -Dsomething=else -jar foo.jar (parameters)
The system properties available to the parent java process are not by default propagated to child. I should do it myself. And here I get into a roadblock: I have no way to tell which properties are set by operator and which are initialized by default by JVM.
Take that java.io.tmpdir one. If operator has provided it, he has a good reason to do so (perhaps the default location is "disk full"). I have to set it to child process, or it will fail. But how do I know if it came from operator? It may be just the default value.
I may try and set all available system properties to the child process. It takes a long list though and, worse, fails in some environments where the command line length is limited.
The only workaround I've found so far (quite a wicked one) is to spawn another child process first, with no arguments at all, and let it pipe back to the parent all the system properties it has. The values that match those that parent has are defaults. The rest should be passed down to the worker child process.
Does anyone have a better alternative?
Where I work, we had a slowly growing list of system properties that users could apply, and while we did not have the child process to worry about, we did have a different issue: there were simply too many.
Rather than making the user supply system properties via the command line (or, in our case, making the line in the script that launches the application yet another property longer), we added support for loading a .properties file by default.
If you can convince users to put permanent properties there, then start the process of launching the child process, and then loading from the file, you could avoid the headache altogether.
Still, you would likely be presented with debug scenarios where temporary, or one-time properties are desired without modifying the file (not that it's really a big deal). You have a few choices here:
Continue to use the approach you are currently.
Get the user to pass the system properties as command line arguments that you then load into system properties for both the parent and child process.
Say tough, use the file. (Not a terrible thing, but I would be annoyed with that solution as a user)
I don't think there is a good answer to this. But fortunately, most of the standard system properties either can't be overridden, or nobody in their right mind would override.
So the following approaches are probably your best bets:
pass on the subset of the standard properties that you think that it makes sense to pass on,
provide a way to specify the JVM options (including -D options) to be used for child JVMs, or
a combination of the above approaches.
Chosen solution:
I still had to go with a child process that does nothing but passes the parent all the system properties it gets to compare. The only minor issue I stumbled upon was line.separator property which caused my line reading code stumble on extra empty line. That was easy to fix.
Why I accepted none of answers:
Approaches suggested in the answers below are reasonable, but none of them is completely satisfying.
I do not have much power over the users to tell them that Java system properties should be passed via a property file or a special command-line argument. This is awkward and goes against operational practices (special cases are always bad).
I cannot also select a subset of system properties to pass to the child process. System class documentation doesn't tell which ones are OK to overwrite (and common sense replaces no documentation). There is also a facility for end-user to define their own properties, and those I cannot predict neither by name no number.

Java tip for plugin-like architecture

My application will output a graph, for which the layout is to be defined by the user. The custom layout class should implement an interface defined by me.
How should I do this? Have a special folder where I look for layout classes? Have the user pass the class name as argument to the app?
Any help would be greatly appreciated.
Multiple approaches used at the same time usually give the best results here. Different users may choose different ways to configure your application. For example:
A default directory where users can put plugins. Or even a list of directories, which could include some subdirectory of the application folder, some system-wide directory in the platform-dependent "application data" place, some user-local directory.
A config file with some options to control plugins search and selection.
A Java system property which specifies a list of directories to search for plugins, like java -Dorg.something.appname.plugindirs=plugindir1;plugindir2.
A special command-line option or Java system property to select a particular plugin, possibly providing an absolute path or just a name to look up in the directories specified by the methods above.
I think that the more ways your application provide, the better. Of course, it should have some sort of default setup so users won't have to bother with all that stuff if they don't want to. Also, the order of using those options should be sensible: for example, it makes perfect sense for the user plugins to override the system ones, not the other way around.
The model chosen by toolkits years over, AWT, Swing, etc. is to be passed the layout as an argument to your API. Assuming you're being invoked from the commandline:
java -jar yourapp.jar;theirintf.jar yourapp org.example.theirintf
Don't try and be overly magical with special folders and conventions. Just take it as an argument. Please have a default value if the user choose not to create one of their own - your app should be usable on it's own.

Keeping i18n resources synced

I am looking for an editor/comparator for i18n property files that would help me keep different language files in sync.
Basically, something that would compare a bunch a of property files and show which keys are not present in a particular language.
a property would look something like
component.titlepage.title = hello world
A simple diff is not possible since the right-hand-side will be different from a language to another.
Our current infrastructure:
Java application
Built using maven2
Different i18n property files for different components of the system. (1 property file per language per component)
The Checkstyle tool, which I typically run as part of every continuous integration build which is done after every check-in to the main branch, will tell you if any given set of properties files has an inconsistent set of properties. When I first started using Checkstyle, I indeed found that a few of my properties files were missing a small number of properties.
This won't help on the editor end, but it will help you efficiently identify any gaps.
If you are using Eclipse, I find the ResourceBundle Editor plugin very handy. You can edit several properties files at the same time and you have warnings when a key is missing in one of the files.
There are also a number of web applications that allow you to do that (along with many other activities). To name a few:
Amanuens (disclaimer: my company builds this product)
Transifex
Get Localization

Categories

Resources