I was asked to resolve the run-time error which was thrown by a Java application (on a Windows server) while trying to send an email.
The application was written a while ago and is working on another Windows server.
The error thrown is: "Error 500: java.lang.NoSuchMethodError:
com/sun/mail/util/SocketFetcher.getSocket(Ljava/lang/String;ILjava/util/Properties;Ljava/lang/String;Z)Ljava/net/Socket; "
The whole environment was moved to a new server where that applications failed.
I determined that the application was using the JavaMail package.
I could not located the mail.jar file in the major Java directories (I only located one deep down in one of WebSphere directories).
I also could not recompile the java file that was using JavaMail because it could not find the package.
So I downloaded and installed the latest mail.jar file (JavaMail version 1.4.4) and included the path into the CLASSPATH.
By the way, the CLASSPATH variable was not configured on the server, so the path to JavaMail is now the only path in the CLASSPATH.
Anyway, nothing helped after I recompiled the application. I am still getting the same "NoSuchMethodError" error.
I tried to replace the new mail.jar file by the old one from the older server (where the app worked), then recompiled the app and ran again - same error.
Could you please suggest how to resolve this?
Thank you!
Java
Last Comment
for_yan
8/22/2022 - Mon
for_yan
Well, NoSuchMethod error in general almost always means some version incompatibility, so your general direction of seraching at least looks right
for_yan
Did you put mail.jar at the top of your classpath?
When I move my one mail.jar up to the top of the
classpath, however, it runs fine. This means in one of the many
libraries we have in our path, there must be a conflict. We're usin
for_yan
It looks like in the latest versions of mail.jar (like 1.4.4)
SocketFetcher.getSocket has the method with the arguments it expects
So maybe some older SocketFetcher class pappears in classpath
before mail.jar of 1.4.4 javaMail
So, really check if you have this mail.jar in the very beginning of your classpath
I have the only one directory in my CLASSPATH, and that is the one I created for the JavaMail.
That variable was not set on the server, although multiple Java applications on the server run just fine.
I read the post that you mentioned earlier, it does look somewhat similar, but I have nothing in the path to play with.
Also, as I mentioned earlier, I tried to replace the new mail.jar file by the old one from the older server (where the app worked), then recompiled the app and ran again - same error.
I also renamed the mail.jar file that I found deep in the WebSphere directories - did not help.
What else can be done?
Thank you.
for_yan
So you are running it in WebSphere?
So it does not matter if you have it on classpath or in the lib folders somewhere
Besides -when eyou made all these changes - were you restarting the server every time?
It matters how they were all aligned at the moment fo server startup
for_yan
In general if it is running on WebSphere you should not do anything with CLASSPATH - it should all be done through the lib forlders jar's
Yes, I am running in a WebSphere.
I'll try to code in and run your code to determine where it gets the class from.
Two questions: 1) for the System.out.println(), what log file does it print to? native-stdout.log?
I tried to use the System.out.println(), but could not find the output.
2) Could you please specify "it should all be done through the lib folders jar's"?
Thank you!
pavelmed
ASKER
Also, no, I have not restarted the server.
Is it the only way to force the changes take effect?
for_yan
In J2EE application there is main lib fordler for server which applies to all applications
server_home/lib
and then within each application there is folder
webapps/app_name/WEB-INF/lib
these should have jars
I think app specific jars should be coming first in the theoretical classpath which server maintains, but who knows
Is it the only way to force the changes take effect?
In my exeprince to be sure it is the only way.
I didn't work with Websphere though. Mostly with Tomcat
So add the code for printing the location -it will help
you should have logs folder in your home and there align
the log files by date
If it is the servlet which you are running - you can temporaily send the output to the web page
pavelmed
ASKER
I checked the libs in specific folder webapps/app_name/WEB-INF/lib but they obviously did not have the mail.jar there.
And I was looking for the mail.jar everywhere else but found it (only one) only in the directory \IBM\WebSphere\AppServer\deploytool\itp\plugins\com.ibm.websphere.v7_7.0.1.v20100710_0411\wasJars - which, I was told, was created by the WAS installation. And it does not look like a directory where it could run from...
for_yan
well I'd try to get the output of that code
I tried it in my simple application - and it printed for me right away
who knows may be thye can have SocketFetcher in some other jars, not just mail.jar ?
The only thing we know is that there is incompatibilty in method parameters
So I think you would want taht mail.jar from javaMail 1.4.4. comes before everything
Still it does not seem too simple to change and regulate
I'd rather anyway first try to print out from where we are getting this class
import javax.activation.DataHandler;
import javax.activation.FileDataSource;
import javax.mail.*; // should be from that package
import javax.mail.internet.*; // should be from that package
Ran the app, but could not find the printout in the log files that I thought would be used for that - native_stdout.log - that file simply was not updated. maybe it's not the right file but I am not sure which is the right one then.
The only file that got updated was SystemOut.log which simply captured that run-time error.
Maybe I need to write to another file...
for_yan
is this servlet?
may be you can send it to web page?
grab out from HtttpResponse
pavelmed
ASKER
It is a java file, not a servlet. it is called from the JSP page.
This error somehow is not captured by the try/catch block and is not sent up in a proper way.
I'll try to rerun the code to get it displayed, but still it would be interesting to know why the stdout files don't get updated.
if it
it is called from the JSP page
then you can print theis location on the JSP page
In fact you can put this code in any Servlet or jsp within in the same application
It will everywhere access the same SocketFetcher class - it even acn be in some other servlet/jsp in the same application not related to your activity with javamail - the location fo the jar will anyway be the same
pavelmed
ASKER
Yes, I will re-write the code to put your block into the very first JSP dispayed
pavelmed
ASKER
Still can't get it displayed...
But I have to take a break for a couple of hours. Will post the updates later.
Thanks.
Well, I displayed it.
the path was for mailapi.jar file located in one of Lawson directories.
Lawson is the product that the custom app is working with.
The class SocketFetcher can be found also in the mail.jar as well in the mailapi.jar.
Maybe they have different set of parameters.
I am a bit confused how to proceed, probably will play with recompiling and env. variables.
I have already recompiled my java file with the new path for the jar but it did not help so far.
Thanks.
for_yan
what means Lawson directories?
How come they appear in WebSphere classpath?
Is it in general lib folder or in the lib folder of the same application ?
Don't think any recompilation could help with that
pavelmed
ASKER
Lawson is a big ERP application that is installed on that server.
WebSphere is configured to work with it.
I don't know how come that path was picked up, but it was shown by your code, and it in fact also contains all packages that I thought should come from mail.jar.
Also, it looks like the mailapi.jar is a light version of the JavaMail
So I thought that if it is picked in runtime, so that I have to recompile my class with it as well.
I did it and it did not help.
for_yan
Is your JavaMail going to be used in the same web application as Lawson or it is in deifferent web application ?
This web application works with Lawson and is accessed from Lawson but does not belong to it.
I installed the JavaMail just because I was trying to resolve the error with the socket class, wanted to modify the java file which had the Transport.send() method to put some debug code it and found out that I could not compile it because it could not resolve (import) the packages javax.mail.*; and javax.mail.internet.*;
So I looked them up and found in the JavaMail, then I installed it and included into the classpath for compilation.
If there is a different jar file that contains it, I would not need the one that I installed.
The problem is that it still does not work. I will need to undo all my configuration changes and start over, but I am too tired to do it now.
another thing - copy mailapi.jar to winodws area rename copy to mailapi.zip
Extract the SocketFetcher.class
then open this binary file with Notepad or WordPad.
You'll see a lot of gibberish - but among it you can see the signature of the method getSocket
Compare if the signature is the same as the one you have in SocketFetcher.class in mail.jar
I'm guuessing these signatures will be different
pavelmed
ASKER
You gave me many good ideas - thank you. I will play with them tomorrow.
But I cannot move the mailapi.jar file to any other place as it apparently is a part of lawson installation that I should not modify.
My app is installed outside of Lawson in standard websphere place.
But there are many other such custom apps that also don't work on this server (the mail part) so that's a common issue.
So if this mailapi.jar is in the general lib folder fo the server and you cannot move it to local lib folderof lawson application then it is difficult to deal with this situation
One option is to see if you can deal with mail in the same way as Lawson does - so that you could live without JavaMail's mail.jar and rely only on Lawson's jars.
Another option is to read about MANIFEST.MF, which you can put in META_INF folder under your application and in general could indicate the order of jars in the classpath for your application, using classpath parameter of MANIFEST.MF
pavelmed
ASKER
I will analyze this further and provide mo details but I am done for today.
Thank you for your help today.
pavelmed
ASKER
I was able to finally resolve the issue. Your code to determine what jar file is used for a specific class really helped.
It was resolved by placing the right jar file on the top of the WebSphere CLASSPATH.
Setting the path to the applications' Class-Path (in MANIFEST.MF files) did not work. Only WebSphere CLASSPATH, and only after a WebSphere restart. I had to wait for the time when I can do the restart, and that delayed a problem resolution.
I did dissassenble the SocketFetcher classes from various jar files but I could not find differences that I could use to select a jar file. So I had to use a "try and test" method - many times.
There were several jar files that included classed used for java mail, but only two of them would could be used to avoid that problem: j2ee.jar or mail.jar.
The j2ee.jar file existed on the server but was not in a CLASSPATH.
It worked for that error when I placed it on the top of the CLASSPATH but I was not sure if placing that rich jar file on the top would not cause incompatibilitity problems with other classes and applications, so I ended up placing mail.jar on the top.
Thank you for your help.
Good. I'm glad you finally resolved it.
Indeed this piece of code, which detects from which jar comes particular class, is useful in such complex cases, especially with J2EE applications.