How do I get JBoss AS 7.2 to register my OSGi services when the bundle is loaded? - jboss

I have created a small sample project to have a reference implementation of OSGi with Spring (i.e. Blueprint), and I can get all bundles to install, resolve and start OK, but my service is not registered when the bundle starts.
I've made the entire project available on github so you can take a look at the source - the jars output from the build are in the artifacts folder, but you can also build the project yourself by running gradle assemble.
As I've understood the Blueprint specification, and particularly this guide, there is no need for an activator class to register the services if the configuration files are in the right place - in my jar, I have the following under OSGI-INF/blueprint/sillyservice.xml:
<?xml version="1.0" encoding="UTF-8"?>
<blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0">
<bean id="sillyService" class="se.sunstone.silly.service.ServiceImpl"
init-method="startService">
</bean>
<service ref="helloservice"
interface="com.sample.blueprint.helloworld.api.HelloWorldService" />
</blueprint>
When deploying this bundle, JBoss reports the bundle as ACTIVE.
When I then deploy the client bundle, there is an activator class that runs the following snippet to list all registered services:
ServiceReference[] refs = context.getAllServiceReferences(null, null);
if (refs != null) {
logger.info(String.format("There are %s references", refs.length));
for (ServiceReference ref : refs) {
logger.info(ref);
}
} else {
logger.info("There are no registered services.");
}
A bunch of services that are registered by the OSGi framework inside JBoss are listed, but not my SillyService.
What do I need to do to make this work?

To enable Blueprint functionality, you need to install a Blueprint Extender bundle. There are two implementations available: Apache Aries and Eclipse Gemini. I recommend Aries, which is available from http://aries.apache.org/

Related

Custom TeamCity plugin is uploaded but doesn't seem to get executed

I'm developing a TeamCity plugin and I fail to even get it executed by TeamCity.
I upload the zip file with the plugin and restart TeamCity, then I can see the plugin on the list of external plugins, it also gets unpacked into .BuildServer/plugins/.unpacked but other than that nothing happens.
It doesn't seem that the plugin is running. (I don't even see the plugin name in any logfile)
My simplest attempt was to just create a plugin from maven archetype:
mvn archetype:generate -DarchetypeRepository=http://download.jetbrains.com/teamcity-repository -DarchetypeArtifactId=teamcity-server-plugin -DarchetypeGroupId=org.jetbrains.teamcity.archetypes -DarchetypeVersion=RELEASE
and then only add some logging:
package com.example.plugin;
import jetbrains.buildServer.log.Loggers;
public class AppServer {
public void run() {
Loggers.SERVER.info("I'm running");
}
}
and create the necessary bean with init method:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd"
default-autowire="constructor">
<bean id="appServer" class="com.example.plugin.AppServer" init-method="run"/>
</beans>
I upload the plugin, restart TeamCity but the log message from AppServer does not appear in any logfile.
What am I missing? How to log this message?
I would expect to see an exception (plus a stacktrace) in the teamcity-server.log file. Are you sure you checked that file?
The behaviour you're describing can be symptomatic of you having built the plugin with a JDK version incompatible with TeamCity's JRE. For example, you build your plugin with Java 8 but your TeamCity is running under Java 7. In that case, the plugin will be detected (as it is in your case) but will crash when TC tries to invoke it.

Glassfish v3: Web application not finding JAR in the same EAR

I created a EAR application in Eclipse to run in Glassfish 3.1. The used projects are: BibliotecaEAR2 (the main EAR. 'Biblioteca' means 'Library'), BibliotecaEJB (with EJBs), BibliotecaModel (with entities and DAOs) and BibliotecaWeb (The Web application). The application.xml has this structure:
<?xml version="1.0" encoding="UTF-8"?>
<application xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/application_6.xsd" id="Application_ID" version="6">
<display-name>BibliotecaEAR2</display-name>
<module>
<web>
<web-uri>BibliotecaWeb.war</web-uri>
<context-root>biblioteca</context-root>
</web>
</module>
<module>
<ejb>BibliotecaEJB.jar</ejb>
</module>
</application>
In BibliotecaWeb, the META-INF/MANIFEST.MF is written this:
Manifest-Version: 1.0
Class-Path: lib/google/guava-18.0.jar
// other JARs in BibliotecaEAR2 project
BibliotecaEJB.jar
When I start the glassfish I get this warning message:
2014-10-20T14:34:31.691-0200|WARNING: PWC6351: In TLD scanning, the supplied resource file:/C:/dev/glassfish3/glassfish/domains/biblioteca-glass3/eclipseApps/BibliotecaEAR2/BibliotecaEJB.jar does not exist
java.io.FileNotFoundException: C:\dev\glassfish3\glassfish\domains\biblioteca-glass3\eclipseApps\BibliotecaEAR2\BibliotecaEJB.jar (O sistema nao pode encontrar o arquivo especificado)
Although it does not stop me from running the application, I would like to eliminate it.
Googling for PWC6351 warning, I perceived that it happens when a used JAR is not found in the Manifest File. However the request JAR is not simply a external library, but a sub-project in same EAR. Is there any additional configuration that should I do?
Thanks,
Rafael Afonso
From Packaging libraries with EARs:
When packaging applications in an EAR file, the library JARs need to
be placed in the archive lib directory (jars at the archive root level
are not added to the classpath and thus available from other EAR
artifacts.)
The library jars placed in the "/lib" directory of the EAR (the
directory name can be overridden in application.xml) will be visible
to all sub-modules (JARs, WARs, and RARs) with no further
configuration. No need to add Class-Path entries in the EAR manifest.
In fact you don't need to reference the jars in the lib folder, and it looks like it will not work if you reference a jar on the EAR root level, like your BibliotecaEJB.jar.
If you don't have a real dependency from your WAR module classes to your EJB module classes you can just remove all the entries from the MANIFEST.MF and it should work.
If you instead have a real dependency from WAR to EJB, you may have to think about your project structure and if you really need an EAR. You can also package all the stuff into a single WAR.
The right way to use an EAR with WAR and EJB modules requires a little bit of work if your current WAR classes directly depend on classes from the EJB module:
1. Step
You have to create interfaces for all your "service" classes which should be available to classes in the web application (WAR).
Here is a simple example:
public interface FileService {
public void showFileInformation(File file);
}
and
#Stateless
#Local(FileService.class)
#Remote(FileService.class)
public class FileServiceImpl implements FileService {
#Override
public void showFileInformation(File file) {
// here
// is
// the
// real
// stuff
}
}
2. Step
The next step is to package all your new interfaces into a new jar. Your model jar looks similar to this approach. If this can't be used for this purpose, create a simple java application project which gets packaged as jar and put all the interfaces into this project. This jar has to be in the lib folder of the EAR.
BibliotecaEAR2
-- BibliotecaEJB
-- BibliotecaWeb
-- /lib/interfaces.jar
Then you have to add a dependency to this new jar in your WAR and EJB modules, so that they can find the interface classes.
3. Step
The services can be injected into the managed classes of your web applications (and into other service classes) like this:
#RequestScoped
public class FileHandler {
// make sure to use the interface
#EJB
FileService fileService;
}
Maybe you already have something similar to this, but then it should work without any entries in the MANIFEST.MF.
See also:
Maven2: Best practice for Enterprise Project (EAR file)
Java EE - EAR vs separate EJB+WAR
Packaging EJB in JavaEE 6 WAR vs EAR
I had a similar issue and solved by customizing module location, like this
<?xml version="1.0" encoding="UTF-8"?>
<application xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/application_6.xsd" id="Application_ID" version="6">
<display-name>BibliotecaEAR2</display-name>
<module>
<web>
<web-uri>BibliotecaWeb.war</web-uri>
<context-root>biblioteca</context-root>
</web>
</module>
<module>
<ejb>BibliotecaEJB.jar</ejb>
<bundleDir>/lib</bundleDir> <!-- ADD THIS OPTION TO THE MODULE -->
</module>
</application>
This solution is taken from the Maven EAR plugin documentation, which uses Maven 3 syntax, but I think you can use it too (or you can migrate to Maven 3).
Hope that helps.

Importing External JAR to Websphere Liberty? [NoClassDefFoundError]

I want to use this JSON parser in my JAX-RS application that runs on Websphere Liberty.
I have done the following:
1) Right-click on Project -> Properties -> Java Build Path -> Add External Jar -> C:\javalib\quick-json.jar
2) Added C:\javalib to enviroment variable CLASSPATH
3) Added fileset xml to serverl.xml
<library id="ExternalLibs">
<fileset dir="C:\javalib" includes="*.jar"/>
</library>
4) Unchecked 'Enable project specific settings' in 'Java Compiler'
5) Cleaned the Project
[EDIT]
I was initially creating a new instance and then I turned it into an #ApplicationScoped bean and injected it. Now I get this error:
The JNDI lookup failed for JNDI name java:module/ConsoleREST with the following Exception CNTR4007E: An error occurred creating the websphere.jaxrs.service.ConsoleREST interface for the ConsoleREST enterprise bean in the WebApiConsole.war module in the WebApiConsole application. The enterprise bean look up failed using the java:module/ConsoleREST JNDI name. Exception: com/json/parsers/JsonParserFactory.
CNTR4007E: An error occurred creating the websphere.jaxrs.service.ConsoleREST interface for the ConsoleREST enterprise bean in the WebApiConsole.war module in the WebApiConsole application. The enterprise bean look up failed using the java:module/ConsoleREST JNDI name. Exception: com/json/parsers/JsonParserFactory
The first step was enough to get it to compile. Now I'm getting what I learned to be a runtime error. I would appreciate help!
You also need a <classloader> element in your application definition in the server.xml, which references the shared library. For example,
<application id="myapp" name="My App" type="war" location="somewhere.war">
<classloader commonLibraryRef="ExternalLibs" />
</application>
Alternatively, if your application is the only user of the library, you could package it in the WEB-INF/lib folder of your war. (Putting it in WebContent/lib in Eclipse should accomplish this.)

Spring context:component-scan fails to find components in another Eclipse project dependency referenced in POM

I am working on a GWT web application split across two Eclipse Projects (myclient & myservice).
The myclient project references the myservice project via a dependency in the POM.
<dependency>
<groupId>com.myproject</groupId>
<artifactId>myservices</artifactId>
<version>1.0.0</version>
</dependency>
The myclient project has a WAR directory src/main/webapp. The output folder for the myclient project is src/main/webapp/WEB-INF/classes.
The myclient project has a Spring descriptor application-context.xml with the following
<context:component-scan base-package="com.myproject.myclient, com.myproject.myservices"/>
and the web.xml
<web-app>
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/application-context.xml</param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<listener>
<listener-class>org.springframework.web.context.request.RequestContextListener</listener-class>
</listener>
...
</web-app>
I have several files in the myservices project annotated as spring #Component, #Service, #Configuration but these are not picked up by the component scan when I run the GWT application in Eclipse. As a test I experimented with placing an #Component in the myclient project and this was successfully created.
I believe the following log entry during application startup indicates the source of the problem
org.springframework.core.io.support.PathMatchingResourcePatternResolver - Resolved location pattern [classpath*:com/myproject/myservices/**/*.class] to resources []
the location pattern for the myclient project resolves to all the resources on the classpath but for myservices no resources are found.
I experimented with building the myservices project JAR and placing this JAR into the src/main/webapp/WEB-INF/lib folder of the myclient project. When I do this the component scanning works. However for development I don't want to have to build and copy a JAR everytime I make changes to the myservices project. I imagine that the component scanning should work on a project referenced through the POM without having to the build that project but after much experimenting I have been unable to get this working.
Be sure that in the deployment assembly (right click your web project and select "deployment assembly" of your myclient project it is configured to deploy the jar that is outputted by the myservices project. If you are using maven, the m2e, m2e-wtp project configurators should do this deployment assembly setup automatically.
Once you have deployment assembly settings properly configured, now when you deploy a project to your server using the Eclispe server adapter publish mechanism, everything should get deployed and the myservices jar would get placed in the right spot for your myclient project.
But make sure you the latest version of m2e-wtp installed. This way your configuration in your pom.xml and deployment assembly will get correctly configured.
Try splitting your application-context.xml into 2 separate files:
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:service-context.xml,classpath:client-context.xml</param-value>
</context-param>
myservices/src/main/resources/service-context.xml:
<context:component-scan base-package="com.myproject.myservices"/>
myclient/src/main/resources/client-context.xml:
<context:component-scan base-package="com.myproject.myclient"/>
Try this :
<context:component-scan base-package="com.myproject"/>
Please check the following things:
Is your serviceproject present "only" as jar or is the whole project available via workspace resolution. This can be checked via maven-context-menue (Disable/Enable Workspaceresolution)
The layout of the webapp under src/main/webapp is okay. BUT do i get you right that all classes are copied there? If so, you should make sure everything is under target directory. So please check whether a maven call "clean package" generates a webappstructure under the target folder and all required libs (e.g. myservice) exist under target\$your-webarchivename\WEB-INF\lib
Check that packaging in myservice pom.xml is set to jar (you probably have this, right?)
it's obvious that your service jar is not included in your client project's build path. this is the only root cause.
Make sure 3 points:
you have run mvn clean install under your service project which has correct pom.xml.
you have run mvn eclipse:eclipse under your client project. this will pull out all your dependency project.
check your client eclipse project's build path dialog. is there your service jar in the list? Make sure this
You better once look this tutorial
http://fusesource.com/docs/framework/2.2/deploy_guide/CXFServletDeploySpring.html

Deploying my GWT Application on Tomcat Server

I want to setup a GWT application (Version 2.0.0) with many dependencys in my local Tomcat Server. I started to write a maven2 build script for deploying and packaging of the application.
I wrote a maven2 script which works really fine in my eyes, but I get an error when trying to deploy the out coming war on my tomcat.
2011-04-21 18:14:13,951 ERROR org.apache.catalina.startup.ContextConfig - Parse error in application web.xml file at jndi:/localhost/quickfinder.ui-1.0-SNAPSHOT/WEB-INF/web.xml
org.xml.sax.SAXParseException: The markup declarations contained or pointed to by the document type declaration must be well-formed.
The web.xml is look like the following:
here and my maven2 script looks like this:
here
After compiling and linking and the other stuff my "deploy" directory (named war) looks like:
|-AnswerPanel.css
|-common.css
|-DomainListPanel.css
|-glossary.css
|-glossary.html
|-images
|-META-INF
|-MulitpleChoiceEditPanel.css
|-MultipleChoiceDisclosurePanel.css
|-NaviPanel.css
|-QuestionnairePanel.css
|-quickfinder
|-Quickfinder.css
|-Quickfinder.html
|-quickfinderportlet
|-QuickfinderPortlet.html
|-styles-css2.css
|-styles-css3.css
|-WEB-INF
|--lib
Under lib in the WEB-INF directory, all needed library's are available. The Project has got some RPC calls and so on.
With mvn compile war:war a .war file and a folder named #artifactId#-SNAPSHOT-1.00 are created under /target.
I don't know how to handle with this error form tomcat, or is there a logical mistake in the pom.xml.
BR,
mybecks
Your web.xml is not well-formed: fix the below section
<!DOCTYPE web-app
PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
"http://java.sun.com/dtd/web-app_2_3.dtd" [
<!ENTITY GlossaryWebXml SYSTEM "glossary.web.xml"> -->
]>
I would suggest to add maven-xml-plugin to your validate phase. It will check your web.xml automatically.