I am trying to learn OSGI. (Mainly, the dynamic loading and unloading of bundles).
Following Neil Bartlett's tutorial for How To Embed OSGi, I added The Equinox OSGi framework implementation to the class path and started the game.
Here's the code:
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.ServiceLoader;
import org.osgi.framework.Bundle;
import org.osgi.framework.BundleContext;
import org.osgi.framework.BundleException;
import org.osgi.framework.Constants;
import org.osgi.framework.launch.Framework;
import org.osgi.framework.launch.FrameworkFactory;
public class BundleManager {
/**
* #param args
* #throws Exception
*/
public static void main(String[] args) throws Exception {
// TODO Auto-generated method stub
FrameworkFactory frameworkFactory = ServiceLoader.load(
FrameworkFactory.class).iterator().next();
Map<String, String> config = new HashMap<String, String>();
//TODO: add some config properties
Framework framework = frameworkFactory.newFramework(config);
framework.start();
BundleContext context = framework.getBundleContext();
List<Bundle> installedBundles = new LinkedList<Bundle>();
installedBundles.add(context.installBundle(
"file:C:/Users/student/Documents/eclipse/myPlugins/HellowService.jar"));
for (Bundle bundle : installedBundles) {
if (bundle.getHeaders().get(Constants.FRAGMENT_HOST) == null)
bundle.start();
}
System.out.println("done!!");
}
}
Yes, it works. No errors at all. However, the bundle that I installed which is a jar file in the path:C:/Users/student/Documents/eclipse/myPlugins/HellowService.jar contains a "HelloWorld" in its start method. I don't see that "HelloWold" in my eclipse console. Why I don't see that message although the bundle was started? I appreciate any simple help.
Note: HellowService.jar is a plugin project that i created earlier, implemented BundleActivator in one of its classes to add "HelloWorld" message in the start method, and finally exported it as a jar file to the directory C:/Users/student/Documents/eclipse/myPlugins/
Edit: Here's my Activator class in the bundle I am installing and starting:
package com.javaworld.sample.service.impl;
import org.osgi.framework.BundleActivator;
import org.osgi.framework.BundleContext;
import org.osgi.framework.ServiceRegistration;
import com.javaworld.sample.service.HelloService;
public class HelloServiceActivator implements BundleActivator {
ServiceRegistration helloServiceRegistration;
public void start(BundleContext context) throws Exception {
HelloServiceFactory helloServiceFactory = new HelloServiceFactory();
helloServiceRegistration =context.registerService(HelloService.class.getName(), helloServiceFactory, null);
System.out.println("Hello World!");
}
public void stop(BundleContext context) throws Exception {
helloServiceRegistration.unregister();
}
}
And here's the MANIFEST.MF file of the bundle:
Manifest-Version: 1.0
Bundle-ManifestVersion: 2
Bundle-Name: HelloService
Bundle-SymbolicName: com.javaworld.sample.HelloService
Bundle-Version: 1.0.0.qualifier
Bundle-Activator: com.javaworld.sample.service.impl.HelloServiceActivator
Bundle-Vendor: JAVAWORLD
Bundle-RequiredExecutionEnvironment: JavaSE-1.7
Import-Package: org.osgi.framework;version="1.3.0"
Export-Package: com.javaworld.sample.service
The way i export the bundle is by Right Click on the bundle project->Export->Runnable Jar File->then I select the Launch Configuration to be BundleManager (Which is the class installing the bundle).
I still do not see "Hello World!" message when I start the bundle from my application.
Your launcher does not wait for the OSGi Framework to stop. I would expect this program to start everything but then immediately shut down, because we reach the end of the main method. Refer back to my tutorial where I show how to use the Framework.waitForStop method.
Having said that, I would expect the output from your HelloWorld bundle to actually appear before the shutdown. So it seems likely there is an error in that bundle also. Perhaps you haven't declared the activator? I can only guess, because you haven't given any details.
It turned out that I was exporting the bundle incorrectly. That's because I tried to do it by myself. Here's how the bundle should be exported as a jar file:
Open the plugin export wizard File > Export... > Plug-in Development >
Deployable plug-ins and fragments .
Then select the bundle you want to export and the destination directory. Done!
You can now use the path of the jar file to install the bundle. In my case, it is:
installedBundles.add(context.installBundle(
"file:C:/Users/student/Documents/eclipse/myPlugins/plugins/com.javaworld.sample.HelloService_1.0.0.201307220322.jar"));
Source: http://help.eclipse.org/juno/index.jsp?topic=%2Forg.eclipse.pde.doc.user%2Fguide%2Ftools%2Fexport_wizards%2Fexport_plugins.htm
And for sure thanks to #Neil Bartlett
Related
First of all, i am a newbie to Eclipse and Java.
So, my problem is, that i am unable to install javafx to my Eclipse.
What i have installed:
https://www.oracle.com/java/technologies/javase-jdk13-downloads.html (Windows x64 installer)
https://www.java.com/de/download/win10.jsp (download button)
What i already tried:
i followed this guide on how to install Maven and then javafx:
https://www.vogella.com/tutorials/EclipseMaven/article.html
For the POM.xml file i used the code from this link:
https://search.maven.org/remotecontent?filepath=org/openjfx/javafx/15-ea+1/javafx-15-ea+1.pom
Now, after creating a new Maven project and trying to import (e.g. javafx.scene.shape.Rectangle) i get this error:
(After importing jfxrt.jar)
Error: JavaFX runtime components are missing, and are required to run this application
An Example Code i want to run is from my friend:
package vierGewinnt;
import javafx.application.Application;
import javafx.event.EventHandler;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.input.KeyEvent;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;
public class Game extends Application{
public static void main(String[] args){
launch(args);
}
public void start(Stage primaryStage){
Field field = new Field();
Button newGame = new Button("Neues Spiel");
PositionColumn pos = new PositionColumn();
VBox root = new VBox();
root.getChildren().addAll(field, pos, newGame);
Scene scene = new Scene(root);
scene.addEventHandler(KeyEvent.KEY_RELEASED, new EventHandler<KeyEvent>(){
#Override
public void handle(KeyEvent event) {
/*if(field.victory()){
Stage secondaryStage = new Stage();
HBox viBox = new HBox();
Scene viScene = new Scene(viBox);
secondaryStage.setScene(viScene);
secondaryStage.show();
}*/
if (event instanceof KeyEvent)
field.setStone(event);
}
});
primaryStage.setScene(scene);
primaryStage.show();
}
}
(There are other classes for this to work, thats not the problem)
So, at this point i dont know what to next to make it work, or how to get javafx to work in a different way
You are using a JDK version 13 which no longer includes JavaFX. So you need to add JavaFX manually to your project.
This is quite easy, because you are using a Maven project. So all you need to do is:
open the pom.xml file of your project (in the top level directory of your project)
add the javafx dependency to your maven dependencies
(maybe) refresh your maven project (Alt + F5) for eclipse to notice the changes
To add the maven dependency to your project you simply add this to the pom.xml file (somewhere between the tags <dependencies> and </dependencies>:
<dependency>
<groupId>org.openjfx</groupId>
<artifactId>javafx</artifactId>
<version>11</version>
<type>pom</type>
</dependency>
Edit:
To answer your second question about the exception that occures when starting the application:
The StackTrace says:
Caused by: java.lang.IllegalAccessException: class
com.sun.javafx.application.LauncherImpl (in module javafx.graphics)
cannot access class vierGewinnt.Game (in module
org.openjfx.archetype_simple) because module
org.openjfx.archetype_simple does not export vierGewinnt to module
javafx.graphics
So the problem is that the class vierGewinnt.Game can't be created because it can't be accessed. That's because it is not exported. If you add the export it should work.
i want to know that if "MethodOrderer" class is available in JUnit5 Library FOR ECLIPSE or not, because i am unable to find it.
If not, how can i shift jupiter.api_5.3.1 to jupiter.api_5.4.2 in eclipse JUnit5 library?
Will be thankful to see your reply.
I downloaded JUnit5 jar file from "https://search.maven.org/artifact/name.remal.tools.test/junit5/1.26.97/jar" and this jar does have "MethodOrderer" class but when i add this to project dependency and run the testclass, eclipse shows up this error "No tests found with test runner 'JUnit5'."
import static org.junit.jupiter.api.Assertions.assertEquals;
import org.junit.jupiter.api.AfterAll;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.MethodOrderer;
import org.junit.jupiter.api.Order;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.TestMethodOrder;
#TestMethodOrder(MethodOrderer.OrderAnnotation.class)
class JunitCalculatorV4 {
#BeforeAll
static void setUpBeforeClass() throws Exception {
System.out.println("Before All");
}
#AfterAll
static void tearDownAfterClass() throws Exception {
System.out.println("After All");
}
#Test
#Order(1)
void addTest() {
System.out.println("Add test");
}
#Test
#Order(2)
void divideTest() {
System.out.println("Divide Test");
}
}
Actually this annotation #TestMethodOrder(MethodOrderer.OrderAnnotation.class) is from jupiter.api_5.4.2 which i added as an external jar, and that might be causing conflict with the existing JUnit5 library.
My problem would be solved if the JUnit5 library is updated as a whole, or atleast the jarfile inside the library is updated.
Project > Properties: Java Build Path, tab Libraries:
You are using Eclipse 2018-12 (4.10) with JUnit 5.3.1 instead of Eclipse 2019-03 (4.11) with JUnit 5.4.0 (the screenshot shows JAR file names containing _5.3.1.v20181005- instead of _5.4.0.v20190212-).
Please upgrade.
I am trying to make a webDav client on Android using sardine library. I am using Android Studio as IDE. So I added sardine-5.0.1.jar in my libs folder and compile files(sardine-5.0.1.jar) in build.gradle. The project compiles well but when I execute it, I have the error:
java.lang.NoClassDefFoundError: Failed resolution of:
Lorg/slf4j/LoggerFactory.
I just have a single activity.
import android.app.Activity;
import android.os.Bundle;
import com.github.sardine.Sardine;
import com.github.sardine.SardineFactory;
public class MainActivity extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Sardine s = SardineFactory.begin();//This line is the problem
}
}
I tried to add some slf4j.jar files like explained in other tutorials, but it did not help. I'm really struggling with that for a moment and maybe i should take another library for webDav Client.
I am using Eclipse with the Google App Engine plugin. I'm trying to run a simple program with added joda time. It seems like the error relates to the build path and I followed the instructions in:
https://stackoverflow.com/a/12105417/3255963
but I am still getting the error below. What do I need to do to next?
package test;
import java.io.IOException;
import javax.servlet.http.*;
import org.joda.time.DateTime;
import org.joda.time.format.DateTimeFormat;
import org.joda.time.format.DateTimeFormatter;
#SuppressWarnings("serial")
public class testServlet extends HttpServlet {
public void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException {
DateTime newYears = new DateTime (2014, 1, 1, 0, 0);
resp.setContentType("text/plain");
resp.getWriter().println("Hello, world");
}
}
Error:
java.lang.NoClassDefFoundError: org/joda/time/DateTime
I see the joda-time-2.3.jar in the project explorer and the build path.
I also tried selecting it under order and export.
NoClassDefFoundError in Java comes when Java Virtual Machine is not able to find a particular class at runtime which was available during compile time.
Please ck whether u have the req. jars under \WebContent\WEB-INF\lib in the project explorar as well as on the project build path.
I've been trying for some time to learn Java EE but I could never run an EJB example. Oracle's guide uses netbeans but I must learn how to do it in Eclipse. Neither did books did any help or youtube videos.
I can run servlets, jsp, jsf without problems but I always had problems with EJBs. What am I missing?
The problem is configuration within Eclipse I think.
My Project Structure in Eclipse is the following:
The code of HelloWorld.java file:
package helloworld.ejb;
import javax.ejb.Remote;
#Remote
public interface HelloWorld {
public String outputHelloWorld();
}
Code of the HelloWorldBean.java file
package helloworld.ejb;
import javax.ejb.Stateless;
#Stateless
public class HelloWorldBean implements HelloWorld {
public String outputHelloWorld() {
return "Hello World!";
}
}
Code of the HelloWorldClient.java
package helloworldprojectclient;
import javax.ejb.EJB;
import helloworld.ejb.HelloWorld;
public class HelloWorldClient {
#EJB
private static HelloWorld helloWorld;
public static void main (String[] args) {
System.out.println(helloWorld.outputHelloWorld());
}
}
I am using Glassfish 4.0 as a server. The HelloWorldProject is an "EJB Project" while "helloworldprojectclient" is a regular Java Project and i've added javaee.jar (from the glassfish directory) to the buildpath.
When I try to run the HelloWorldClient.java I get the following exception:
Exception in thread "main" java.lang.NullPointerException
at helloworldprojectclient.HelloWorldClient.main(HelloWorldClient.java:10)
which is the following line: System.out.println(helloWorld.outputHelloWorld());
What is the problem? I mention i'm a total beginner at EJBs. Thank you!
Just in case you are still intrested in this:
The first version doesn´t work because you are trying to inject an ejb reference in a class that is not managed by a Container. When you execute the main method, the #EJB annotation is ignored, thus 'HelloWorld' class member is never initialized.
In order to execute this code without modification, you need execute the class in a Application Client Container that will inject the ejb reference.
Your second version runs because instead of to delegate to Container, you are getting the ejb reference through the JNDI service. This is the suggested way when Container injection is no available.
I've managed to make it work. I don't know if this is the correct way but in the "helloworldprojectclient" if you set the buildpath's Project tab and add HelloWorldProject then on the Libraries tab add appserv-rt.jar and javaee.jar (both from glassfish lib folder)
then the client should look like this:
package helloworldprojectclient;
import javax.naming.InitialContext;
import helloworld.ejb.HelloWorld;
public class HelloWorldClient {
public static void main(String[] args) {
try {
InitialContext ic = new InitialContext();
HelloWorld thing = (HelloWorld) ic.lookup("helloworld.ejb.HelloWorld");
System.out.println("It seems it runs: " + thing.outputHelloWorld());
} catch (Exception e) {
e.printStackTrace();
}
}
}