DZone
Java Zone
Thanks for visiting DZone today,
Edit Profile
  • Manage Email Subscriptions
  • How to Post to DZone
  • Article Submission Guidelines
Sign Out View Profile
  • Post an Article
  • Manage My Drafts
Over 2 million developers have joined DZone.
Log In / Join
  • Refcardz
  • Trend Reports
  • Webinars
  • Zones
  • |
    • Agile
    • AI
    • Big Data
    • Cloud
    • Database
    • DevOps
    • Integration
    • IoT
    • Java
    • Microservices
    • Open Source
    • Performance
    • Security
    • Web Dev
DZone > Java Zone > Service Factory and OSGI Logging Proposal

Service Factory and OSGI Logging Proposal

Slim Ouertani user avatar by
Slim Ouertani
·
Oct. 08, 08 · Java Zone · Interview
Like (0)
Save
Tweet
12.03K Views

Join the DZone community and get the full member experience.

Join For Free

I've been doing some thinking lately about how can we log different bundles  or the same bundle with different versions with different log level.   Logging is an important part of any application thus Osgi gives developers logService to use when possible, but standard logging api (slf4j, log4j) are simple to use.

Why I'm asking this question :
 1 -Working with osgi is a bit different regarding simple java programming: The same class can exist on many bundle with different version (different loader).
 2- Making an upgrade on some bundles by changing the bundle versions :  we should leave the two running  versions  if some other bundles are not updated to use the new milestone version.

I try here to present ServiceFactory utilities and I will present some brainstorming about possible logging enhancement :

ServiceFactory :

We create here three bundles :

1- logger  : contains the api and impl
2- client 1 : using logger service with version 1, as stable implementation the log level is ERROR
3- client 2 : using logger service with version 2.0.0.m1 as unstable implementation the log level is Debug to catch all messages.

Here is the draft implementation of logger class :

package com.jtunisie.osgi.logger.impl;

import com.jtunisie.osgi.logger.Level;
import java.util.Dictionary;
import org.osgi.framework.Bundle;
import org.osgi.framework.ServiceFactory;
import org.osgi.framework.ServiceRegistration;
import org.osgi.framework.Version;

public class Logger implements com.jtunisie.osgi.logger.Logger, ServiceFactory {

@Override
public void log(Class clazz, Level level, String msg, Object... params) {
}

@Override
public Object getService(Bundle bundle, ServiceRegistration arg1) {

Dictionary dictionary = bundle.getHeaders();
Version version = Version.parseVersion((String)dictionary.get(org.osgi.framework.Constants.BUNDLE_VERSION));
String name = (String) dictionary.get(org.osgi.framework.Constants.BUNDLE_NAME);

com.jtunisie.osgi.logger.Logger logger = getLogger(name, version);
return logger;

}

private com.jtunisie.osgi.logger.Logger getLogger(String name, Version version) {
if (version.toString().contains("m")) {
return new ErrorLogger();
} else {
return new DebugLogger();

}
}

@Override
public void ungetService(Bundle arg0, ServiceRegistration arg1, Object arg2) {
}
}
package com.jtunisie.osgi.logger.impl;

import com.jtunisie.osgi.logger.Level;

class ErrorLogger implements com.jtunisie.osgi.logger.Logger {

@Override
public void log(Class clazz, Level level, String msg, Object... params) {
if (level.compareTo(Level.ERROR) == 0) {
msg = LoggerUtils.processMsg(params, msg);
System.out.println("----" +clazz+ " :>"+LoggerUtils.getMessage()+"//"+msg);
}

}
}
package com.jtunisie.osgi.logger.impl;

import com.jtunisie.osgi.logger.Level;

class DebugLogger implements com.jtunisie.osgi.logger.Logger{

@Override
public void log(Class clazz, Level level, String msg, Object... params) {
msg = LoggerUtils.processMsg(params, msg);
System.out.println("----" + clazz + " :>"+ LoggerUtils.getMessage()+"//"+msg);
}

}

client 1 and 2 are to simple activator class as

//client 1

package com.jtunisie.osgi.logger.client;

import com.jtunisie.osgi.logger.*;
import static com.jtunisie.osgi.logger.Level.*;

public class Activator {


private Logger logger;

public Activator(Logger logger) {
this.logger = logger;

}
public void init(){
logger.log(Activator.class ,DEBUG, "DEBUG : 1>>>>>My Id is ## version is ## ", 1,1);
logger.log(Activator.class ,ERROR, "ERROR : 1>>>>>My Id is ## version is ## ", 1,1);
}

}
package com.jtunisie.osgi.logger.client;

import com.jtunisie.osgi.logger.*;
import static com.jtunisie.osgi.logger.Level.*;

public class Activator {
private Logger logger;

public Activator(Logger logger) {
this.logger = logger;

}
public void init(){
logger.log(Activator.class ,DEBUG, "DEBUG : 2>>>>>My Id is ## version is ## ", 2,2);
logger.log(Activator.class ,ERROR, "ERROR : 2>>>>>My Id is ## version is ## ", 2,2);
}
}

if we run these examples the out put will be like :

----class com.jtunisie.osgi.logger.client.Activator :>Wed Oct 08 03:25:18 CEST 2008//ERROR : 2>>>>>My Id is 2 version is 2
----class com.jtunisie.osgi.logger.client.Activator :>Wed Oct 08 03:25:18 CEST 2008//DEBUG : 1>>>>>My Id is 1 version is 1
----class com.jtunisie.osgi.logger.client.Activator :>Wed Oct 08 03:25:18 CEST 2008//ERROR : 1>>>>>My Id is 1 version is 1

==> ServiceFactory gives new implementation per bundle client depends on it's version.

Logging proposal :

Many considerations should be taken when osgi is your framework :

 -Class implementation can be found in different bundles version with same package version.
 -Class implementation can be found in different bundles version with different package version.

log4j.dtd does not have the notion of bundle and version and my proposition is :

 

<!ELEMENT log4j:configuration (renderer*, appender*,(category|logger)*,root?,
categoryFactory?)>

Will be

<!ELEMENT log4j:configuration (renderer*, appender*,(bundle|category|logger)*,root?,
categoryFactory?)>

and

we add version to category and logger element


so our log4j.xml file could be :

<category name="com.jtunisie.osgi.logger.client">
<priority value="ERROR" version="[0.0.0,2.0.0("/>
<priority value="DEBUG" version="2.0.0"/>
</category>

or in our case

<bundle name="com.jtunisie.osgi.client">
<priority value="ERROR" version="[0.0.0,1.0.0("/>
<priority value="DEBUG" version="2.0.0"/>
</bundle>
Factory (object-oriented programming)

Opinions expressed by DZone contributors are their own.

Popular on DZone

  • Why Great Money Doesn’t Retain Great Devs w/ Stack Overflow, DataStax & Reprise
  • The 5 Healthcare AI Trends Technologists Need to Know
  • Growth in Java Development for Web and Mobile Apps
  • 6 Best Books to Learn Multithreading and Concurrency in Java

Comments

Java Partner Resources

ABOUT US

  • About DZone
  • Send feedback
  • Careers
  • Sitemap

ADVERTISE

  • Advertise with DZone

CONTRIBUTE ON DZONE

  • Article Submission Guidelines
  • MVB Program
  • Become a Contributor
  • Visit the Writers' Zone

LEGAL

  • Terms of Service
  • Privacy Policy

CONTACT US

  • 600 Park Offices Drive
  • Suite 300
  • Durham, NC 27709
  • support@dzone.com
  • +1 (919) 678-0300

Let's be friends:

DZone.com is powered by 

AnswerHub logo