Osgi with Java EE 6 Getting started - osgi

I am trying to develop a service where in all the different stacks e.g Persistence, Security, etc. run as OSGi bundles in an OSGi container. I am using JBoss AS 7.1.1 as my OSGi container.
I used the following JBoss stack to setup my project.
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.jboss.bom</groupId>
<artifactId>jboss-javaee-6.0-with-osgi</artifactId>
<version>1.0.3.Final</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
However, I was thinking the Manifiest.MF as well as activator classes will be auto-generated (not that i have a problem doing this), but to my surprise, nothing happens and I am bumped on that.
Also i cannot figure out how to wire services provided by different OSGi bundles together in a web application.
Most of the examples I see are targeting a Spring environment. Please, could someone point me in the Java EE 6 direction?

Your best bet for wiring is probably Blueprint. Blueprint can also replace Activators with eager singleton beans. Blueprint can't be used directly within the web bundle to register and consume services, but a JNDI-Blueprint bridge allows you to use JNDI lookups with an 'osgi:service' namespace.
You can find plenty of Blueprint and Enterprise OSGi tutorials if you google for Apache Aries, and you may find Enterprise OSGi in Action useful. Chapters 1 and 2 are available free on the web.

Related

Felix Scr change log levels

I am using Apache ServiceMix 7.0.1 with Felix SCR. On startup, a number of my OSGI components are in Disabled / Unsatisfied state. In order to get some additional logs around the lifecycle of the components, I looked at changing the log levels for scr and found this article -
http://felix.apache.org/documentation/subprojects/apache-felix-service-component-runtime.html
But I am not clear on where to set the ds.loglevel property in ServiceMix. I tried setting the same in config.properties and also by passing as a launch argument via -D option but it did not result in any additional logging.
Can you please advise me on how to troubleshoot the failing components?
Thanks.
As far as I know scr is using the OSGi log service. In many log configurations these logs are not forwarded to the log backend.
I recently found that felix now offers a new logging solution based on logback that also works for log service as well as several types of OSGi events. So I propose you try with felix logback support bundle.
Here is a blog how to set it up:
http://liquid-reality.de/2018/08/07/logging-osgi.html
Edit: The blog text is below, slightly worse formatted, from a time when the link appeared to be dead because it had moved from blog.liquid-reality.de.
Logging in OSGi seemed to be an arcane thing for quite some time. On
the logback website there is still this explanation by Ekke which was
surely good 2008 but in 2018 people do not accept creating their own
logging bridges, adding config using fragments and tweaking start
levels.
Luckily this all improved quite a lot. Apache Karaf uses pax-logging
and there is now also the felix logback support bundle. In this
article I will focus on the latter as it is simple to setup and has
some nice features.
Example code
I added the felix logback support to my OSGi DS hello
world example because logging is a core aspect in any professional
development.
See the Readme in the example for instruction how to build and run it.
Logging frontends
Logback + Felix logback supports a wide range of
logging frontends (slf4j, jul, log4j, logback, commons logging, OSGi
Log service). For your own code I recommend to use the slf4j API. It
is very slim in dependencies and provides a lot of features.
At compile time you only need the slf4j API.
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.7.25</version>
</dependency>
You instantiate slf4j exactly like outside OSGi. So it
can also be used for hybrid code that can run inside and outside of
OSGi.
class MyClass {
Logger log = LoggerFactory.getLogger(this.getClass()); }
Deployment
At runtime you install the bundles below. These also
include the Felix log service which is used by some OSGi reference
implementations.
<dependency> <groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId> <version>1.7.25</version>
</dependency> <dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<version>1.2.0</version> </dependency> <dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-core</artifactId>
<version>1.2.0</version> </dependency> <dependency>
<groupId>org.apache.felix</groupId>
<artifactId>org.apache.felix.log</artifactId>
<version>1.2.0</version> </dependency> <dependency>
<groupId>org.apache.felix</groupId>
<artifactId>org.apache.felix.logback</artifactId>
<version>1.0.0</version> </dependency>
The simplest way to install these is to use the bndtools bndrun packaging like in the example
above.
Configuration
The logback configuration can be provided by a framework
property. Logback will automatically watch the file for changes and
apply new settings.
-runproperties: logback.configurationFile=file:${.}/logback.xml
You can use plain logback configs but felix logback also provides some
special settings to configure OSGi specific logs like bundle events.
See the examples in the felix logback docs.
An example config can be found here.

How can I know if a maven dependency is supported by a Java EE web container?

Background: I had a maven war project migrated from WildFly 10.1.0.Final Java EE7 Full & Web Distribution to Payara Server 164 Full. The pom.xml was set to specifically satisfy WildFly environment. As a result, some of the <provided> scoped dependencies became problematic after migration because Payara did not have correct implementations for them. By changing some of the dependency scopes to <compile>, I fixed the problems. But it seemed not very smart to try out each of the dependencies to see if one was provided by the container or not.
Question: How can I know what dependencies are supported by a particular container?
For example, there are many versions of Servlet API. How can I know if version 4.0.0-b01 is supported by GlassFish 3.1.2.2?
I want to be able to do it in an appropriate way. E.g. reading from the documentations, using an official toolkit, etc. By the way, I searched in Payara's documentation. But I didn't find a list of supported dependencies and versions.
Alright, I eventually found out a nicer way to do this. I was inspired by this answer, although, it was not directly related to my question.
Short answer:
Go to Java EE version history on Wikipedia. There is a full list of implementations of all the APIs that each Java EE container version implements.
Full answer:
Java EE containers are implementations of Java EE APIs. It means that Java EE projects do not need to contain all the implementation libraries of the dependencies being used. Instead, they need only API libraries such as servlet-api : 3.1.0. However, if any of the API version is "too new" or "too old", and the non-implemented abstract methods are called, an AbstractMethodError will be thrown.
Here is an example of reproducing this error:
On a Java EE 7 container (GlassFish 4) with jdk 1.8, use servlet-api : 4.0.0-b02 as your Servlet API (which contains abstract methods with default implementations). Create a ServletFilter without implementing init and destroy methods. Deploy and start the server. an AbstractMethodError will appear during startup.
The reason for this is that servlet-api : 4.0.0-b02 is supposed to be implemented in Java EE 8. Java EE 7 is associated with jdk 1.7 which does not support default interface method. With servlet-api : 3.1.0 (which is implemented by Java EE 7), init and destroy methods must be implemented in the project. Whereas, when using servlet-api : 4.0.0-b02, it is possible to not implement them. That is where problems occur.
In conclusion, it is generally not a good idea to use different versions between Java EE APIs and their implementations. Oracle provides specifications for different versions of Java EE APIs as an official introduction. It should be checked when building project dependencies.
To use them directly is not a very smart idea.
If you need web profile, just use:
<dependency>
<groupId>javax</groupId>
<artifactId>javaee-web-api</artifactId>
<version>7.0</version>
<scope>provided</scope>
</dependency>
If you need full profile, slightly change it to:
<dependency>
<groupId>javax</groupId>
<artifactId>javaee-api</artifactId>
<version>7.0</version>
<scope>provided</scope>
</dependency>
And you're done. Everything present in the project from now on that comes from this set of dependencies is present in the application servers.
This is actually the correct way to do it. Your way is wrong and whoever told you to work with Java EE like this deserves punishment.

Unit Tests with Jersey 1.17 Test framework

I want to write unit tests for my Resource classes in my Restful Web application.
I am using jersey version 1.17 and using maven 3.0.2. junit 4.8.1.
(Just a background, my web application will be deployed on a Jboss server packaged with other components as an ear.)
Now, I read the Jersey Test framework wiki, but I am unable to find the right set of dependencies to get it working.
There are many versions and artifact and groupIds that are confusing.
Some blogs say
<groupId>com.sun.jersey.test.framework</groupId>
Whereas others say,
<groupId>com.sun.jersey.jersey-test-framework</groupId>
while few say, its changed to
<groupId>com.sun.jersey</groupId>
I am totally confused.
Please help me figure out the right set dependencies required to write a unit test for Resource Classes. I want to use grizzly container. Is it possible?
Thanks in advance.
The Jersey docs for 1.18 say:
Maven developers require a dependency on the
jersey-test-framework-grizzly module. The following dependency needs
to be added to the pom:
<dependency>
<groupId>com.sun.jersey.jersey-test-framework</groupId>
<artifactId>jersey-test-framework-grizzly</artifactId>
<version>1.18</version>
<scope>test</scope>
</dependency>
which looks like it brings in all the dependencies you'll need. EG jersey-test-framework-core

Deploying Simple Spring Hibernate Utility Project via Maven to Tomcat

My goal is understanding the J2EE lifecycle at a high-level with Spring, Hibernate, and Maven. From much research, I understand that Spring provides dependency injection and Hibernate provides object-relation mapping with databases. Maven is a tool to improve the build/deployment process from my understanding. With that said, everywhere I search I get more and more lost on configuration files (i.e. pom.xml, server.xml, etc.), terminology, and alternatives such as Gradle. I just want to build and launch the application and be able to see via http://localhost:8080 in tomcat.
At first, I couldn't get the default project (picture attached) built, but after further research found that I needed to Maven clean and Maven install.
I also modified settings in pom.xml changing version numbers and the database to use MySQL.
<properties>
<maven.test.failure.ignore>true</maven.test.failure.ignore>
<spring.framework.version>3.1.1.RELEASE</spring.framework.version>
</properties>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-entitymanager</artifactId>
<version>4.1.1.Final</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.6</version>
</dependency>
The next issue I had was in OrderPersistenceTests.java it used org.hibernate.classic.Session which is no longer the correct class path and found that it needed to be org.hibernate.Session.
Finally, I was able to get it to build but cannot figure out how to deploy to Tomcat from Spring Tool Suite.
I have put together a simple example using Maven, Spring, Hibernate, and ExtJS for the front end at the following link:
https://github.com/drembert/java-webapp-sample
If you are using Spring Source Tool Suite which it looks like you are in the screen shot, you should be able to import everything using the "Import Maven Projects" option. The example uses Hypersonic as the in-memory DB to allow easier deployment. Keep in mind this example generates two different .war files (one is presentation-layer and the other is service-layer) to emulate a simple RESTful service so both will need to be deployed to the Spring tcServer (STS's version of Tomcat), but once they are you should be able to view the GUI at http://localhost:8080/presentation-layer. Another thing to make note of is that this example currently doesn't have a security layer which would normally be implemented using Spring security, but I am working on adding that in the near future.

jaxws-spring maven dependency is for what purpose

I have the following maven dependecy in my project.
<dependency>
<groupId>org.jvnet.jax-ws-commons.spring</groupId>
<artifactId>jaxws-spring</artifactId>
<version>1.8</version>
</dependency>
Question:
Is this Spring Webservices project?
If not what this dependency is for?
Thanks for your help.
It's a project combining JAX-WS and Spring. Basically it gives you the wss namespace that you might be using in your application context to expose JAX-WS providers as web services. It isn't mandatory but it can be a convenience as it allows you to easily have dependency injection in your servlets although there are other ways to get this. Unfortunately, the last time I was using it I noticed that it was depending on some pretty old spring libraries (pre 3.x) and didn't seem to be updated in some time.

Resources