gcc/gcj 3.4 - bug report

rezaei@promail.com rezaei@promail.com
Thu Jul 24 02:11:00 GMT 2003


Success! thanks for the help. details below.
> It's usually better to build to .o and then link as a separate step.
> The above is probably a bug -- feel free to put it in bugzilla.
> (Preferably with the full -v output...) Still, this will be low
> priority, I think.
>> Try:
>> gcj ... -fPIC -shared -o collections.so .../collections.jar
> [ repeat for each .jar ]
> gcj --main=... -o test.exe collections.so ...other .so files... -lswt
>Thanks for the tip. I was able to compile a jar to a static .a (gcj -c -o blah.a 
blah.jar). for the final compile, I did have to put all the jars on the classpath as 
well as the .o's for linking. (It didn't solve the problem, but does reduce my 
build time).
> Probably this is a static linking problem. I'm not sure, since I
> haven't tried your program. But make sure that the image loaders are
> in fact linked into your final executable. 
hmm... how do I do that? I can do an nm on a .o or .a file, but it doesn't work 
on .exe files.
> Search this list's
> archives for lots of talk about the problems of static linking, most
> likely including discussions about this exact problem involving SWT.
You hit the nail on the head here. This is the code swt uses to load images:
	static final String FORMAT_PACKAGE = 
"org.eclipse.swt.internal.image";
	static final String FORMAT_SUFFIX = "FileFormat"; 
	static final String[] FORMATS = {"WinBMP", "WinBMP", "GIF", 
"WinICO", "JPEG", "PNG"}; 
	for (int i = 1; i < FORMATS.length; i++) {
		if (FORMATS[i] != null) {
			try {
				Class clazz = 
Class.forName(FORMAT_PACKAGE + '.' + FORMATS[i] + 
FORMAT_SUFFIX);
				fileFormat = (FileFormat) 
clazz.newInstance();
				if (fileFormat.isFileFormat(stream)) {
					isSupported = true;
					break;
				}
			} catch (ClassNotFoundException e) {
				FORMATS[i] = null;
			} catch (Exception e) {
			}
		}
	}
	if (!isSupported) 
SWT.error(SWT.ERROR_UNSUPPORTED_FORMAT);
As you can see, it does some dynamic class loading via Class.forName. 
BTW, a lot of java code works like this. I guess ld was just optimizing too 
much and removing those classes because they were not invoked directly 
anywhere. The solution was a simple class (I had to put it in the the eclipse 
package, because those classes are package private).
For anyone who's interested:
package org.eclipse.swt.internal.image;
public class ForceClassLoader /* not part of eclipse. fixes gcj ld issue */
{
 static
 {
 GIFFileFormat x = new GIFFileFormat();
 PNGFileFormat y = new PNGFileFormat();
 JPEGFileFormat z = new JPEGFileFormat();
 WinBMPFileFormat q = new WinBMPFileFormat();
 WinICOFileFormat p = new WinICOFileFormat();
 }
}
Note to Mohan: you might want to put that class in your builds and add it as a 
.o for linking.
> >> Exception in thread "Thread-1" java.awt.AWTError: Cannot load AWT toolkit:
>> AWT isn't available yet. I'm surprised that an SWT application would
> try to use it.

Sorry about the confusing message. When I *removed* the SWT loaders and 
tried to do it via AWT, it failed as above. I know AWT is not done, which is 
one of the reasons I'm using SWT. I was kinda hoping the "invisible" parts 
(things like loading an image, but not displaying anything) were somewhat in 
place.
Thanks for help.
Moh


More information about the Java mailing list

AltStyle によって変換されたページ (->オリジナル) /