Class found in a Java application but not in JSF? - java

I'm trying to use bacnet4j with JSF.
I build an application in .java which turn on/off a lamp, but if I try to call the same method from a JSF page (which communicates with my manage bean) , gives me :
type Exception report
message
descriptionThe server encountered an internal error () that prevented it from fulfilling this request.
exception
javax.servlet.ServletException: com/serotonin/bacnet4j/type/Encodable
root cause
java.lang.NoClassDefFoundError: com/serotonin/bacnet4j/type/Encodable
root cause
java.lang.ClassNotFoundException: com.serotonin.bacnet4j.type.Encodable
But I'm pretty sure that the class is there, because if not my java application don't work, right ?
Any idea why this is happening ?

The JAR file containing this class should go in webapp's /WEB-INF/lib folder.
A plain Java Application does not use the same classpath as a Java Web Application. For a plain Java Application the classpath is usually specified by -cp or -classpath argument in java command, or if unspecified, by %CLASSPATH% environment variable, or if being a JAR, by Class-Path entry in JAR's /META-INF/MANIFEST.MF. For a Java Web Application the classpath covers by default the webapp's /WEB-INF/lib and /WEB-INF/classes folder and server's /lib (and more) folders and any custom folders which you can specify in server-specific configuration, such as shared.loader property of /conf/catalina.properties in case of Tomcat.

NoClassDefFound means that the class was available at compilation but not at runtime. You need to add the jar-file with the appropriate class to your war (or add it to the application server classpath)

Related

Java class not loading from javaclassloader service in IIB

I have an application build in IIB v10 where i am referencing a java routine from esql. I have created the java class as an independent resource, then exported it as a JAR file and placed it in a folder under C://lib. There was an existing configuration service for java class loader which also pick yet another jar file from C://lib. I then amended the existing configuration service for Java Class loader with the new jar name and its path. Also, did a restart of the broker and inspected via mqsireportbroker command and webconsole to confirm the new jar has been updated in the configuration service. Now when i deploy the BAR file to the server, I am getting the below error.
BIP3202E: (com.xxxx.soa.xx.xxx.createMD5Hash, 1.12) : An error occurred when trying to resolve the Java class or method 'com.xxxx.gen.createMD5.createMD5Hash' which is referred to by the routine 'createMD5Hash'.
Further messages are generated that explain the error in more detail.
Correct the syntax of your Java expression in node 'com.xxxx.soa.xx.xxx.createMD5Hash', around line and column '1.12', then redeploy the message flow.
BIP2943E: The Java Method 'com.xxxx.gen.createMD5.createMD5Hash' could not be found as its containing class could not be found in the deployed bar file or in the 'workpath/shared-classes/' directory.
The specified Java Method 'com.xxxx.gen.createMD5.createMD5Hash' belongs to a class that could not be found in the deployed bar file or the 'workpath/shared-classes/' directory. Ensure that the fully qualified name of the method is correct and that its containing class or jar file is in the deployed bar file or in the 'workpath/shared-classes/' directory.
Examine and correct the SQL program.
When I put the jar file under workpath/shared-classes directorey, its working. But I want the jar file to take from the shared class librarry which is C://lib. What am I missing in this case?
All you need to do it to put your jar in the shared-classes folder.
You can find all the information about it in the IBM documentation really easily, but here is an example on Unix :
/var/mqsi/config/MY_BROKER/shared-classes
You can either put the .jar there, and it will be loaded for each execution group (also called integration servers).
If you know you only need this for a specific execution group, then you can copy it there :
/var/mqsi/config/MY_BROKER/MY_EG/shared-classes
And I would highly recommand you to use the second option, otherwise you might have performance issues if you do this with a lot of libraries
There are only a few paths where the .jar files are loaded from.
See for more information: https://www.ibm.com/support/knowledgecenter/en/SSMKHH_9.0.0/com.ibm.etools.mft.doc/bk58210_.htm
JAR files are loaded in the following precedence order:
JAR files placed in the integration server shared-classes directory allow only a single defined integration server to access them. Files placed in here are loaded first.
JAR files placed in the broker shared-classes directory allow only a single defined broker to access them. Files placed in here are loaded after any files placed in the integration server shared-classes directory.
JAR files placed in the top level shared-classes directory are made available to all brokers and all integration servers. Files placed in here are loaded after any files placed in the broker shared-classes directory.
I found it on windows here C:\ProgramData\IBM\MQSI\config*\shared-classes
using this command mqsireportbroker <my_broker_name>

Issues launching a JAR file from an executable JAR using Manifest file ClassNotFoundException

I have a project which uses both RMI and JDBC and I need to make it an executable JAR. Now my instructions are to make one JAR file with all my source code which ive included all my .java files. My second JAR needs to be the RMI server .class files and then the third JAR is to have all my RMI client .class files.
Now the first JAR and the third JAR I can make no problem but the issue lies with that in my second I require the use of JDBC so I need to include the mysql-connector-java-5.1.31-bin.jar file in it.
My folder consists of the following layout, only default packages are used and everything is in the root directory.
1st JAR - Source Code Jar File Contains...
A2Interface.java
A2InterfaceImpl.java
A2RmiClient.java
A2RmiServer.java
InvalidLocationException.java
DuplicatedAddressException.java
I used this command to jar it
jar cvf source.jar *.java
2nd JAR - Contains the classes related to RMI server, I also need the mysql JDBC jar file included along with it
And I used this command to JAR it
jar cvfm RMIserver.jar server.txt A2RmiServer.class A2Interface.class
A2InterfaceImpl.class *Exception.class mysql-connector-java-5.1.31-bin.jar
My server.txt Manifest file contains the following
Main-Class: A2RmiServer
Class-Path: mysql-connector-java-5.1.31-bin.jar
-empty line as per the docs-
3rd JAR - Contains the classes related to the RMI client
jar cvfm RMIclient.jar client.txt A2RmiClient.class
A2RmiClient$EventHandler.class
Any my client.txt manifest file contains
Main-Class: A2RmiClient
-empty line as per the docs-
Now everything jars perfect fine and I extract my first JAR file containing all my .java files with no errors. I then attempt to run my RMIserver.jar file with the following command...
First I start the registry..
start rmiregistry 5566
Then I run the executable jar file..
java -cp mysql-connector-java-5.1.31-bin.jar -jar RMIserver.jar
AND here is where I get an Exception of the following
Trouble: java.rmi.ServerException: RemoteException occurred in server thread; nested exception is:
java.rmi.UnmarshalException: error unmarshalling arguments; nested exception is:
java.lang.ClassNotFoundException: A2Interface
I cannot determine why this is doing this at all. If I dont use any jar files my code runs perfectly fine with ZERO exceptions but as soon as I try this I always get exceptions. I have searched many places and some people say that you cant include the mysql JAR file (or any JAR file) like this and even according to the Java doc here http://docs.oracle.com/javase/tutorial/deployment/jar/downman.html
They also mention that its designed for use only for JAR's over the network and not in the same directory, however my professor believes this can be done. I have been trying to figure this out for hours and have come to a wall. I don't know how I can make it work with using the necessary mysql JAR file.
OH and please dont mention using any other tools to create a JAR package as I cannot do that for my assignment or even eclipse. I can only do this from using strictly command line tools.
The ClassNotFoundException is happening in the rmiregistry, and it's being returned to your server application wrapped in a ServerException.
In normal usage, the RMI server annotates the classes with their codebase URL so that other Java processes can load the unknown classes. However, the jar file isn't a usable URL for this purpose (I'm not totally sure, but I think it's because it's generally insecure to load from file: URLs received from the network).
The reason it works when you're not using jar files is because the rmiregistry is able to find the missing classes in its own classpath (because you're running it in the same directory that contains A2Interface.class).
You have two choices:
Serve the class files (or a jar containing them) from an http server running on the RMI server's host, and use the java flag -Djava.rmi.server.codebase=http:... to point to the directory/jar where the classes can be found; or
Insert the common classes in every classpath: server, client, and rmiregistry.
For more detail, see http://docs.oracle.com/javase/7/docs/technotes/guides/rmi/codebase.html.
And here is where I get an Exception of the following
The Registry doesn't have that class available on its CLASSPATH. There are three solutions, in increasing order of difficulty:
Run the Registry inside the server JVM, via LocateRegistry.createRegistry(). When you do this, you must store the result of that call in a static variable, to prevent it being garbage-collected. That also makes it possible to unexport the Registry when you want the JVM to exit.
Run the rmiregistry with an appopriate CLASSPATH. There are several ways to do that, including -J-classpath and setting a CLASSPATH environment variable.
Use the RMI codebase feature.
Now my instructions are to make one JAR file with all my source code which ive included all my .java files. My second JAR needs to be the RMI server .class files and then the third JAR is to have all my RMI client .class files.
Your instructions are incorrect. You need to make four JAR files:
Source code (why?)
.class files that are common to both client and server
.class files that are only used on the server
.class files that are only used on the client.
(3) and (4) need manifests, both to name the Main-Class and to name (2) on the Class-path.
The server deployment needs (2) and (3). The client deployment needs (2) and (4).

Externalising resource Adapter giving : java.lang.ClassCastException someclass incompatible with someclass

I am working on externalizing Resource adapter rars.
Earlier, the rar were packaged inside the /lib of war and everything worked good. Now to make the war light and also generic, I want to externalize resource adapter.
What I have done yet
Removed rars from war
installed rar externally through WAS7.0 Admin console
configured J2C connection factories for each RAR
I did a clean ,restart and I got some ClassNotFoundErrors.
Why were these errors there :
Basically the rars use some jars that are present inside /lib. so earlier there was no problem but now when I externalized it, I started getting CNFE`s.
How I resolved:
When we install a rar through WAS admin console , there is an option to provide classpath. I provided the jars that were causing issues on classpath there. And I could deploy and start my application
The problem:
When I login to my application. There is a line of code in one of the jars (that was causing issues and was added to classpath of resource adapter , note that currently this is present inside war and also on classpath of resource adapter), that is doing a type cast.
Now on this statement
I get an exception
java.lang.ClassCastException: com.csc.fs.ra.SimpleMappedRecord incompatible with com.csc.fs.ra.SimpleMappedRecord
I dug up and found that a possible cause is multiple version of same jars. which is a case in my case.
i have a version of jar inside war library and also on classpath of resource adapter.
I am kind of out of ideas here. what to do to resolve this kind of situation. please help
Regards
The RAR and the WAR got their own ClassLoader, even if you use the same version of the jar, each one of them loads the class separately and you get ClassCastException.
Before when it was embedded it worked because the RAR was using the same ClassLoader.
If the RAR are now separate I think you will have to put the jars in a shared library so it will be loaded by a single ClassLoader.
You can check the classloaders. It will show you all jars that are loaded.

Configuration to get class picked from classes folder instead of lib folder in Tomcat?

I have same class file under classes folder and also in jar file inside lib folder.But the class is getting picked up from jar file. As per my understanding when this is the case , class under classes folder gets preference over jar file. At least this is the behaviour i have seen in glassfish. But this is not the behaviour in tomcat. Do i need to do any configuration in case of tomcat to give the preference to classes under classes folder? I am using tomcat 6.0.26.
The spec (2.4) says:
The Web application class loader must load classes from the
WEB-INF/classes directory first, and then from library JARs in the
WEB-INF/lib directory.
So if Tomcat loads from the jar first, it's not compliant with the spec.
Its documentation says:
Therefore, from the perspective of a web application, class or
resource loading looks in the following repositories, in this order:
Bootstrap classes of your JVM
System class loader classes (described above)
/WEB-INF/classes of your web application
/WEB-INF/lib/*.jar of your web application
Common class loader classes (described above)
So I'm surprised you're seeing such a behavior. If you're absolutely sure that the class is not in some jar in Tomcat's own classpath, file a bug report. Before doing that, also make sure to clear Tomcat's work directory, or even to start from a fresh install of Tomcat.
The workaround is of course to repackage the jar file to include your modified class instead of relying on the classloading order.

java.lang.ClassNotFoundException: javax.servlet.Servlet

I receive this exception when I try to run a jar file
java.lang.ClassNotFoundException: javax.servlet.Servlet
The file servlet-api-2.5-6.1.14.jar lives in the same dir as the jar im trying to run.
servlet-api-2.5-6.1.14.jar contains the class javax.servlet.Servlet
Any ideas ?
Thanks
You need to include its path in the Class-Path entry of the MANIFEST.MF file of the JAR you're running. Assuming that both JAR's are in the same folder:
Class-Path: servlet-api-2.5.6.1.14.jar
I only wonder how it's useful to have the Servlet API as a dependeny of a plain Java application.
you would need the servlet apis and any dependent libraries in a web application.
To run a web applicaton, you will "deploy" it on a servlet container or application server like tomcat, jboss, jetty so on. All the libs to run your web app., which you would need in this way are included in your container/container classpaths. You don't have to define them explicitly in your application configs.
If you are working on exclusively an application like an application server, and want to develop a server on yourself, you need to add the servlet library into your app.'s classpath.

Categories