i get java.lang.ClassNotFoundException wher i run my application fromJWS


S

steven acer

Hi all
I have a Java application that i intent to use as a JWS app.
non whenever i start the application from JWS, i get
ClassNotFoundException eventhough the jar where the class resides is
downloaded by JWS but if i run normally using java.exe on the command
line it runs smoothly and i don't have the exception.
The exception seems to come from the following line

Class clazz = Class.forName(className, false,
ClassLoader.getSystemClassLoader());

is it because i am using ClassLoader.getSystemClassLoader?

i don't understand why it runs from the command line normally but not
from JWS, here's my jnlp file

<?xml version="1.0" encoding="utf-8"?>
<jnlp codebase="http://127.0.0.1:8080/awclient" href="AW.jnlp"
spec="1.0+">
<information>
<title>Sample</title>
<vendor>N/A</vendor>
<homepage href=""/>
<description kind="short">Sample</description>
<description kind="tooltip">Sample</description>
<icon href="images/AW_image_install.jpg" />
<icon kind="splash" href="images/AW_image_splash.jpg" />
</information>
<security>
<all-permissions/>
</security>
<resources>
<j2se href="http://java.sun.com/products/autodl/j2se" initial-heap-
size="127m" max-heap-size="255m" version="1.5+"/>
<jar href="lib/client.jar" main="true"/>
<jar href="lib/skin.jar" main="false"/>
<jar href="lib/kswing.jar" main="false"/>
<jar href="lib/sslca.jar" main="false"/>
<jar href="lib/admin.jar" main="false"/>
<jar href="lib/adminc.jar" main="false"/>
<jar href="lib/core.jar" main="false"/>
<jar href="lib/intrl.jar" main="false"/>
<jar href="lib/intrlc.jar" main="false"/>
<jar href="lib/server_stub.jar" main="false"/>
<jar href="lib/te.jar" main="false"/>
<jar href="lib/tec.jar" main="false"/>
<jar href="lib/ext/ktl.jar" main="false"/>
<jar href="lib/ext/ktlc.jar" main="false"/>
<jar href="lib/ext/rmisec.jar" main="false"/>
<jar href="lib/si18n.jar" main="false"/>
<jar href="lib/soutil.jar" main="false"/>
<jar href="lib/print.jar" main="false"/>
<jar href="lib/htec.jar" main="false"/>
<jar href="lib/hte.jar" main="false"/>
<jar href="lib/ext/x509-jndi.jar" main="false"/>
<jar href="lib/vectorgraphics.jar" main="false"/>
<jar href="lib/ext/freehep-graphicsio-gif.jar" main="false"/>
<jar href="lib/ext/freehep-graphicsio-ppm.jar" main="false"/>
<jar href="lib/ext/freehep-graphicsio.jar" main="false"/>
<jar href="lib/ext/freehep-graphicsio-pdf.jar" main="false"/>
<jar href="lib/ext/freehep-base.jar" main="false"/>
<jar href="lib/ext/freehep-graphics2d.jar" main="false"/>
<jar href="lib/ext/freehep-graphicsio-ps.jar" main="false"/>
</resources>
<application-desc main-class="so.kernel.client.DesktopMain">
<argument>http://127.0.0.1:8080/help</argument>
</application-desc>
</jnlp>

can you please help
 
Ad

Advertisements

A

Andrew Thompson

...
is it because i am using ClassLoader.getSystemClassLoader?

i don't understand why it runs from the command line normally but not
from JWS, here's my jnlp file

Quite possibly. Try using the context classloader.

ClassLoader cl = Thread.
currentThread().
getContextClassLoader();
....

You might also try checking the JNLP file/resources
with JaNeLA. <http://pscode.org/janela/>
 
A

Andrew Thompson


My reply to you is not an invitation to start
a private conversation in email. Or to put that
another, more explicit, way.

*Do not send me email(1).*

(1) Except under the explicit conditions mentioned
in my Google groups 'profile'.
 
S

steven acer

My reply to you is not an invitation to start
a private conversation in email.  Or to put that
another, more explicit, way.

*Do not send me email(1).*

(1) Except under the explicit conditions mentioned
in my Google groups 'profile'.

I am terribly sorry, i did not mean to. I must've clicked on reply to
author instead of just "Reply"
but i was so taken by the problem that i did not pay attention to what
happened. please excuse me.
anyway, i tried to use Thread.currentThread().getContextClassLoader()
and it managed to load the class. by inspecting it, i found that the
context class loader is nothing but the JNLPClassLoader.
it works at least but i still don't understand why it doesn't with the
application class loader because he is the one supposed
to be launching the application.
 
M

markspace

steven said:
but i still don't understand why it doesn't with the
application class loader because he is the one supposed
to be launching the application.


Your original post was cut off, I only saw Andrew's reply. However the
bit he quoted indicated you were doing this:
> is it because i am using ClassLoader.getSystemClassLoader?
>

That's the system class loader, not the class loader that loads your
application. They're different.

I would personally use getClass().getClassLoader(). Each class is
loaded by a class loader, and if you use the one that loaded *your*
classes then you'll get the right one.

The context class loader seems like the wrong idea to me, but if it
works, sure. I'd just be concerned that the context class loader was
set to some other class loader (than the one returned by
getClass().getClassLoader()) and it would fail for some reason. However
maybe applets guarantee that the context class loader will be set to the
correct loader to load the app's resources? I haven't seen that in any
docs, but it might be true. Maybe Andrew knows something I don't.
 
R

Roedy Green

ClassNotFoundException

see
http://mindprod.com/jgloss/runerrormessages.html#CLASSNOTFOUNDEXCEPTION

You have a staggering list of jars in your JNLP. I presume you forgot
one, or misspelled it. Check your classpath and ext directories for
all jars you had present at compile time and when you run as an app.

ClassNotFoundException implies the problem was with Class.forName or
with a class loader. It did not happen as a side effect of an ordinary
class load. If it were, you would gave gotten a NoClassDefFoundError.

I would expect your error message to contain the name of the offending
class which should give you a big clue to the problem.
--
Roedy Green Canadian Mind Products
http://mindprod.com

"For reason that have a lot to do with US Government bureaucracy, we settled on the one issue everyone could agree on, which was weapons of mass destruction."
~ Paul Wolfowitz 2003-06, explaining how the Bush administration sold the Iraq war to a gullible public.
 
Ad

Advertisements

A

Andrew Thompson

...
The context class loader seems like the wrong idea to me,

From the JavaDocs..
"... The context ClassLoader is provided by the
creator of the thread for use by code running in
this thread when loading classes and resources. ..."
...but if it works, sure.  

The context class loader (CCL) works more commonly
than using the default class loader. Try loading
an icon in main().

Little e.g., complete with build file and icon,
for less than 3Kb..
..I'd just be concerned that the context class loader was
set to some other class loader (than the one returned by
getClass().getClassLoader()) and it would fail for some reason.

It is more the other way around. Using the default
class loader will fail in any number of situations,
especially with applets, JWS apps. and server code.
.. However
maybe applets guarantee that the context class loader will be set to the
correct loader to load the app's resources?

Not just applets, but most situations.
..I haven't seen that in any docs, ..

It is very poorly documented by Sun. :-/

Except for that one quote from the JavaDocs,
I cannot find much else in support of the CCL.
Sun's example code is notorious for using the
simpler construct you mentioned. But then,
many of Sun's example codes try to get to the
point the quickest way they can, and are not
necessarily good examples of doing much beyond
what the code is focusing on.
..but it might be true.  Maybe Andrew knows something I don't.

I have run into this problem on a number of
occasions. The first and most irritating was
that I caould never manage to load a frame
icon, unless I (ended up) sub-classing (J)Frame.

Once called from inside the constructor, using
the default ..
this.getClass().getResource("the.gif");
... worked OK. But it does *not* work from the
main().

A variety of time, discussions and experiences
later, I tried again using the /CCL/ in main()
and finally, was able to manage the 'marvellous
technology' of finding an URL to a frame icon,
without sub-classing frame.

One discussion in relation to the CCL.
<http://forums.sun.com/thread.jspa?threadID=5355229>
...it also links back to another thread hereabouts.

And to he OP. No worries about the wrong button,
I figured it was something like that and you'd get
back to us here.

Glad you sorted it.
 
M

markspace

Andrew said:
A variety of time, discussions and experiences
later, I tried again using the /CCL/ in main()
and finally, was able to manage the 'marvellous
technology' of finding an URL to a frame icon,
without sub-classing frame.

You might want to take a look at this:

<http://www.javaworld.com/javaworld/javaqa/2003-06/01-qa-0606-load.html>

The important bit is on the second page, where it says that there is no
single right answer. It depends on how the system (and CCL) is configured.

CCLs are intended as a back-door for frameworks where the regular class
loader won't work. It's not an all singing, all dancing solution to
resource loading. In fact, I'm surprised it works in an applet, since
the default is for a CCL to be set to the system class loader, which we
saw in the OP's example that didn't work.

Here's a bit of code I whipped up that loads an image icon without using
a CCL, or sub-classing a JFrame. I'll post a complete Jar file in a bit.



package frameimage;

import java.awt.image.BufferedImage;
import java.io.IOException;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.imageio.ImageIO;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.SwingUtilities;


public class Main {
public static void main( String[] args ) throws IOException
{
SwingUtilities.invokeLater( new Runnable() {

public void run()
{
createAndShowGui();
}
} );
}

private static void createAndShowGui()
{
JFrame frame = new JFrame();

JLabel message = new JLabel( "Frame with icon." );
message.setFont( new java.awt.Font( "Tahoma", 0, 36 ) );
frame.add( message );
java.net.URL imgURL = Main.class.getResource(
"images/Favorites.png" );
BufferedImage img = null;
try {
img = ImageIO.read( imgURL );
}catch( IOException ex ) {
Logger.getLogger( Main.class.getName() ).log( Level.SEVERE,
null, ex );
}
frame.setIconImage( img );

frame.pack();
frame.setLocationRelativeTo( null );
frame.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );
frame.setVisible( true );
}

}
 
S

steven acer

From the JavaDocs..
"... The context ClassLoader is provided by the
creator of the thread for use by code running in
this thread when loading classes and resources. ..."


The context class loader (CCL) works more commonly
than using the default class loader.  Try loading
an icon in main().

Little e.g., complete with build file and icon,
for less than 3Kb..


It is more the other way around.  Using the default
class loader will fail in any number of situations,
especially with applets, JWS apps. and server code.


Not just applets, but most situations.


It is very poorly documented by Sun.  :-/

Except for that one quote from the JavaDocs,
I cannot find much else in support of the CCL.
Sun's example code is notorious for using the
simpler construct you mentioned.  But then,
many of Sun's example codes try to get to the
point the quickest way they can, and are not
necessarily good examples of doing much beyond
what the code is focusing on.


I have run into this problem on a number of
occasions.  The first and most irritating was
that I caould never manage to load a frame
icon, unless I (ended up) sub-classing (J)Frame.

Once called from inside the constructor, using
the default ..
this.getClass().getResource("the.gif");
.. worked OK.  But it does *not* work from the
main().

A variety of time, discussions and experiences
later, I tried again using the /CCL/ in main()
and finally, was able to manage the 'marvellous
technology' of finding an URL to a frame icon,
without sub-classing frame.

One discussion in relation to the CCL.
<http://forums.sun.com/thread.jspa?threadID=5355229>
..it also links back to another thread hereabouts.

And to he OP.  No worries about the wrong button,
I figured it was something like that and you'd get
back to us here.

Glad you sorted it.

i think i understand why i had this exception.
in my case, turned out that when using a jnlp file to laucnh the app.
Thread.currentThread().getContextClassLoader() and
the current class loader both evaluate to JNLPClassLoader while
getSystemClassLoader() evaluates to Laucnher$AppClassLoader.
When launching from the command line (using java directly), all of
these expressions evaluate to Laucnher$AppClassLoader.
so that means in my case , when using jnlp to launch, the Laucnher
$AppClassLoader cannot load the classes since they are not in the
classpath, but JNLClassLoader( whose parent is the Application class
loader) can(because that's the way JWS is implemented i think).
so that means when i used System.getSystemClassLoader() it was like
telling the class loader to locate a class that was only visible to
its child class loader and thuus it failed.
am i right? please correct me if not.
also, if i was not right, in what scenario could using the System or
Application class loader work? can it be triggered by some change in
the jnlp file? please advise

in my case, (just as in any JWS application i think) the classloade
 
A

Andrew Thompson


Yes, I had seen it.
The important bit is on the second page, where it says that there is no
single right answer. It depends on how the system (and CCL) is configured.

I thought the important bit was at the bottom of
the 3rd page, in the source to DefaultClassLoadStrategy,
where it effectively only returns the non-CCL if
the callerLoader is a child of the CCL.

I doubt, but am not sure, that that ever happens
in JREs, and would need to see test code before I
believed it.
CCLs are intended as a back-door for frameworks where the regular class
loader won't work. It's not an all singing, all dancing solution to
resource loading. In fact, I'm surprised it works in an applet, since
the default is for a CCL to be set to the system class loader, which we
saw in the OP's example that didn't work.

Huhh? What example? What applet?

The OP I am replying to in this thread, seems
to be dealing with a JWS deployed application.
Further, they posted the JNLP but I saw no 'code'
from them beyond mentioning the snippet I
suggested, in their second reply.

We don't both seem to be 'on the same page'
Here's a bit of code I whipped up that loads an image icon without using
a CCL, or sub-classing a JFrame. ....
         JFrame frame = new JFrame(); ....
         java.net.URL imgURL = Main.class.getResource(
"images/Favorites.png" );

Huhh. OK. In my example I was using the frame
instance to getClass(). When I changed it to
use the ClassName.class.getResource() it worked.

But then, I think that supports my point, more
than disagrees with it.

It 'always' works with the CCL (or at least
more often than calling SomeClass.class or
SomeInstance.getClass() to produce a class loader).
...At least barring that hypothetical code that
shows the non-CCL failing, while one of the others
works.
 
M

markspace

Andrew said:
Huhh. OK. In my example I was using the frame
instance to getClass(). When I changed it to
use the ClassName.class.getResource() it worked.


When I call getClass().getClassLoader() on my frame, I get "null". The
Java docs say that indicates the bootstrap class loader is used. Maybe
that was your issue?

ClassLoader cl = frame.getClass().getClassLoader();
System.err.println( cl );

Prints "null" when inserted into the example I posted earlier.


Don't forget these classes are being built on the EDT. That might
affect how the class loaders are set. I'm just guessing here. But it
should be obvious that the bootstrap class loader wouldn't be able to
load your individual resources.
 
Ad

Advertisements

M

markspace

markspace said:
Don't forget these classes are being built on the EDT. That might
affect how the class loaders are set. I'm just guessing here.


Or possible "JFrame" *IS* a system class that was loaded with the
bootstrap class loader? Geeze, kinda obvious after two minutes thought.
It take me a while but I often do manage to get there.
 
A

Andrew Thompson

Or possible "JFrame" *IS* a system class that was loaded with the
bootstrap class loader?

I think that is the most likely explanation. I had
never thought of the construct you used, and the
JFrame instance seemed the most logical candidate for
use from an object, since I had not instantiated any
custom (non J2SE) object by that stage in the code.

Maybe I should do some more experiments .. (15
seconds later).

OK yeah. When I instead do..

FrameIconFromMain fifm = new FrameIconFromMain();

imageUrl = fifm.getClass().getResource(imageName);


...in my original source, the URL *is* valid.

It was me, stupidly using the J2SE core class,
that was the problem.

I am not sure of my ultimate conclusions from this,
I suspect I will continue to push the CCL for JWS
and applets unless I see a test case that fails.
But it has certainly been worth pursuing this
thread, thanks for helping clarify what the real
problem with my original example, was.
 
Ad

Advertisements

S

steven acer

I think that is the most likely explanation.  I had
never thought of the construct you used, and the
JFrame instance seemed the most logical candidate for
use from an object, since I had not instantiated any
custom (non J2SE) object by that stage in the code.

Maybe I should do some more experiments .. (15
seconds later).

OK yeah.  When I instead do..

  FrameIconFromMain fifm = new FrameIconFromMain();

  imageUrl = fifm.getClass().getResource(imageName);

..in my original source, the URL *is* valid.

It was me, stupidly using the J2SE core class,
that was the problem.

I am not sure of my ultimate conclusions from this,
I suspect I will continue to push the CCL for JWS
and applets unless I see a test case that fails.
But it has certainly been worth pursuing this
thread, thanks for helping clarify what the real
problem with my original example, was.

do you have such fail scenarios in mind? in which possible case can it
fail?
Is the application class loader always different from the CCL for JWS?
and does
the CCL always evaluate to JNLPClassLoader?
what change could trigger JWS to work with the application class
loader?
thanks
 

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

Top