728x90
반응형
Github 소스
- MathConsumer : https://github.com/yscho03/MathConsumer
- MathService : https://github.com/yscho03/MathService
Tutorial (튜토리얼)
1. OSGi "MathConsumer" 생성
1-1. MathConsumer 프로젝트 생성
Activator Code
package org.tutorial.helloosgi.mathconsumer;
import org.osgi.framework.BundleActivator;
import org.osgi.framework.BundleContext;
public class Activator implements BundleActivator {
private static BundleContext context;
static BundleContext getContext() {
return context;
}
public void start(BundleContext bundleContext) throws Exception {
Activator.context = bundleContext;
System.out.println("MathConsumer Starting...");
System.out.println("MathConsumer Started");
}
public void stop(BundleContext bundleContext) throws Exception {
Activator.context = null;
System.out.println("MathConsumer Stopped");
}
}
2-2. MathConsumer 번들 구성
OSGi 번들을 구성하기 위하여 Dependencies에 다음과 같은 Plug-in을 추가해주자.
- org.eclipse.osgi
- org.eclipse.equinox.console
- org.apache.felix.gogo.command
- org.apache.felix.gogo.runtime
- org.apache.felix.gogo.shell
2-3. MathConsumer 실행 설정
프로젝트에서 마우스 오른쪽 버튼을 눌러 Run As > Run Configurations를 클릭해준다.
마우스 오른쪽 버튼을 눌러 New Configuration을 클릭한다.
Workspace를 제외한 나머지 Target Platform을 해제시키고 Apply를 클릭한다.
Add Required Bundles를 클릭 → Only show selected → Apply → Run 순서대로 실행한다.
2-3. MathConsumer 시작
Run을 클릭하면 OSGi MathConsumer가 실행될 것이다. Bundle 목록을 볼 수 있으며 start, stop을 실행시킬 수 있다.
3. OSGi "MathService" 생성
3-1. MathService 프로젝트 생성
3-2. MathService 작성 Service Register 등록
다음과 같은 Package에 Class를 구성한다.
MathService.java
package org.tutorial.helloosgi.mathservice;
public interface MathService {
public int sum(int a, int b);
}
MathServiceImpl.java
package org.tutorial.helloosgi.mathservice.impl;
import org.tutorial.helloosgi.mathservice.MathService;
public class MathServiceImpl implements MathService {
@Override
public int sum(int a, int b) {
return a + b;
}
}
MathUtils.java
package org.tutorial.helloosgi.utils;
public class MathUtils {
public static int minus(int a, int b) {
return a - b;
}
}
Activator.java
package org.tutorial.helloosgi;
import org.osgi.framework.BundleActivator;
import org.osgi.framework.BundleContext;
import org.tutorial.helloosgi.mathservice.MathService;
import org.tutorial.helloosgi.mathservice.impl.MathServiceImpl;
public class Activator implements BundleActivator {
private static BundleContext context;
static BundleContext getContext() {
return context;
}
public void start(BundleContext bundleContext) throws Exception {
Activator.context = bundleContext;
System.out.println("Registry Service MathService...");
this.registryMathService();
System.out.println("OSGi MathService Started");
}
private void registryMathService() {
MathService service = new MathServiceImpl();
context.registerService(MathService.class, service, null);
}
public void stop(BundleContext bundleContext) throws Exception {
Activator.context = null;
System.out.println("OSGi MathService Stopped!");
}
}
3-3. OSGi MathService 번들 구성
다음과 같은 두 패키지를 Exported Packaged로 구성하여 외부에서 호출 가능하도록 한다.
- org.tutorial.helloosgi.utils and
- org.tutorial.helloosgi.mathservice
4. MathConsumer에서 MathService 사용하도록 설정 및 실행
Activator.java파일을 아래와 같이 재편집하도록 한다.
Activator.java
package org.tutorial.helloosgi.mathconsumer;
import org.osgi.framework.BundleActivator;
import org.osgi.framework.BundleContext;
import org.osgi.framework.ServiceReference;
import org.tutorial.helloosgi.mathservice.MathService;
import org.tutorial.helloosgi.utils.MathUtils;
public class Activator implements BundleActivator {
private static BundleContext context;
static BundleContext getContext() {
return context;
}
public void start(BundleContext bundleContext) throws Exception {
Activator.context = bundleContext;
System.out.println("MathConsumer Starting...");
System.out.println("5-3 = " + MathUtils.minus(5, 3));
ServiceReference<?> serviceReference = context.getServiceReference(MathService.class);
MathService service = (MathService) context.getService(serviceReference);
System.out.println("5+3 = " + service.sum(5, 3));
System.out.println("MathConsumer Started");
}
public void stop(BundleContext bundleContext) throws Exception {
Activator.context = null;
System.out.println("MathConsumer Stopped");
}
}
Troubleshooting
원인
- context가 service를 찾지 못해서 발생하는 문제이다.
해결방안
- MANIFEST.MF 파일에서 Runtime에서 Exported Packages 지정을 하였는지 살펴본다.
- bundle 시작 순서를 명시적으로 지정하여 해당 service가 먼저 로드되도록 한다.
MathConsumer Starting...
5-3 = 2
Registry Service MathService...
!SESSION OSGi MathService Started
2022-05-03 09:57:35.730 -----------------------------------------------
eclipse.buildId=unknown
java.version=1.8.0_271
java.vendor=Oracle Corporation
BootLoader constants: OS=win32, ARCH=x86_64, WS=win32, NL=ko_KR
Command-line arguments: -dev file:D:/workspace/.metadata/.plugins/org.eclipse.pde.core/Run OSGI MathConsumer/dev.properties -os win32 -ws win32 -arch x86_64 -consoleLog -console
!ENTRY MathConsumer 4 0 2022-05-03 09:57:38.021
!MESSAGE FrameworkEvent ERROR
!STACK 0
org.osgi.framework.BundleException: Exception in org.tutorial.helloosgi.mathconsumer.Activator.start() of bundle MathConsumer.
at org.eclipse.osgi.internal.framework.BundleContextImpl.startActivator(BundleContextImpl.java:834)
at org.eclipse.osgi.internal.framework.BundleContextImpl.start(BundleContextImpl.java:762)
at org.eclipse.osgi.internal.framework.EquinoxBundle.startWorker0(EquinoxBundle.java:1032)
at org.eclipse.osgi.internal.framework.EquinoxBundle$EquinoxModule.startWorker(EquinoxBundle.java:371)
at org.eclipse.osgi.container.Module.doStart(Module.java:605)
at org.eclipse.osgi.container.Module.start(Module.java:468)
at org.eclipse.osgi.container.ModuleContainer$ContainerStartLevel$2.run(ModuleContainer.java:1847)
at org.eclipse.osgi.internal.framework.EquinoxContainerAdaptor$1$1.execute(EquinoxContainerAdaptor.java:136)
at org.eclipse.osgi.container.ModuleContainer$ContainerStartLevel.incStartLevel(ModuleContainer.java:1840)
at org.eclipse.osgi.container.ModuleContainer$ContainerStartLevel.incStartLevel(ModuleContainer.java:1783)
at org.eclipse.osgi.container.ModuleContainer$ContainerStartLevel.doContainerStartLevel(ModuleContainer.java:1745)
at org.eclipse.osgi.container.ModuleContainer$ContainerStartLevel.dispatchEvent(ModuleContainer.java:1667)
at org.eclipse.osgi.container.ModuleContainer$ContainerStartLevel.dispatchEvent(ModuleContainer.java:1)
at org.eclipse.osgi.framework.eventmgr.EventManager.dispatchEvent(EventManager.java:234)
at org.eclipse.osgi.framework.eventmgr.EventManager$EventThread.run(EventManager.java:345)
Caused by: java.lang.NullPointerException: A null service reference is not allowed.
at org.eclipse.osgi.internal.framework.BundleContextImpl.getService(BundleContextImpl.java:653)
at org.tutorial.helloosgi.mathconsumer.Activator.start(Activator.java:23)
at org.eclipse.osgi.internal.framework.BundleContextImpl$2.run(BundleContextImpl.java:813)
at org.eclipse.osgi.internal.framework.BundleContextImpl$2.run(BundleContextImpl.java:1)
at java.security.AccessController.doPrivileged(Native Method)
at org.eclipse.osgi.internal.framework.BundleContextImpl.startActivator(BundleContextImpl.java:805)
... 14 more
Root exception:
java.lang.NullPointerException: A null service reference is not allowed.
at org.eclipse.osgi.internal.framework.BundleContextImpl.getService(BundleContextImpl.java:653)
at org.tutorial.helloosgi.mathconsumer.Activator.start(Activator.java:23)
at org.eclipse.osgi.internal.framework.BundleContextImpl$2.run(BundleContextImpl.java:813)
at org.eclipse.osgi.internal.framework.BundleContextImpl$2.run(BundleContextImpl.java:1)
at java.security.AccessController.doPrivileged(Native Method)
at org.eclipse.osgi.internal.framework.BundleContextImpl.startActivator(BundleContextImpl.java:805)
at org.eclipse.osgi.internal.framework.BundleContextImpl.start(BundleContextImpl.java:762)
at org.eclipse.osgi.internal.framework.EquinoxBundle.startWorker0(EquinoxBundle.java:1032)
at org.eclipse.osgi.internal.framework.EquinoxBundle$EquinoxModule.startWorker(EquinoxBundle.java:371)
at org.eclipse.osgi.container.Module.doStart(Module.java:605)
at org.eclipse.osgi.container.Module.start(Module.java:468)
at org.eclipse.osgi.container.ModuleContainer$ContainerStartLevel$2.run(ModuleContainer.java:1847)
at org.eclipse.osgi.internal.framework.EquinoxContainerAdaptor$1$1.execute(EquinoxContainerAdaptor.java:136)
at org.eclipse.osgi.container.ModuleContainer$ContainerStartLevel.incStartLevel(ModuleContainer.java:1840)
at org.eclipse.osgi.container.ModuleContainer$ContainerStartLevel.incStartLevel(ModuleContainer.java:1783)
at org.eclipse.osgi.container.ModuleContainer$ContainerStartLevel.doContainerStartLevel(ModuleContainer.java:1745)
at org.eclipse.osgi.container.ModuleContainer$ContainerStartLevel.dispatchEvent(ModuleContainer.java:1667)
at org.eclipse.osgi.container.ModuleContainer$ContainerStartLevel.dispatchEvent(ModuleContainer.java:1)
at org.eclipse.osgi.framework.eventmgr.EventManager.dispatchEvent(EventManager.java:234)
at org.eclipse.osgi.framework.eventmgr.EventManager$EventThread.run(EventManager.java:345)
!ENTRY org.eclipse.osgi 4 0 2022-05-03 09:57:38.065
!MESSAGE Bundle MathConsumer_1.0.0.qualifier [1] is not active.
osgi>
참고
https://o7planning.org/10135/java-osgi-tutorial-for-beginners
728x90
반응형
'백엔드 > 개발' 카테고리의 다른 글
OSGi에 대하여 알아보자 (0) | 2022.05.03 |
---|---|
Java + Gradle을 사용하여 gRPC 서비스를 만들어보자 (0) | 2022.04.28 |
Spring Boot - Hello World 시작해보기 (0) | 2022.04.13 |
Spring Boot 환경설정 (0) | 2022.04.13 |
Django-DSL 동적 INDEX 생성 (0) | 2019.02.03 |