I`m developing client that uses library Overthere 2.3.1. With local machine client works perfectly. But when I try to call same code included to EJB 3.0, I've got exception that not all required classes have been loaded.
I`ve looked over the source and found that the class contains Protocol annotation scanner (https://github.com/hierynomus/scannit) with hardcoded class name:
Scannit scannit = new Scannit(Configuration.config()
.scan("com.xebialabs")
.with(new AbstractScanner[] { new TypeAnnotationScanner() }));
The command
Thread.currentThread().getContextClassLoader().getResources("com/xebialabs")
returns null.
Looks like EJB runs in a separate classloader which does not have access to all the jars.
The EJB is packed to EAR with following structure:
EAR
--META-INF
----sda-dd.xml
----SAP_MANIFEST.MF
----MANIFEST.MF
----application-j2ee-engine.xml
--ejb.jar
--extlibs.jars
The MANIFEST.MF file don`t contain any referenses to external libs in CLASS-PATH. The EAR project is deployed to Application server successfully.
The EJB.jar also contains META-INF/MANIFEST.MF with value "Class-Path: ." by default.
I`ve already tried playing around with CLASS-PATH in manifest files, but have no luck.
Could anyone help me, how to build project with all external libs to be loaded while EJB runs? What have I missed with resources and classloaders?
Related
I have many CXF WS to deploy (13 wars) and sometimes one of them give me this error:
java.lang.NoClassDefFoundError: org/apache/cxf/transport/servlet/BaseUrlHelper
org.apache.cxf.transport.servlet.ServletController.getBaseURL(ServletController.java:74)
org.apache.cxf.transport.servlet.ServletController.updateDestination(ServletController.java:83)
org.apache.cxf.transport.servlet.ServletController.invoke(ServletController.java:196)
org.apache.cxf.transport.servlet.ServletController.invoke(ServletController.java:149)
org.apache.cxf.transport.servlet.CXFNonSpringServlet.invoke(CXFNonSpringServlet.java:171)
org.apache.cxf.transport.servlet.AbstractHTTPServlet.handleRequest(AbstractHTTPServlet.java:290)
org.apache.cxf.transport.servlet.AbstractHTTPServlet.doPost(AbstractHTTPServlet.java:209)
javax.servlet.http.HttpServlet.service(HttpServlet.java:646)
org.apache.cxf.transport.servlet.AbstractHTTPServlet.service(AbstractHTTPServlet.java:265)
org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52
The jar containing this class is in every lib application: cxf-rt-transports-http-3.0.2.jar.
When I reload the one who's not working by the tomcat manager, I don't have the problem anymore and it reappears (on another war randomly) when I restart the server. The missing class is always the same.
I use Cxf version 3.0.2.
It appears it was a problem with the number of file opened by process. The tomcat's classloader has opened too many files because each application/war had numerous libraries in his repertory WEB-INF/lib.
When the ClassLoader can't open a java class file because of this limit, it doesn't throw any Exception: it just doesn't load the class... So when I called my application, the first class which was called and not loaded was BaseUrlHelper...
I've put some libraries in the tomcat/lib (and I have deleted them from the repertory WEB-INF/lib) and the applications have worked fine.
If you have admin access in your unix system, i saw there is also a thing with the command ulimit ..
You can also put you application in more tomcats.
My project is in Java EE. I got two modules war and ejb. When I remove stripes jar from libraries of ejb module and include it to war module Localizable error works fine.
But when I did that war module cant connect to ejb session bean(I'm using stripes-injection-enricher).
Project sees the StripesResources.properties file because I can get string like that in jsp file:
<fmt:message key="layout.otherLanguage"/>
in resources I got:
layout.otherLanguage=French
it works. But LocalizableError or SimpleError not working in actionbean file:
errors.add("username",
new LocalizableError("primaryEmailNotFound"));
In resources file:
project.action.LoginActionBean.primaryEmailNotFound=wrong login
What can I do?
The problem was solved when I delete stripes.jar from ejb module and deploy .war file instead of .ear file.
I am in the process of creating a REST web service in Java Spring. I've successfully loaded STS and the example detailed at :
"This guide walks you through the process of creating a "hello world" RESTful web service with Spring."
http://spring.io/guides/gs/rest-service/
However that tutorial only goes so far.. I want to create a WAR file instead of a self running jar containing a servlet, and deploy that WAR file. I then found this tutorial, and attempted to just modify the first tutorials build.gradle file.
"Converting a Spring Boot JAR Application to a WAR"
http://spring.io/guides/gs/convert-jar-to-war/
It seemed to build just fine into a .war file.. the service is running in my TOMCAT instance's manager.. but I get 404's once I attempt to use the service.
URL 404'd
http://localhost:8080/gs-rest-service-0.1.0/dbgreeting?name=MyName
Do I need to modify the mapping?
DataBaseController.java
#RequestMapping("/dbgreeting")
public #ResponseBody DataBaseGreeter dbgreeting(
#RequestParam(value="name", required=false, defaultValue="World") String name) {
return new DataBaseGreeter(counter.incrementAndGet(),String.format(template, name));
}
Now I have the .war file created according to a blending of things.. and worried I perhaps missed something.
I've since discovered XAMPP on OSX doesn't contain a webapp/ folder, which has forced me to load Bitnami's Tomcat stack instead. Do people generally switch between XAMPP and other stacks based on this? or did I miss something to get webapp folder created in XAMPP?
A WAR is just a JAR with special properites. It needs to have a WEB-INF, under which you need a web.xml to describe your deployment, any app server dependentXML configuration files, and usually a lib, classes, and other odds and ends.
The easiest way would be to use Maven to create your WAR. I think you should be able to simply change the project type in the pom.xml from JAR to WAR. The tutorial you followed seems to use Gradle, which in turn uses Maven I believe, so you should have one there somewhere. Other than that, google for tutorials on how to construct a WAR. I don't believe that Tomcat requires any special deployment descriptors, so you should only need the web
.xml.
(Answer from OP moved from question to here)
Boy I feel really dumb.. Found there was more to the tutorial after changing the gradle instructions.. including the very needed Auto Configuration that supercedes/replaces the need for a web.xml
Solution
Initialize the servlet
Previously, the application contained a public static void main() method which the spring-boot-gradle-plugin was configured to run when using the java -jar command.
By converting this into a WAR file with no XML files, you need a different signal to the servlet container on how to launch the application.
src/main/java/hello/HelloWebXml.java
package hello;
import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.boot.web.SpringBootServletInitializer;
public class HelloWebXml extends SpringBootServletInitializer {
#Override
protected void configure(SpringApplicationBuilder application) {
application.sources(Application.class);
}
}
Will give credit to the first answer, but you both were correct that the web.xml (or what Spring-Boot uses to replace it) was needed.
I would expect to see some INFO output when a spring boot application starts so some ideas are:
Try a regular tomcat instance
Download and extract the zip distribution.
Start tomcat with bin/startup.sh
Copy your war to the webapps directory
Check the logs... hope to see some evidence of spring starting up
Manually inspect the war file
Unzip your war file
Expect to see WEB-INF/web.xml
So I have an Axis2 web service (called "ReleaseService"), which requires a properties file to work correctly. I've deployed axis2 into Tomcat7 on RHEL6 and have a structure like this:
tomcat/webapps/axis2
+ axis2-web, META-INF, org
+ WEB-INF
+ + classes, conf, lib, modules
+ + services
+ + + ReleaseService
+ + + + com, lib, META-INF
Thinking about Java, I would expect the working directory to be tomcat/webapps/axis2/WEB-INF/services/ReleaseService, because it contains a lib folder and the root folder for my binaries.
So I put my properties file in there and tried to access it via
File configFile = new File("releaseservice.properties");
which apparently doesn't work. I've looked for hours but couldn't find a post or documentation snippet, which tells me where the working directory is. I found this, but a system property is no option for me, because I want to keep the deployment simple.
Found out, that the working directory is my tomcat/bin folder, which is the root of the Tomcat Java process.
Bonus question: How can I find out my service directory inside my web service? Does Axis2 provide any helpers to find out which is the folder for the service?
Making assumptions about the current working directory in application code deployed in a Java EE container is not recommended. In addition, you are making the assumption that when the WAR is deployed, releaseservice.properties will exist as a file, i.e. that the container explodes the WAR. This is true for Tomcat, but may not be the case on other servers.
Axis2 creates a distinct class loader for every deployed service. This means that you can access your property file by looking it up as a resource:
MyService.class.getResourceAsStream("/releaseservice.properties")
Replace MyService with the actual class implementing your service, or any other class loaded from WEB-INF/services/ReleaseService.
Apparently the working directory is the tomcat/bin folder. Even though it seems like there is a dedicated application running inside tomcat, it's all the same Java process.
Found it out by adding the following debug code:
File test = new File("abc.txt");
System.out.println(test.getAbsolutePath());
Which returned /opt/tomcat/bin
I have a openJPA based project that I need to deploy it in format of aar into the following folder under Tomcat.
tomcat\webapps\axis2\WEB-INF\services
But it seems that the service cannot load the persistence.xml file in the META-INF folder within the aar file. I found a solution to rename the aar file into jar, like DummySerivce.aar -> DummySerivce.jar and then put the DummySerivce.jar into the lib folder, to be exactly
tomcat\webapps\axis2\WEB-INF\lib
This time, the persistence.xml could be loaded and the service worked well. But this unnecessarily imported a jar file which was not included in the specification.
So my question is, is there any way to load the persistence.xml from a aar file? is it possible to overload the path of persistence.xml file in code?
btw, only entity information are left in the persistence.xml, database connection parameters are already define in code, and I'm using Axis2.
Thanks!
I have found a solution.
By adding the following line into the services.xml, persistence.xml packed in aar file could be successfully loaded.
<parameter name="ServiceTCCL">composite</parameter>
for detailed info. please refer to http://wso2.org/node/1131
Now checking if there's any side effect.
TCCL - Thread context class loader
default - Status quo, normal behavior
composite - TCCL contains all
jars from environment (say webapp) and those specified in the
service
archive (aar) file under /lib service - TCCL contains all jars from
service archive (aar)