Need Testers for *nix - 'libXm.so' file detector

  • Thread starter Andrew Thompson
  • Start date
A

Andrew Thompson

This is a repost from a JDIC forum message from Oct. 2nd.
<https://screensavers.dev.java.net/servlets/ProjectForumMessageView?forumID=698&messageID=4325>

The forum (for the 'Saverbeans' Java based screensavers) is a
bit quiet and I have got no responses, so I am reposting here
in the hope of getting some.

Here is the problem..

I intend to make an installer for screen savers. While
installation on Win is pretty straightforward, *nix boxes
(Solaris, Unix, Linux) are more complicated, primarily
because of the inconsistencies in the set-up.

As such, I intend to use a simple class to attempt to detect
the appropriate paths, and I figure that if I can detect the
presence of 'libXm.so', that will get me %90 of the way.

I have hacked out some crude code to begin testing this
theory, it is below. I would appreciate if some *nix
enabled devlopers could run it on their boxes and paste
the results back for me.

Please note that if the code fails to find the file on any
of the paths defined for the java.library.path, it will then
revert to a 'brute force' search of the local disks
returned by File.listRoots(), so it might take 'a few
moments'..

Suggestions for improvement are welcome. I do not have
a *nix box on which to test, and I would not be surprised
if many of my naiive assumptions are wrong, we'll start
fixing them here.

<sscce>
import java.io.File;
import java.util.Arrays;
import java.util.ArrayList;

/** This class searches for the existence of the libXm.so file
that is indicative of the installation of XScreensaver on *nix
based systems. */
class XScreensaverPath {

/** Array of directories that form a path to the libXm.so file */
public final String[] pathToLibXm = {
"usr", "X11R6", "lib",
"libXm.so" // for the real test on *nix boxes
// "tomcat.ico" // for testing on a Win box w/Tomcat
};

/** Path to the libXm.so file, built from the pathToLibXm array
using the platform path separator. */
String relativePath;

/** Flag to indicate the libXm.so file has been located. */
boolean found = false;

/** The file object that represents the libXm.so file. */
File libXmSo = null;

/** Compile true for debugging output. */
public static final boolean TEST = false;

/** The XScreensaverPath constructor. Automatically searches for
the XScreensaver existence by detecting the path to a crucial
file. */
XScreensaverPath() {
File f = getXScreensaverPath();
String result = "not found";
if (f!=null) {
result = f.toString();
}
System.out.println( "libXm.so - Search (1): " + result );

if (f==null) {
searchRoots();
if (f!=null) {
result = f.toString();
}
System.out.println( "libXm.so - Search (2): " + libXmSo );
}
}

/** Build the pathToLibXm into the relativePath. */
public void initializePathString() {
String sep = System.getProperty( "file.separator" );
relativePath = "";
for( int ii=0; ii<pathToLibXm.length; ii++ ) {
relativePath += pathToLibXm[ii] + sep;
}
relativePath = relativePath.substring(0,
relativePath.length()-1);
if (TEST) System.out.println("XSP.XSP: " + relativePath);
}

/** Searches the java library path to ascertain if the
libXm.so file is on it.*/
public File getXScreensaverPath() {
initializePathString();
String s = System.getProperty("java.library.path");
String[] paths = s.split(
System.getProperty("path.separator") );
Arrays.sort(paths);
ArrayList uniquePath = new ArrayList();
for (int ii=0; ii<paths.length; ii++) {
if (ii>0 && !paths[ii].equals(paths[ii-1]) ) {
uniquePath.add( paths[ii] );
System.out.println( "paths: " + paths[ii] );
}
}
File f = null;
for (int ii=0; ii<uniquePath.size(); ii++) {
File f1 = new File(
(String)uniquePath.get(ii), relativePath );
if (TEST) System.out.println( "XSP.gXSP: " + f1 );
if ( f1.exists() ) {
f = f1;
break;
}
}
return f;
}

/** Searches the 'roots' for the 'libXm.so' file.
A brute force method used if the targetted search fails. */
public void searchRoots() {
File[] roots = File.listRoots();
File libXm = null;
int ii = 0;
while ( ii<roots.length && !found ) {
searchDirectory(roots[ii]);
ii++;
}
}

/** Searches a directory and all it's subdirectories for
the 'libXm.so' file. */
public void searchDirectory(File f) {
if (TEST) System.out.println("XSP.sD: " + f);
File[] files;
File libXm = null;
if (!found) {
try {
File libXmTest = new File(f,
pathToLibXm[pathToLibXm.length-1]);
if (TEST) System.out.println("XSP.sD: " +
libXmTest + "/" + libXmTest.exists() );
if ( libXmTest.exists() ) {
found = true;
libXm = libXmTest;
libXmSo = libXmTest;
} else {
// search the sub-directories.
files = f.listFiles();
int ii = 0;
while ( ii<files.length && !found ) {
if ( files[ii].isDirectory() ) {
searchDirectory( files[ii] );
}
ii++;
}
}
} catch (NullPointerException npe) {
// empty/inaccessible disk
}
}
}

/** Create an XScreenaverPath instance and let it do it's stuff. */
public static void main(String args[]) {
new XScreensaverPath();
}
}
</sscce>
 
T

Thomas Weidenfeller

Andrew said:
As such, I intend to use a simple class to attempt to detect
the appropriate paths, and I figure that if I can detect the
presence of 'libXm.so', that will get me %90 of the way.

Well, I don't know why you want to do that, especially, because there
might be multiple X installations on a system, so there is absolutely no
guarantee that you can detect anything out of this.

I also don't see why (at least on Unix) the installation of a screen
saver requires to know the location of Xm. And, why are you looking for
libXm, and not libX?

I would recommend something else: Instead of trying to somehow figure
out a Java way to do it, check the native installation procedures on
these platforms.

If supporting many different installation mechanisms gets to time
consuming or confusing, just do what has been done in the last 30 years:

Provide a tar file, which also includes a small install shell script,
asking the user the necessary questions when run.

If you distribute source code, provide a configure script. if you have
the time to work through it, consider creating the configure script with
GNU autoconf.
I have hacked out some crude code to begin testing this
theory, it is below. I would appreciate if some *nix
enabled devlopers could run it on their boxes and paste
the results back for me.

I will refuse to run it, because your code is outright dangerous. The
moment you really start to search for libXm from the root down, two
things can and will happen on non trivial systems:

(a) You will walk all network-mounted file systems, generating a lot of
network traffic for nothing,

(b) You have absolutely no precaution for running into endless loops,
created by symlinks pointing to one of their own parent directories.

If (b) happens on a file system as pointed out in (a) ...

As some food for thought, on my little workstation I get:
488 2929 44599

No joke ...
Please note that if the code fails to find the file on any
of the paths defined for the java.library.path, it will then
revert to a 'brute force' search of the local disks
returned by File.listRoots(), so it might take 'a few
moments'..

Don't do it. It might take more than just a few moments.

Please, instead, tell us which directories you need to know for this
screen saver installation, and why you need them.

/Thomas
 
A

Andrew Thompson

Please, instead, tell us which directories you need to know for this
screen saver installation, and why you need them.

Thanks for your interest ( and the possible avoidance of those
disasters you were referring to ;-) perhaps it is best if you
look over the 'Unix ReadMe' file I have placed here..
<http://www.physci.org/saver/unix_readme.txt>

I need to detect
a) the existence of the 'xscreensaver'. To know whether
the box has the necessary functionality installed.
b) the correct directories to install components..
the example refers to SCREENSAVER_BIN & SCREENSAVER_CONF
and all the paths start with /usr/..

Suggestions (in addition to your earlier ones) welcome.
 
T

Thomas Weidenfeller

Andrew said:
perhaps it is best if you
look over the 'Unix ReadMe' file I have placed here..
<http://www.physci.org/saver/unix_readme.txt>

This is fubar in multiple ways. No, I don't blame you, I blame Sun :)

Just some issues:

- You will notice that they require to provide valid values for jdkhome
and xscreensaverhome before compiling. In other words, these locations
are probably hard-coded in the binaries, jars, or whatever. If this is
the case, the result can not be freely installed at all.

- You have to install (so I guess you also have to compile :) a native
wrapper. So you would need to compile this wrapper for each and every
target platform you want to support. If you want to have one "Unix
installation package", you would have to bundle the wrappers for the
different platforms with your installation package. BTW: I would bet
that Sun has made no provision to cross-compile these native wrappers.
So, to build them you would need access to all the platforms you want to
support (or set up cross compilation by yourself) ...

- They don't distinguish between an installation for one user and an
installation for all users. They always suggest the later, which is bad,
because no sane sysadmin will hand you the root password to allow you to
install some screen saver

- At least on my old trusted Solaris 2.8 there is no xscreensaver by
default. Instead, there is the old xlock (OpenWindows) and dtscreen
(CDE/Motif). CDE/Motif screen savers use a particular CDE API - so the
Java screen savers might not be integratable at all. Also, adding a
screen saver to CDE/Motif is a rather strange process (requiring to set
some environment variable and to provide particular CDE actions to start
the saver). And, of course, instead of lesstif Solaris has the real
Motif library Xm.

- Just providing the Java source (or a precompiled .class) and pointing
Unix users to the screensaver SDK will also not work. At least not for
Solaris users, since Solars does not come with a C compiler. I doubt Joe
Average User will install a C compiler (Sun's is expensive, setting up
GCC is some work) just to install a screen saver. And Joe Average User
would also need ant, probably a JDK and not just a JRE, and the sources
for xscreensaver.

All in all, a real mess which Sun has created here. To get it working
you would have to spend a significant amount of time, and you would need
access to the platforms.

/Thomas
 
A

Andrew Thompson

...To get it working
you would have to spend a significant amount of time, and you would need
access to the platforms.

Thank you. Win installation is relatively straightforward,
and I was toying with dropping the *nix support for the moment
(Mac and any others are not supported at all).

Your advice has convinced me to do just that.
I will proceed with an installer for Win only.
 

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

Forum statistics

Threads
473,755
Messages
2,569,536
Members
45,014
Latest member
BiancaFix3

Latest Threads

Top