JackRabbit setup on WAS for one of our REST application - java

We are trying to setup JackRabbit Oak on one of our Linux machine with IBM WAS application server and facing some issues starting the sever on WAS.
The Apache JackRabbit is a content repository which is a hierarchical content store with support for structured and unstructured content, full text search, versioning, transactions, observation, and more. We are using it for storing digital assets in structured form (specifically, as a tree) as per our requirement.
We have a REST application and another application DAM (Digital Asset Management) which handles creation of repository, providing connection with the repo whenever requested (Singleton), creating nodes, etc. on the repository. In our local development setup we have exported this DAM as a JAR, say dam.jar and have put this in REST application’s class path. We have JackRabbit Oak’s JAR (oak-run-1.4.11.jar), which we have put in class path of DAM application.
While doing a similar setup on Linux machine on WAS application server, we are using the same dam.jar which is created by exporting the project as a JAR in eclipse on Windows machine. We put this in REST application’s class path on WAS by configuring this in the server on which REST app is deployed.
While debugging we found that application is able to access classes from dam.jar, but when DAM’s class tries to call JackRabbit’s classes it fails throwing java.lang.NoClassDefFoundError. We tried putting JackRabbit’s JAR (oak-run-1.4.11.jar) in the class path on WAS by configuring this for REST app’s server, but then server fails to start.
Attached is the log file: /opt/IBM/WebSphere/AppServer/profiles/AppSrv01/servers/RESTAPP/configuration/1489493294429.log
There is nothing much inside server logs from /opt/IBM/WebSphere/AppServer/profiles/AppSrv01/logs/RESTAPP (RESTAPP is the server name for our REST application), below is the snippet:
[3/14/17 17:38:04:872 IST] 00000001 ModelMgr I WSVR0801I: Initializing all server configuration models
[3/14/17 17:38:08:564 IST] 00000001 WorkSpaceMana A WKSP0500I: Workspace configuration consistency check is disabled.
[3/14/17 17:38:08:834 IST] 00000001 AdminTool A ADMU3200I: Server launched. Waiting for initialization status.
[3/14/17 17:38:18:241 IST] 00000001 AdminTool A ADMU3011E: Server launched but failed initialization. Server logs, startServer.log, and other log files under /opt/IBM/WebSphere/AppServer/profiles/AppSrv01/logs/RESTAPP should contain failure information.
We suspect dam.jar here, as this has been created from our eclipse workspace by exporting it as a JAR file and this might need some extra information to have this JackRabbit Oak libraries included in that.
We are putting classpath entries in Application servers > RESTAPP > Process definition > Java Virtual Machine of WAS.
Thanks

I would try creating a "Shared library" in Websphere and putting your JackRabbit dependency jars in there:
Environment -> Shared libraries -> New...
Set then name "Jackrabbit", and then in the Classpath box add the paths to your jars.
Then in your REST application (Applications -> Application Types -> WebSphere enterprise applications -> [your application name])
Click "Shared library references" under "References"
Select the application and click "Reference shared libraries"
Select the Jackrabbit shared library and click the right arrow to reference that shared library from the application.
Classloading in WebSphere is very complicated -- see chapter 22 of the WebSphere Application Server V8.5 Administration and Configuration Guide for the full description. Trying to add classpath entries at the JVM definition level definitely won't work.

To piggyback on Andrew's answer above, the real key is to make sure that both dam.jar and oak-run-1.4.11.jar are within the same class loader, and that they are NOT in a server-level class loader - putting custom code in the server JVM class path makes it visible to the server runtime and can actually override server classes (which is probably why your server init failed after doing that).
The very easiest answer, assuming this is a simple web application, is to put both jars in the WEB-INF directory of your WAR module. Both will be loaded by the web app class loader, and they'll be able to see each other. If there's some reason you don't want them in the application itself, then Andrew's shared library suggestion would have the same practical effect.

Related

Get error java.sql.SQLException: No suitable driver found for jdbc:sqlserver://localhost;databaseName=ABC;integratedSecurity=true on Production

I created a Web Application using Java, JSP,Tomcat via Eclipse.
When running the Application on my Windows development Env, it works fine. database connection is fine (sqljdbc42.jar in Lib via Eclipse) The test db is on my Window development PC
Link: http://localhost:8080/App/
To test the db connection on Production is working right, I have a Java file (not related to my project, but using same db driver and url. It's just for test DB connection on production), it connects to db which is located on production correctly.
However, after I upload my war file (from local development environment) to Tomcat WebApps folder, I got the error in title, the db on production is not connected successfully.
I use the following drivers and url for db connection
drivers=com.microsoft.sqlserver.jdbc.SQLServerDriver
url=jdbc:sqlserver://localhost;databaseName=ABC;integratedSecurity=true
In the above url string, I have tried localhost as above, also tried production IP address, Server name, localhost:1433, localhost\\MSSQLSERVER, all get the same error
I have below in ClassPath in production site:
C:\sqljdbc42.jar;C:\microsoft-mssqlserver.jar;C:\Program Files\Java\jdk1.8.0_201\bin;C:\Program Files\Java\jre1.8.0_201\bin;.
Thank you in advance.
You should check the classloader paths for tomcat server. Regarding the docs, your server will hope finding sqlserver driver jar (sqljdbc42.jar) in the following places:
Bootstrap classes of your JVM ($JAVA_HOME/jre/lib/ext)
/WEB-INF/classes of your web application
/WEB-INF/lib/*.jar of your web application
System class loader classes (described through CLASSPATH environment variable)
Common class loader classes ($CATALINA_BASE/lib and $CATALINA_HOME/lib)
So, best options you can try are:
copying the jar to $JAVA_HOME/jre/lib/ext (#1)
or configuring your build so that, the jar is copied in /WEB-INF/lib/ (#3)
Number#2 is suitable for java classes; does not fit your case.
Number#4 and #5 are more likely for the use of tomcat's own structure, but still it is perfectly legal if you want to put the jar in.
Further Edit: For some reason, there are cases Tomcat may prevent sqlserver driver for the sake of preventing memory leaks. So, if you're sure the jar is on the classpath by applying the solutions mentioned in beforehand this post; you may also try to check with adding the following to server/.xml to disable that leak check:
<Listener className="org.apache.catalina.core.JreMemoryLeakPreventionListener" driverManagerProtection="false" />

JDBC driver not found (servlet, DAO, mariaDB) [duplicate]

I developer a web application using Java. When I deploy it to my application server (Jetty, Tomcat, JBoss, GlassFish, etc.) throws an error. I can see this error message in the stacktrace:
java.lang.ClassNotFoundException
Or
java.lang.NoClassDefFoundError
What does this mean and how can I fix it?
What does this mean?
First, let's see the meaning of java.lang.ClassNotFoundException:
Thrown when an application tries to load in a class through its string name using:
The forName method in class Class.
The findSystemClass method in class ClassLoader.
The loadClass method in class ClassLoader.
but no definition for the class with the specified name could be found.
Usually, this happens when trying to open a connection manually in this form:
String jdbcDriver = "...'; //name of your driver
Class.forName(jdbcDriver);
Or when you refer to a class that belongs to an external library and strangely this class cannot be loaded when the application server tries to deploy the application.
Let's see the meaning of java.lang.NoClassDefFoundError (emphasis mine):
Thrown if the Java Virtual Machine or a ClassLoader instance tries to load in the definition of a class (as part of a normal method call or as part of creating a new instance using the new expression) and no definition of the class could be found.
The searched-for class definition existed when the currently executing class was compiled, but the definition can no longer be found.
The last part says it all: the class existed at compile time i.e. when I compiled the application through my IDE, but it is not available at runtime i.e. when the application is deployed.
how can I fix it?
In Java web applications, all third party libraries used by your application must go in WEB-INF/lib folder. Make sure that all the necessary libraries (jars) are placed there. You can check this easily:
- <webapp folder>
- WEB-INF
- lib
+ jar1
+ jar2
+ ...
- META-INF
- <rest of your folders>
This problem usually arises for JDBC connectivity jars (MySQL, Derby, MSSQL, Oracle, etc.) or web MVC frameworks libraries like JSF or Spring MVC.
Take into account that some third party libraries rely on other third party libraries, so you have to add all of them in WEB-INF/lib in order to make the application work. A good example of this is RichFaces 4 libraries, where you have to download and add the external libraries manually.
Note for Maven users: you should not experience these problems unless you have set the libraries as provided, test or system. If set to provided, you're responsible to add the libraries somewhere in the classpath. You can find more info about the dependency scopes here: Introduction to the Dependency Mechanism
In case the library must be shared among several applications that will be deployed on your application server e.g. MySQL connector for two applications, there's another alternative. Instead of deploying two war files each with their own MySQL connector library, place this library in the common library folder of the server application, this will enable the library to be in the classpath of all the deployed applications.
This folder vary from application server.
Tomcat 7/8: <tomcat_home>/lib
JBoss 7/Wildfly: <jboss_home>/standalone/lib
The class must exist under WEB-INF/classes or be inside a .jar file under WEB-INF/lib. Make sure it does.
Same problem happen with me.
Might be possible one of your libraries are using some classes internal which is not available
in your lib or maven dependency pom.xml.
Thats means you have analyze your error logs and identify these classes and then import all dependencies in maven or lib folder.
I have fixed this error by the same way.
because some of my libraries are using activation.jar and json.jar internally.

Problem creating an Embedded Jetty Endpoint in a NetBeans Platform Application using System.setProperty

I created a Netbeans Platform Application using Netbeans 7.0.1 and the JDK 1.7.
I implemented my own Web Application on a normal module using Embedded Jetty 7.4.5 (consisting of a Web Service and a couple of servlets), and I created a Library Wrapper Module including all the Jetty jar files and the "jetty-j2sehttpspi-7.4.5.v20110725.jar" that I needed to be able to publish the Web Service's Endpoint. The Web module has a dependency on the Jetty module.
The code I'm using is this:
System.setProperty("com.sun.net.httpserver.HttpServerProvider",
"org.mortbay.jetty.j2sehttpspi.JettyHttpServerProvider");
server = new Server();
JettyHttpServerProvider.setServer(server);
//We read the config file
String[] configFiles = {"etc/jetty.xml"};
for(String configFile : configFiles) {
XmlConfiguration configuration =
new XmlConfiguration(new File(configFile).toURI().toURL());
configuration.configure(server);
}
// Web Services
QueryWeb qWS = new QueryWeb();
Endpoint.publish("http://0.0.0.0:" +
(server.getConnectors()[0].getPort()) + "/ws", qWS);
// Servlets
HandlerCollection hc = (HandlerCollection)server.getHandler();
ServletContextHandler sch =
new ServletContextHandler(ServletContextHandler.SESSIONS);
sch.setContextPath("/web");
sch.addServlet(stream.class, "/stream");
// We add the servlet handler to the server's context handler collection
// because it's the one used by the Web Service Endpoint
ContextHandlerCollection chc = (ContextHandlerCollection)hc.getHandlers()[0];
chc.addHandler(sch);
server.start();
When I try and run the application, I get the following error after the "Endpoint.publish" call:
Exiting C:\Program Files (x86)\NetBeans 7.0\harness\run.xml.
Exiting C:\Program Files (x86)\NetBeans 7.0\harness\run.xml.
C:\Program Files (x86)\NetBeans 7.0\harness\suite.xml:500:
The following error occurred while executing this line:
C:\Program Files (x86)\NetBeans 7.0\harness\run.xml:225:
The following error occurred while executing this line:
C:\Program Files (x86)\NetBeans 7.0\harness\run.xml:193:
The application is already running within the test user directory.
You must shut it down before trying to run it again.
As far as I understand, this is happening because the system can't find the "org.mortbay.jetty.j2sehttpspi.JettyHttpServerProvider" class. Therefore it defaults back to the web server included in the JDK, which causes a conflict since we get both web Servers (Jetty and the JDK's) trying to run on the same port (in this case it's 8081).
The only way I managed to fix this problem was by copying all the Jetty jar files into the JRE's "lib/ext" folder (copying only the "jetty-j2sehttpspi-7.4.5.v20110725.jar" results in no errors, but the server won't start). In this way the system can find the class it needs and all it's dependencies.
I suppose that what's going on is that even if NetBeans uses it's own classpath loader, the System.setProperty method is ignoring this and trying to access the standard classpath, and since a NetBeans Platform Application doesn't actually let you change the classpath directly (that would beat the whole purpose of having modules administered by the NetBeans platform), I don't really know how to make it use the library included in the wrapper module.
I can keep developing the application with the temporary solution I found, but honestly, copying stuff into the JRE folders is not an acceptable solution and will eventually result in distribution and installation problems in client machines (already tried it in a Mac OS machine and I didn't even know where the JRE kept it's libraries to try and do the same dirty trick).
Therefore I want to ask you guys if there is any solution to this particular problem or if anyone has a better explanation of what's going on and how I might fix it without having to recreate the whole architecture of my project (which actually works OK except for this little inconvenient).
Thanks in advance!
Write your question to the mailing list, dev#platform.netbeans.org, and you're more likely to get an answer.

CXF on WebSphere 6.1 Class Loading Problem

I have a project with the following configuration:
WebSphere Application Server 6.1.0.19
wsdl4j-1.6.2.jar at the $WAS_ROOT/java/jre/lib/ext directory, (to overwrite wsdl4j-1.6.1 included in WAS 6.1).
cxf-2.4.0.jar (and others dependencies) at the $WAS_ROOT/lib/ext directory.
An EAR 'X' with a Web Module 'Y'.
The Web Module 'Y' has a JAR Module 'Z' (at the WEB-INF/lib directory).
'Z' has a set of classes that implement a SOAP Web Service generated using CXF's wsdl2java.
'Y' has a business class (at the WEB-INF/classes directory) that calls the SOAP Web Service Client at 'Z'.
This configuration works well at my development enviroment (Rational Application Developer with a WebSphere AS 6.1 runtime). But at the QA enviroment, I had the following exception, (please pay attention at bolds in the stack trace):
org.apache.cxf.bus.extension.ExtensionException
at org.apache.cxf.bus.extension.Extension.loadInterface(Extension.java:134)
at org.apache.cxf.bus.extension.ExtensionManagerImpl.loadAndRegister(ExtensionManagerImpl.java:160)
at org.apache.cxf.bus.extension.ExtensionManagerImpl.getBeansOfType(ExtensionManagerImpl.java:256)
at org.apache.cxf.bus.CXFBusImpl.getExtension(CXFBusImpl.java:99)
at org.apache.cxf.endpoint.ClientImpl.notifyLifecycleManager(ClientImpl.java:186)
at org.apache.cxf.endpoint.ClientImpl.(ClientImpl.java:117)
at org.apache.cxf.frontend.ClientFactoryBean.createClient(ClientFactoryBean.java:104)
at org.apache.cxf.frontend.ClientFactoryBean.create(ClientFactoryBean.java:92)
at org.apache.cxf.frontend.ClientProxyFactoryBean.create(ClientProxyFactoryBean.java:152)
at org.apache.cxf.jaxws.JaxWsProxyFactoryBean.create(JaxWsProxyFactoryBean.java:142)
at org.apache.cxf.jaxws.ServiceImpl.createPort(ServiceImpl.java:464)
at org.apache.cxf.jaxws.ServiceImpl.getPort(ServiceImpl.java:331)
at org.apache.cxf.jaxws.ServiceImpl.getPort(ServiceImpl.java:318)
at javax.xml.ws.Service.getPort(Service.java:46)
at web.service.client.implementation.at.z.module.method(Unknown Source)
at business.class.at.y.web.module.method(AvisoCobroDAO.java:86)
... 32 more
Caused by: java.lang.ClassNotFoundException: org.apache.cxf.endpoint.ClientLifeCycleManager
at com.ibm.ws.classloader.CompoundClassLoader.findClass(CompoundClassLoader.java:472)
at com.ibm.ws.classloader.CompoundClassLoader.loadClass(CompoundClassLoader.java:373)
at java.lang.ClassLoader.loadClass(ClassLoader.java:561)
at org.apache.cxf.bus.extension.Extension.loadInterface(Extension.java:132)
... 51 more
Seems like the CompoundClassLoader (which works at application level) is trying to load a CXF's class which exists at the server runtime level.
I hope somebody help me with this issue. I'll be very very grateful.
Placing Jars in the WAS_HOME/lib/ext should be your last resort.
Always try the PARENT_LAST classloader mode and have your classes/jars picked up first.
This would avoid a number of problems for you.
The App Server start up would use this directory extensively and if there are clashes it might not even start up.
THe best way to troubleshoot is to turn on classloading and look at the native_stdout/stderr file and see who is loading the class(es) that is in question.
Bkail,
Did you mean to say things differently? This path is high up the class loader chain so it would be checked earlier (with the default PARENT_FIRST) class loading policy.
This would be in the second rung (after the BOOT CLassloader of the JDK) and it's extensions.
HTH
Manglu

Ejb lookup failing on WAS7.0 with NamingException

I have an application developed on RAD using WAS 6.0. I migrated the code to WID 7.0. After making some changes in the EJB modules(Had to remove the bnd.xmi file from each ejb module to deploy the application on Application Server)the application is running fine, but the EJB modules give the following error:
NamingException has Occured While Getting Local Home
javax.naming.NameNotFoundException:nullName ejb/com/igcc not found in context "local:".
I am not able to figure out what changes do it need to make to run the application on WID.
Any help is appreciated.
Thanks,
Ayush
Well, the "bnd.xmi" files you deleted are the WebSphere-specific deployment descriptors, containing binding information. One of the things that are mentioned there is the name under which to bind each individual EJB home.
You cannot possibly run an EJB module without this binding information existing somewhere.
If you delete these files (which are generated by RAD), you have to assign new binding information from within the administration console, or via your wsadmin-based deployment scripts.
In short... lets start by recovering those files that you erased. :-)

Categories