Servlet class is not a javax.servlet.Servlet while deploying a bundle in felix jetty - servlets

I am trying to deploy an OSGI bundle in felix jetty. BootStrap is my class which extends HttpServlet.
I am getting the below Exception at deployment stage :
ins.server.servlet.HttpServlet30Dispatcher is not assignable from javax.servlet.http.HttpServlet
2018-07-11T07:46:55,044 WARN sure-rest-neo [] web-reactor - unavailable
javax.servlet.UnavailableException: Servlet class com.nokia.mdf.sure.neo.utils.Bootstrap is not a javax.servlet.Servlet
at org.eclipse.jetty.servlet.ServletHolder.checkServletType(ServletHolder.java:519) ~[jetty-servlet-9.3.10.v20160621.jar:9.3.10.v20160621]
at org.eclipse.jetty.servlet.ServletHolder.doStart(ServletHolder.java:379) ~[jetty-servlet-9.3.10.v20160621.jar:9.3.10.v20160621]
at org.eclipse.jetty.util.component.AbstractLifeCycle.start(AbstractLifeCycle.java:68) ~[jetty-util-9.3.10.v20160621.jar:9.3.10.v20160621]
at org.eclipse.jetty.servlet.ServletHandler.initialize(ServletHandler.java:874) ~[jetty-servlet-9.3.10.v20160621.jar:9.3.10.v20160621]
at org.eclipse.jetty.servlet.ServletContextHandler.startContext(ServletContextHandler.java:349) ~[jetty-servlet-9.3.10.v20160621.jar:9.3.10.v20160621]
at org.eclipse.jetty.webapp.WebAppContext.startWebapp(WebAppContext.java:1404) ~[jetty-webapp-9.3.10.v20160621.jar:9.3.10.v20160621]
at org.eclipse.jetty.webapp.WebAppContext.startContext(WebAppContext.java:1366) ~[jetty-webapp-9.3.10.v20160621.jar:9.3.10.v20160621]
at org.eclipse.jetty.server.handler.ContextHandler.doStart(ContextHandler.java:778) ~[jetty-server-9.3.10.v20160621.jar:9.3.10.v20160621]
at org.eclipse.jetty.servlet.ServletContextHandler.doStart(ServletContextHandler.java:262) ~[jetty-servlet-9.3.10.v20160621.jar:9.3.10.v20160621]
at org.eclipse.jetty.webapp.WebAppContext.doStart(WebAppContext.java:520) ~[jetty-webapp-9.3.10.v20160621.jar:9.3.10.v20160621]
I have embedded all dependencies including the transitive ones. How to resolve this, which I assume is due to jar conflict ?

The problem is exactly with embedding dependencies. When you embed the javax.servlet package then your bundle will use the embedded class while jetty will use the class available from an exported package. So while these classes are named the same there are different instances in the classloaders which leads to exactly this kind of error.
To generally solve this you make sure that ideally only one bundle exports each package and all bundles that need it import the package. So the easiest solution is to not embed dependencies.
If that does not work for you then you can try to import and export the javax.servlet package in your bundle. This allows the OSGi environment to decide which package it will actually wire and avoid having the same class names with different instances in bundles.

Related

Pax Exam: resolving project dependencies with bundles and wrapped bundles

I'm aware of this answer: Pax Exam: provisioning bundle with all dependencies
But it feels like I'm doing something wrong when I have to include bundles that are part of bundles that are external to my project.
Here is the error I'm getting:
java.lang.Exception: Could not start bundle wrap:mvn:org.apache.cxf/cxf-bundle-jaxrs/2.7.14 in feature(s) test-dependencies-0.0.0: Unresolved constraint in bundle org.apache.cxf.bundle-jaxrs [80]: Unable to resolve 80.0: missing requirement [80.0] osgi.wiring.package; (&(osgi.wiring.package=com.ctc.wstx.stax)(version>=4.4.0)(!(version>=5.0.0)))
Here is my configuration code for my pax exam test:
#Configuration
public Option[] config() {
MavenArtifactUrlReference karafUrl = maven()
.groupId("org.apache.karaf")
.artifactId("apache-karaf")
.version(karafVersion())
.type("tar.gz");
MavenUrlReference karafStandardRepo = maven()
.groupId("org.apache.karaf.features")
.artifactId("standard")
.classifier("features")
.version(karafVersion())
.type("xml");
return new Option[] {
// KarafDistributionOption.debugConfiguration("5005", true),
karafDistributionConfiguration()
.frameworkUrl(karafUrl)
.unpackDirectory(new File("target/exam"))
.useDeployFolder(false),
keepRuntimeFolder(),
KarafDistributionOption.features(karafStandardRepo , "scr"),
//**Do I seriously need to do this?**
wrappedBundle(mavenBundle("org.codehaus.woodstox", "wstx-lgpl")).noStart(),
//**Why am I doing this?**
wrappedBundle(mavenBundle("org.apache.cxf", "cxf-bundle-jaxrs").version("2.7.14")).noStart(),
//**Some of my bundles use this so I guess this makes sense**
wrappedBundle(mavenBundle("org.apache.commons", "commons-lang3")),
mavenBundle("com.company.project", "common-core").versionAsInProject().start(),
mavenBundle("com.company.project", "common-properties", "1.3.1").start(),
mavenBundle("com.company.project", "rev-common-core", "1.3.1").start(),
mavenBundle("com.company.project", "rev-common-properties", "1.3.1").start(),
mavenBundle("com.company.project", "maintenance-core", "1.3.1").start(),
};
}
So my questions are: why am I getting the error about unresolved constraints, do I have to include even external bundles, and what do I need to do to get my tests to run?
Yes, you have to include all required bundles, Karaf container is running empty, you have to provide all bundles required in your test.
You can create a feature for the module you want to test as a way to supply all required bundles. Then you can use it in your test, e.g:
KarafDistributionOption.features("mvn:group/artifact-id/version/xml", "feature-name")

Export package in OSGi Bundle

I have an OSGi Bundle and a servlet. Now I want to access the bundle from the servlet. For that purpose I use the following in the servlet:
#Resource
BundleContext context
...
ServiceReference ref = context.getServiceReference("package.MyOSGiServiceInterface");
MyOSGiServiceInterface service = context.getService(ref);
The Problem is that my servlet doesn't know MyOSGiServiceInterface 'cause that is defined in the OSGiBundle. In Eclipse I added a reference to the bundle Project in my Build Path. But at runtime it obviously can't find it.
To solve that Problem I played around with
(in bundle manifest)
Export-Package: package-of-osgi-service-interface
(in servlet manifest)
Import-Package: package-of-osgi-service-Interface
Dependencies: ...,deployment.MyBundle
But I couldn't solve it.
Whats the missing step? How can I tell JBoss to add the package containing MyOSGiServiceInterface in OSGiBundle to the class path?
Thanks for answers!
(JBoss AS 7.1.1)
--> error message <--
Eventually I solved it. I had to put the right combination of settings together to reach my goal:
Deploy the bundle per: File - Export - "Deployable plug-ins and fragments" into folder: "jboss/standalone/deployments"
Bundle-Manifest:
Bundle-SymbolicName: TestBundle
Bundle-Version: 1.0.0
Export-Package: "package-which-includes-my-service"
Servlet-Manifest:
Dependencies: org.osgi.core,org.jboss.osgi.framework,deployment.TestBundle:1.0.0
Import-Package: "package-which-includes-my-service"

Servlet class is not a javax.servlet.Servlet

I am developing a GWT application, but I got the following Exception when I deploy it into a Equinox-jetty server:
404 Servlet class com.cartif.gui.autentication.server.AppServiceImpl is not a javax.servlet.Servlet <html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"/>
<title>Error 404 Servlet class com.cartif.gui.autentication.server.AppServiceImpl is not a javax.servlet.Servlet</title>
</head>
<body><h2>HTTP ERROR 404</h2>
<p>Problem accessing /baasGUIAutentication/baasgui/autentication. Reason:
<pre>
Servlet class com.cartif.gui.autentication.server.AppServiceImpl is not a javax.servlet.Servlet</pre></p><h3>Caused by:</h3><pre>javax.servlet.UnavailableException: Servlet class com.cartif.gui.autentication.server.AppServiceImpl is not a javax.servlet.Servlet
at org.mortbay.jetty.servlet.ServletHolder.checkServletType(ServletHolder.java:362)
at org.mortbay.jetty.servlet.ServletHolder.doStart(ServletHolder.java:243)
at org.mortbay.component.AbstractLifeCycle.start(AbstractLifeCycle.java:50)
at org.mortbay.jetty.servlet.ServletHandler.initialize(ServletHandler.java:685)
at org.mortbay.jetty.servlet.Context.startContext(Context.java:140)
at org.mortbay.jetty.webapp.WebAppContext.startContext(WebAppContext.java:1250)
at org.mortbay.jetty.handler.ContextHandler.doStart(ContextHandler.java:517)
at org.mortbay.jetty.webapp.WebAppContext.doStart(WebAppContext.java:467)
at org.mortbay.component.AbstractLifeCycle.start(AbstractLifeCycle.java:50)
at org.springframework.osgi.web.deployer.jetty.JettyWarDeployer.startWebAppContext(JettyWarDeployer.java:210)
at org.springframework.osgi.web.deployer.jetty.JettyWarDeployer.startDeployment(JettyWarDeployer.java:122)
at org.springframework.osgi.web.deployer.support.AbstractWarDeployer.deploy(AbstractWarDeployer.java:93)
at org.springframework.osgi.web.extender.internal.activator.WarLoaderListener$DeploymentManager$DeployTask.doRun(WarLoaderListener.java:257)
at org.springframework.osgi.web.extender.internal.activator.WarLoaderListener$DeploymentManager$BaseTask.run(WarLoaderListener.java:215)
at org.springframework.scheduling.timer.DelegatingTimerTask.run(DelegatingTimerTask.java:66)
at java.util.TimerThread.mainLoop(Unknown Source)
at java.util.TimerThread.run(Unknown Source)
</pre>
<hr /><i><small>Powered by Jetty://</small></i><br/>
The code header for the AppServiceImpl class is:
public class AppServiceImpl extends RemoteServiceServlet implements AppService
And AppService:
#RemoteServiceRelativePath("autentication")
public interface AppService extends RemoteService {
User getUser(String user, String pass) throws Exception;
}
Moreover, the web.xml declares the servlet as follows:
<servlet>
<servlet-name>baasguiServlet</servlet-name>
<servlet-class>com.cartif.gui.autentication.server.AppServiceImpl</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>baasguiServlet</servlet-name>
<url-pattern>/baasgui/autentication</url-pattern>
</servlet-mapping>
And baasgui is the folder where the GWT Java code is compiled. I have also checked the javax.servlet class and it is used only once.
Could anyone help me??
Thank you very much in advance!!
Jose
This typically happens if you embed the javax.servlet package into your bundle. Then jetty sees the normal javax.servlet deployed as a bundle while your application sees only the embedded class. So the interfaces are considered to be different.
The best solution is to not embed external stuff into your bundle. If you can not avoid it then export and import the javax.servlet package. So the framework can wire jetty and you bundle to the same classloader providing the package.
Start equinox with console
If it is equinox 3.7.x, -Dosgi.console=6666
If it is equinox 3.8 or newer: -Dosgi.console.enable.builtin=true -Dosgi.console=6666
You will be able to telnet to port 6666
Enter the command in telnet session: packages javax.servlet
In the result list, you will see that the package is available in your OSGi container multiple times. Jersey wires to one of them while your wab wires to the other one. Try to achieve having the package only ones in the container.
I got the solution. In the GWT libraries bundle I had to add the following lines:
Bundle-SymbolicName: gwtlibraries; singleton:=true
Require-Bundle: javax.servlet
Instead of importing packages, the tag Require-Bundle and the part of singleton bundle. Also in the GUI manifest I had to add the next line:
Bundle-SymbolicName: GUI; singleton:=true
Require-Bundle: gwtlibraries //apart from importing the specific libraries
Eclipse-RegisterBuddy: com.cartif.gwt
Eclipse-BuddyPolicy: registered
This was not happening with the previous versions of the GWT libraries I had deployed, but the bundle structure was different because now I am using the unzipped libraries and in previous ones the zipped jar files.
Thank you for your collaboration and help!!!!
Here is a rather mundane reason why I got this exception. I adapted my new servlet from an old servlet. Right above the class definition in the .java file, there is a line of the kind: #WebServlet(name="OldServlet",urlPatterns={"/OldServlet"}). Although I properly renamed my class from OldServlet to NewServlet throughout (in the java and web.xml files), I forgot to change the name in the above line. After I changed the above line to #WebServlet(name="NewServlet",urlPatterns={"/NewServlet"}), I stopped getting this exception. Hope this helps.

NoClassDefFoundError: org/jbox2d/collision/shapes/Shape in netbeans

I am trying to add jbox2d as a dependency to my project in netbeans (playn-jbox2d-1.1-SNAPSHOT.jar), but at run time, I get:
Exception in thread "main" java.lang.NoClassDefFoundError: org/jbox2d/collision/shapes/Shape
All other classes can be accessed fine, just not Shape.
I simply right clicked dependencies in my core directory and did add dependency and searched for jbox2d.
Anyone know what could be wrong?
What version of jbox2d do you have, as a dependency? You can crosscheck in the dependency jar file, if that class (Shape.class) exists or not?
EDIT: Most of the times, 'NoClassDefFoundError' happens due to incorrect classpath settings or when there's more than one class (or jar file) in the classpath, with the same namespace.

seam solder (former weld-extensions project) is not initialized

I want to use logger in my java web application.
I'm using JBossAS 6.0.0.final, cdi (weld), jsf ... etc. Seam solder proposes to use an abstract logger is not tying to a concrete implementation (slf4j, log4j, etc) using jboss-logging api.
In order to get this logger in your code will need to write
# Inject
org.jboss.logging.Logger log
seam-solder.jar has the producer for this logger.
package org.jboss.seam.solder.log;
...
class LoggerProducers
{
# Produces
org.jboss.logging.Logger produceLog (InjectionPoint injectionPoint) {}
}
When I deploying my application, I get an error
15:51:18,300 ERROR [org.jboss.kernel.plugins.dependency.AbstractKernelController] Error installing to Start: name=vfs:///C:/Java/jboss-6.0.0.Final/server/default/deploy/kamis-web-client.5.0.0-SNAPSHOT.ear_WeldBootstrapBean state=Create: org.jboss.weld.exceptions.DeploymentException: WELD-001408 Unsatisfied dependencies for type [Logger] with qualifiers [#Default] at injection point [[field] #Inject private ru.kamis.suite.webclient.web.breadcrumbs.BreadcrumbsManager.log]
This is due to the seam-solder.jar has not META-INF/beans.xml file, and it is necessary for cdi container.
If to add beans.xml file in seam-solder.jar manually, then the application works WELL.
How to do without hacks?
To build my application I use maven, so my solution is not comfortable and NOT fine.
PS: Former weld-extensions project contained META-INF/beans.xml file in jar.
with seam-solder-3.0.0.Beta1 there should be no need to modify the jar

Resources