Rocksolid Light

Welcome to novaBBS (click a section below)

mail  files  register  newsreader  groups  login

Message-ID:  

Debug is human, de-fix divine.


computers / comp.os.vms / configuration of Java programs on VMS - a little trick (slightly long post)

SubjectAuthor
o configuration of Java programs on VMS - a little trick (slightly longArne Vajhøj

1
configuration of Java programs on VMS - a little trick (slightly long post)

<61fb212b$0$697$14726298@news.sunsite.dk>

  copy mid

https://www.novabbs.com/computers/article-flat.php?id=20619&group=comp.os.vms#20619

  copy link   Newsgroups: comp.os.vms
Path: i2pn2.org!i2pn.org!aioe.org!feeder1.feed.usenet.farm!feed.usenet.farm!news.uzoreto.com!dotsrc.org!filter.dotsrc.org!news.dotsrc.org!not-for-mail
Date: Wed, 2 Feb 2022 19:26:12 -0500
MIME-Version: 1.0
User-Agent: Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:91.0) Gecko/20100101
Thunderbird/91.5.1
Newsgroups: comp.os.vms
Content-Language: en-US
From: arn...@vajhoej.dk (Arne Vajhøj)
Subject: configuration of Java programs on VMS - a little trick (slightly long
post)
Content-Type: text/plain; charset=UTF-8; format=flowed
Content-Transfer-Encoding: 7bit
Lines: 237
Message-ID: <61fb212b$0$697$14726298@news.sunsite.dk>
Organization: SunSITE.dk - Supporting Open source
NNTP-Posting-Host: d1782d6c.news.sunsite.dk
X-Trace: 1643847979 news.sunsite.dk 697 arne@vajhoej.dk/68.9.63.232:61084
X-Complaints-To: staff@sunsite.dk
 by: Arne Vajhøj - Thu, 3 Feb 2022 00:26 UTC

Properties files are pretty easy.

Let us say that the program looks like:

import java.io.FileInputStream;
import java.io.IOException;
import java.util.Properties;

public class PropsDemo {
public static void main(String[] args) throws IOException {
Properties p = new Properties();
FileInputStream fis = new FileInputStream("props.properties");
p.load(fis);
fis.close();
int a = Integer.parseInt(p.getProperty("demo.a"));
System.out.println("a = " + a);
String b = p.getProperty("demo.b");
System.out.println("b = " + b);
int c = Integer.parseInt(p.getProperty("demo.sub.c"));
System.out.println("c = " + c);
String d = p.getProperty("demo.sub.d");
System.out.println("d = " + d);
System.out.println(p.getProperty("demo.src", "**** problem ****"));
}
}

just put a props.properties file in current dir with:

demo.a = 123
demo.b = ABC
demo.sub.c = 456
demo.sub.d = DEF
demo.src = Properties-file

It cannot be much easier than that.

Let us say that the program use an XML properties file like:

import java.io.FileInputStream;
import java.io.IOException;
import java.util.Properties;

public class PropsDemoX {
public static void main(String[] args) throws IOException {
Properties p = new Properties();
FileInputStream fis = new FileInputStream("props.xml");
p.loadFromXML(fis);
fis.close();
int a = Integer.parseInt(p.getProperty("demo.a"));
System.out.println("a = " + a);
String b = p.getProperty("demo.b");
System.out.println("b = " + b);
int c = Integer.parseInt(p.getProperty("demo.sub.c"));
System.out.println("c = " + c);
String d = p.getProperty("demo.sub.d");
System.out.println("d = " + d);
System.out.println(p.getProperty("demo.src", "**** problem ****"));
}
}

just put a props.xml file in current dir with:

<!DOCTYPE properties SYSTEM "http://java.sun.com/dtd/properties.dtd">
<properties>
<entry key="demo.a">123</entry>
<entry key="demo.b">ABC</entry>
<entry key="demo.sub.c">456</entry>
<entry key="demo.sub.d">DEF</entry>
<entry key="demo.src">XML-properties-file</entry>
</properties>

It is a bit more verbose but still OK.

But what if the Java program has decided to use the preferences API?

That API is a creation in the same category as the triangular wheel.

Code in same style as above:

import java.util.prefs.Preferences;

public class PrefsDemo {
public static void main(String[] args) throws Exception {
Preferences prefs = Preferences.userRoot();
int a = prefs.node("demo").getInt("a", 0);
System.out.println("a = " + a);
String b = prefs.node("demo").get("b", "");
System.out.println("b = " + b);
int c = prefs.node("demo/sub").getInt("c", 0);
System.out.println("c = " + c);
String d = prefs.node("demo/sub").get("d", "");
System.out.println("d = " + d);
System.out.println(prefs.node("demo").get("src", "**** problem
****") + " / " + prefs.getClass().getName());
}
}

that requires a [username._java._userprefs.demo]prefs.xml with:

<!DOCTYPE map SYSTEM "http://java.sun.com/dtd/preferences.dtd">
<map>
<entry key="a" value="123"/>
<entry key="b" value="ABC"/>
<entry key="src" value="XML-preference-file"/>
</map>

and a [username._java._userprefs.demo.sub]prefs.xml with:

<!DOCTYPE map SYSTEM "http://java.sun.com/dtd/preferences.dtd">
<map>
<entry key="c" value="456"/>
<entry key="d" value="DEF"/>
</map>

I don't like that way to store preferences.

The only positive is that it is even worse on Windows where it uses the
Windows registry.

Talk about hiding the configuration.

Probably the only good thing about the Preferences API is that
it comes with a SPI so one can easily change the implementation.

There are implementations using ini-file in same dir, XML-fil in
same dir, database etc..

But I wanted an implementation using VMS logicals.

That is a common way to control stuff on VMS. Despite some
not liking it.

EnvPreferencesFactory.java:

import java.util.prefs.Preferences;
import java.util.prefs.PreferencesFactory;

public class EnvPreferencesFactory implements PreferencesFactory {
public Preferences systemRoot() {
return new EnvPreferences(null, "", "systemprefs");
}
public Preferences userRoot() {
return new EnvPreferences(null, "", "userprefs_" +
System.getProperty("user.name"));
}
}

EnvPreferences.java:

import java.util.prefs.AbstractPreferences;
import java.util.prefs.BackingStoreException;

public class EnvPreferences extends AbstractPreferences {
private String tree;
private String name;
public EnvPreferences(AbstractPreferences parent, String name,
String tree) {
super(parent, name);
this.tree = tree;
this.name = name;
}
@Override
protected void putSpi(String key, String value) {
throw new RuntimeException("Definition of properties not
supported");
}
@Override
protected String getSpi(String key) {
String lognam = tree + name + "_" + key;
return System.getenv(lognam.toLowerCase());
}
@Override
protected void removeSpi(String key) {
throw new RuntimeException("Remove of properties not supported");
}
@Override
protected void removeNodeSpi() throws BackingStoreException {
throw new RuntimeException("Remove of properties not supported");
}
@Override
protected String[] keysSpi() throws BackingStoreException {
throw new RuntimeException("Wildcard lookup of properties not
supported");
}
@Override
protected String[] childrenNamesSpi() throws BackingStoreException {
throw new RuntimeException("Wildcard lookup of properties not
supported");
}
@Override
protected AbstractPreferences childSpi(String name) {
return new EnvPreferences(this, this.name + "_" + name, tree);
}
@Override
protected void syncSpi() throws BackingStoreException {
// nothing
}
@Override
protected void flushSpi() throws BackingStoreException {
// nothing
}
}

And now we can:

$ define/nolog userprefs_arne_demo_a 123
$ define/nolog userprefs_arne_demo_b "ABC"
$ define/nolog userprefs_arne_demo_sub_c 456
$ define/nolog userprefs_arne_demo_sub_d "DEF"
$ define/nolog userprefs_arne_demo_src "VMS-logicals"
$ define/nolog java$getenv_process_list
userprefs_arne_demo_a,userprefs_arne_demo_b,userprefs_arne_demo_sub_c,userprefs_arne_demo_su
b_d,userprefs_arne_demo_src
$ define/nolog decc$efs_case_preserve enable
$ java "-Djava.util.prefs.PreferencesFactory=EnvPreferencesFactory" -cp
.. "PrefsDemo"

And voila - that preference API using program is using VMS logicals.

A few notes:
* this trick does not require any changes to the program so it can
be done with a program only available as binary
* this preferences implementation only allows simple get, not listing of
all or setting, but most configuration usage is just getting
* the java$getenv_process_list thing is because apparently some
HP engineers was concerned about allowing Java applications to
call getenv on anything for security reasons - it does not make
any sense to me, but ...
* the jdecc$efs_case_preserve is necessary because otherwise
all values get converted to lowercase - even though the
logical may contain something that is not a file or directory name

Arne

1
server_pubkey.txt

rocksolid light 0.9.8
clearnet tor