I completed the necessary steps to enable Maps in my Android app such as getting the API Key using the SHA-1 fingerprint however, the maps load very slowly. In my app I am loading the map with a marker of device location. I understand getting this fix takes a while but in my app, it is taking about 25-30 seconds. Please see the logs below:
10-13 08:16:09.717 16078-16078/? I/art: Late-enabling -Xcheck:jni
10-13 08:16:09.767 16078-16085/? E/art: Failed sending reply to debugger: Broken pipe
10-13 08:16:09.769 16078-16085/? I/art: Debugger is no longer active
10-13 08:16:09.769 16078-16085/? I/art: Starting a blocking GC Instrumentation
10-13 08:16:09.870 16078-16078/? W/System: ClassLoader referenced unknown path: /data/app/com.demo.mapinviewpager-1/lib/arm64
10-13 08:16:09.895 16078-16078/? I/InstantRun: Instant Run Runtime started. Android package is com.demo.mapinviewpager, real application class is null.
And then after about 24 seconds, the map loads with the current location:
10-13 08:16:33.034 16078-16078/com.demo.mapinviewpager W/System: ClassLoader referenced unknown path: /data/app/com.demo.mapinviewpager-1/lib/arm64
10-13 08:16:33.083 16078-16078/com.demo.mapinviewpager I/FirebaseInitProvider: FirebaseApp initialization unsuccessful
10-13 08:16:33.382 16078-16078/com.demo.mapinviewpager W/art: Before Android 4.1, method android.graphics.PorterDuffColorFilter android.support.graphics.drawable.VectorDrawableCompat.updateTintFilter(android.graphics.PorterDuffColorFilter, android.content.res.ColorStateList, android.graphics.PorterDuff$Mode) would have incorrectly overridden the package-private method in android.graphics.drawable.Drawable
10-13 08:16:33.880 16078-16078/com.demo.mapinviewpager D/PagerAdapter: Creating FragmentA
10-13 08:16:33.922 16078-16078/com.demo.mapinviewpager D/PagerAdapter: Creating FragmentB
10-13 08:16:33.933 16078-16078/com.demo.mapinviewpager D/PagerAdapter: Creating FragmentC
10-13 08:16:34.007 16078-16078/com.demo.mapinviewpager I/FragmentA: isGooglePlayServicesAvailable SUCCESS
10-13 08:16:34.007 16078-16078/com.demo.mapinviewpager I/FragmentA: Google API client is null so creating one
10-13 08:16:34.265 16078-16078/com.demo.mapinviewpager I/zzai: Making Creator dynamically
10-13 08:16:34.507 16078-16078/com.demo.mapinviewpager W/System: ClassLoader referenced unknown path: /data/user/0/com.google.android.gms/app_chimera/m/00000004/n/arm64-v8a
10-13 08:16:34.585 16078-16078/com.demo.mapinviewpager I/Google Maps Android API: Google Play services client version: 9452000
10-13 08:16:34.599 16078-16078/com.demo.mapinviewpager I/Google Maps Android API: Google Play services package version: 9683440
10-13 08:16:34.743 16078-16078/com.demo.mapinviewpager D/FLASH: Couldn't find file: /data/user/0/com.demo.mapinviewpager/files/DATA_ServerControlledParametersManager.data.com.demo.mapinviewpager (No such file or directory)
10-13 08:16:35.043 16078-16078/com.demo.mapinviewpager I/FragmentA: In onCreateView, calling getMapAsync()
10-13 08:16:35.059 16078-16078/com.demo.mapinviewpager E/MapInPagerDemoActivity: LatLong from FragmentA came up empty
10-13 08:16:35.064 16078-16078/com.demo.mapinviewpager E/MapInPagerDemoActivity: LatLong from FragmentA came up empty
10-13 08:16:35.118 16078-17427/com.demo.mapinviewpager I/Adreno: QUALCOMM build : 74df444, I409c65498b
Build Date : 06/22/16
OpenGL ES Shader Compiler Version: XE031.08.00.02
Local Branch : N16
Remote Branch :
Remote Branch :
Reconstruct Branch :
10-13 08:16:35.143 16078-17427/com.demo.mapinviewpager I/OpenGLRenderer: Initialized EGL, version 1.4
10-13 08:16:35.143 16078-17427/com.demo.mapinviewpager D/OpenGLRenderer: Swap behavior 1
10-13 08:16:35.193 16078-16078/com.demo.mapinviewpager I/Choreographer: Skipped 81 frames! The application may be doing too much work on its main thread.
10-13 08:16:35.460 16078-17507/com.demo.mapinviewpager I/b: Sending API token request.
10-13 08:16:35.617 16078-16078/com.demo.mapinviewpager I/FragmentA: In onMapReady, is map loaded yet?
10-13 08:16:35.708 16078-16078/com.demo.mapinviewpager I/FragmentA: In onConnected(), Google API client is:: true
10-13 08:16:35.724 16078-16078/com.demo.mapinviewpager I/MapInPagerDemoActivity: LatLong from FragmentA is: 37.51554646 and long is: -122.26936605
10-13 08:16:35.745 16078-16078/com.demo.mapinviewpager I/FragmentA: ::Google::My current location set::
10-13 08:16:36.234 16078-17507/com.demo.mapinviewpager I/b: Received API Token: <a token number> / Expires in: 432000000ms
10-13 08:16:36.234 16078-17507/com.demo.mapinviewpager I/c: Scheduling next attempt in 431700 seconds.
10-13 08:16:36.243 16078-17507/com.demo.mapinviewpager I/d: Saved auth token
10-13 08:16:36.271 16078-17461/com.demo.mapinviewpager D/NetworkSecurityConfig: No Network Security Config specified, using platform default
10-13 08:16:37.067 16078-17488/com.demo.mapinviewpager W/DynamiteModule: Local module descriptor class for com.google.android.gms.googlecertificates not found.
10-13 08:16:37.074 16078-17488/com.demo.mapinviewpager W/System: ClassLoader referenced unknown path:
10-13 08:16:37.082 16078-17488/com.demo.mapinviewpager I/DynamiteModule: Considering local module com.google.android.gms.googlecertificates:0 and remote module com.google.android.gms.googlecertificates:1
10-13 08:16:37.082 16078-17488/com.demo.mapinviewpager I/DynamiteModule: Selected remote version of com.google.android.gms.googlecertificates, version >= 1
10-13 08:16:37.129 16078-17488/com.demo.mapinviewpager D/GoogleCertificates: com.google.android.gms.googlecertificates module is loaded
10-13 08:16:37.207 16078-17488/com.demo.mapinviewpager D/GoogleCertificatesImpl: Fetched 172 Google release certificates
10-13 08:16:37.217 16078-17488/com.demo.mapinviewpager D/GoogleCertificatesImpl: Fetched 336 Google certificates
10-13 08:16:38.582 16078-16089/com.demo.mapinviewpager W/art: Suspending all threads took: 5.827ms
10-13 08:16:40.889 16078-16078/com.demo.mapinviewpager D/FragmentA: In onLocationChanged(), sending new lat: 37.5323156 and long: -122.2899224
10-13 08:17:01.934 16078-16078/com.demo.mapinviewpager I/FragmentA: In onConnected(), Google API client is:: true
10-13 08:17:02.011 16078-16078/com.demo.mapinviewpager I/MapInPagerDemoActivity: LatLong from FragmentA is: 37.5323156 and long is: -122.2899224
10-13 08:17:02.013 16078-16078/com.demo.mapinviewpager I/FragmentA: ::Google::My current location set::
10-13 08:17:02.114 16078-16078/com.demo.mapinviewpager D/Fragmenta: In onLocationChanged(), sending new lat: 37.5323156 and long: -122.2899224
10-13 08:17:04.182 16078-16085/com.demo.mapinviewpager W/art: Suspending all threads took: 5.447ms
I am using Activity with a ViewPager loading three Fragments.
MyActivity.java
public class MyDemoActivity extends AppCompatActivity
implements FragmentA.OnFragmentInteractionListener,
FragmentB.OnFragmentInteractionListener {
private MyPagerAdapter pagerAdapter;
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.map_in_pager_demo);
ViewPager mPager = (ViewPager) findViewById(R.id.pager);
mPager.setClipToPadding(false);
pagerAdapter = new MyPagerAdapter(getSupportFragmentManager());
pagerAdapter.notifyDataSetChanged();
mPager.setAdapter(pagerAdapter);
// This is required to avoid a black flash when the map is loaded. The flash is due
// to the use of a SurfaceView as the underlying view of the map.
mPager.requestTransparentRegion(mPager);
//always start w/ Maps View, FragmentA
mPager.setCurrentItem(1);
}
#Override
public void onFragmentInteraction(Uri uri) {
//do something
}
#Override
public void makeUseOfNewLocation(UserLatLong userLatLong) {
newUserLatLong = userLatLong;
}
/**
* Used for fetching data from activity
* #return
*/
public UserLatLong getLLFromActivity() {
if(newUserLatLong == null) {
Log.e(TAG, "LatLong from FragmentA came up empty");
}
return newUserLatLong;
}
}
MyPagerAdapter.java
public class MyPagerAdapter extends FragmentPagerAdapter {
public MyPagerAdapter(FragmentManager fm) {
super(fm);
}
#Override
public int getCount() {
return 3;
}
#Override
public Fragment getItem(int position) {
switch (position) {
case 0:
return new FragmentB();
case 1:
//map fragment
return new FragmentA();
case 2:
return new FragmentC();
default:
return null;
}
}
}
FragmentA.java /**does all the map related work*/
#Override
public void onCreate(#Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//checks whether play services are installed
if(!servicesAvailable()) {
return;
}
//Create the location client to start receiving updates
buildGoogleApiClient();
if(mGoogleApiClient != null) {
mGoogleApiClient.connect();
}
}
#Nullable
#Override
public View onCreateView(LayoutInflater inflater, #Nullable ViewGroup container,
#Nullable Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.fragment_map, container, false);
supportMapFragment = (SupportMapFragment) this.getChildFragmentManager().findFragmentById(R.id.map);
if (supportMapFragment != null) {
supportMapFragment.getMapAsync(this);
}
return v;
}
#Override
public void onMapReady(GoogleMap googleMap) {
mMap = googleMap;
// Display the connection status
try {
if (ContextCompat.checkSelfPermission( getActivity(),
Manifest.permission.ACCESS_FINE_LOCATION) ==
PackageManager.PERMISSION_GRANTED &&
ContextCompat.checkSelfPermission( getActivity(),
Manifest.permission.ACCESS_COARSE_LOCATION) ==
PackageManager.PERMISSION_GRANTED)
{
mMap.setMyLocationEnabled(true);
mMap.getUiSettings().setMyLocationButtonEnabled(true);
} else {
ActivityCompat.requestPermissions( getActivity(), new String[] {
Manifest.permission.ACCESS_FINE_LOCATION,
Manifest.permission.ACCESS_COARSE_LOCATION },
TAG_CODE_PERMISSION_LOCATION);
}
} catch (SecurityException se) {
Log.e(TAG, "SecurityException: " + se.getLocalizedMessage());
}
}
#Override
public void onConnected(#Nullable Bundle bundle) {
if (mGoogleApiClient != null) {
try {
mCurrentLocation = LocationServices.FusedLocationApi.getLastLocation(mGoogleApiClient);
if (mCurrentLocation != null) {
final LatLng latLng = new LatLng(mCurrentLocation.getLatitude(),
mCurrentLocation.getLongitude());
//wrap LatLng into UserLatLong
userLatLong.setLat(latLng.latitude);
userLatLong.setLng(latLng.longitude);
//updating the value in the interface
mLLCallback.makeUseOfNewLocation(userLatLong);
CameraUpdate cameraUpdate = CameraUpdateFactory.newLatLngZoom(latLng, 20);
mMap.animateCamera(cameraUpdate);
mMap.addMarker(new MarkerOptions().position(latLng));
Log.i(TAG, "::Google::My current location set::");
mMap.setOnMapClickListener(new GoogleMap.OnMapClickListener() {
#Override
public void onMapClick(LatLng latLng1) {
mMap.clear(); //removes the previous marker
mMap.addMarker(new MarkerOptions().position(latLng1));
//TODO: update A/C Fragments with these new coordinates
float x = (float) latLng1.latitude;
float y = (float) latLng1.longitude;
Log.d(TAG, "Map clicked w/ lat: " + x + " and long: " + y);
//wrap LatLng into UserLatLong
userLatLong.setLat(latLng1.latitude);
userLatLong.setLng(latLng1.longitude);
//updating the value in the interface
mLLCallback.makeUseOfNewLocation(userLatLong);
}
});
mMap.moveCamera(CameraUpdateFactory.newLatLng(latLng));
//for zooming automatically to the location of the marker
CameraPosition cameraPosition = new CameraPosition.Builder().target(latLng).zoom(12).build();
mMap.animateCamera(CameraUpdateFactory.newCameraPosition(cameraPosition));
//TODO: Constrain the camera target to bounds defined by API
mMap.setMinZoomPreference(Constants.DEFAULT_MIN_ZOOM);
mMap.setMaxZoomPreference(Constants.DEFAULT_MAX_ZOOM);
} else {
Toast.makeText(getActivity(), "Current location was null so, calling startLocationUpdates()",
Toast.LENGTH_SHORT).show();
//Begin polling for new location updates
startLocationUpdates();
}
} catch (SecurityException se1) {
Log.e(TAG, "SecurityException1: " + se1.getLocalizedMessage());
}
} else {
Toast.makeText(getActivity(), "Google API client is null!", Toast.LENGTH_SHORT).show();
}
}
protected void startLocationUpdates() {
mLocationRequest = new LocationRequest();
//TODO: throttle these based on the needs
mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
mLocationRequest.setInterval(Constants.UPDATE_INTERVAL);
mLocationRequest.setFastestInterval(Constants.FASTEST_INTERVAL);
try {
//used for foreground use cases
//for background use a PendingIntent
if (ContextCompat.checkSelfPermission( getActivity(),
Manifest.permission.ACCESS_FINE_LOCATION) ==
PackageManager.PERMISSION_GRANTED &&
ContextCompat.checkSelfPermission( getActivity(),
Manifest.permission.ACCESS_COARSE_LOCATION) ==
PackageManager.PERMISSION_GRANTED)
{
LocationServices.FusedLocationApi.requestLocationUpdates(mGoogleApiClient, mLocationRequest, this);
} else {
ActivityCompat.requestPermissions( getActivity(), new String[] {
Manifest.permission.ACCESS_FINE_LOCATION,
Manifest.permission.ACCESS_COARSE_LOCATION },
TAG_CODE_PERMISSION_LOCATION);
}
} catch (SecurityException see) {
Log.e(TAG, "SecurityException2: " + see.getLocalizedMessage());
}
}
Related
After a lot of trial and error, In order to find the cause, I have reduced the startup to this:
public class Startup
{
public void Configuration(IAppBuilder app)
{
RegisterOnShutdown(app);
Log.Debug("\n Startup end !!!");
}
private void RegisterOnShutdown(IAppBuilder app)
{
var context = new OwinContext(app.Properties);
var token = context.Get<CancellationToken>("host.OnAppDisposing");
if (token != CancellationToken.None)
{
token.Register(OnShutdown);
}
}
private void OnShutdown()
{
Log.Debug("\n Shutdown !!!");
}
}
And I get this log:
2022-12-11 08:00:27,045 [1] DEBUG (null) Web.Startup [(null)] <(null)> -
Startup end !!!
2022-12-11 08:00:29,751 [7] DEBUG (null) Web.Startup [(null)] <(null)> -
Shutdown !!!
Why is this happening?
The log file was put in the bin folder, which shouldn't have been, as it changes and causes change to the folder. Refer to this
Relocating the file solved the problem.
I met a OOM-issue of FAN native ads with the latest version 4.28.0.I want the FAN native ads refresh every 10 seconds,so I create a new instance of NativeAd and load ad every 10s.Implemented as the official docs says. I reproduced this issue in official demo too.To reproduce easily,I changed the interval time from 10s to 2s. here is the sample code of my test:
private void showNativeAd() {
nativeAd = new NativeAd(getContext(), mAdunit);
nativeAd.setAdListener(new AdListener() {
#Override
public void onError(Ad ad, AdError error) {
// Ad error callback
Log.e(TAG,"failed-->" + error.getErrorMessage());
//refresh after 2s
requestDelay(2000);
}
#Override
public void onAdLoaded(Ad ad) {
Log.e(TAG,"loaded-->");
// Add the Ad view into the ad container.
//...
//refresh after 2s
requestDelay(2000);
}
#Override
public void onAdClicked(Ad ad) {
// Ad clicked callback
}
#Override
public void onLoggingImpression(Ad ad) {
// On logging impression callback
}
});
// Request an ad
nativeAd.loadAd();
}
private void requestDelay(int millseconds){
if (handler == null){
handler = new Handler(Looper.getMainLooper());
}
handler.postDelayed(new Runnable() {
#Override
public void run() {
showNativeAd();
}
},millseconds);
}
It is running well at the beginning, but about an hour later,crashed.here is the crash log:
java.lang.OutOfMemoryError: pthread_create (1040KB stack) failed: Try again
at java.lang.Thread.nativeCreate(Native Method)
at java.lang.Thread.start(Thread.java:1063)
at java.util.concurrent.ThreadPoolExecutor.addWorker(ThreadPoolExecutor.java:920)
at java.util.concurrent.ThreadPoolExecutor.execute(ThreadPoolExecutor.java:1327)
at android.os.AsyncTask.executeOnExecutor(AsyncTask.java:590)
at com.facebook.ads.internal.m.b$1.run(Unknown Source)
at android.os.Handler.handleCallback(Handler.java:739)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:145)
at android.app.ActivityThread.main(ActivityThread.java:6145)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1399)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1194)
Can anyone help me?
this issue seems be fixed in the latest version v4.28.1.
When I start the KAA client SDK ( JAVA ) on a raspberry PI the CPU usage shoots up to 100%. As soon as I kill the process the CPU usage drops back to normal
Below is the code snippet using to start the kaa where i am starting the kaa client on a raspberry pi
public class NotificationSystemTestApp {
private static final Logger LOG = LoggerFactory.getLogger(NotificationSystemTestApp.class);
public static void main(String[] args) throws InterruptedException {
/*System.out.println(encryptString("abcd", "12332sd1133sdssd45"));
return;*/
new NotificationSystemTestApp().launch();
}
private void launch() throws InterruptedException {
// Create client for Kaa SDK
final KaaClient kaaClient;
DesktopKaaPlatformContext desktopKaaPlatformContext = new DesktopKaaPlatformContext();
final CountDownLatch startupLatch = new CountDownLatch(1);
kaaClient = Kaa.newClient(desktopKaaPlatformContext, new SimpleKaaClientStateListener() {
#Override
public void onStarted() {
LOG.info("--= Kaa client started =--");
startupLatch.countDown();
}
#Override
public void onStopped() {
LOG.info("--= Kaa client stopped =--");
}
}, true);
kaaClient.setProfileContainer(new ProfileContainer() {
public ClientProfile getProfile() {
return new ClientProfile() {{
setClientProfileInfo(new ProfileInfo() {{
setRidlrId("R_00001");
setStationName("Mumbai");
setEquipmentId("EQ0006");
setStationId("5");
}});
}};
}
});
// Registering listener for topic updates
kaaClient.start();
startupLatch.await();
kaaClient.addTopicListListener(new NotificationTopicListListener() {
public void onListUpdated(List<Topic> topicList) {
System.out.println("Topic list updated!");
for (Topic topic : topicList) {
LOG.info("Received topic with id {} and name {}", topic.getId(), topic.getName());
}
}
});
final ScanInfo scanInfo = new ScanInfo() {{
setDestinationId("12");
setSourceId("3");
setEquipmentId("R_00001");
setScanTime(System.currentTimeMillis() / 1000);
setEvent("ENTRY");
setTransactionId(UUID.randomUUID().toString());
}};
kaaClient.attachEndpoint(new EndpointAccessToken("1234"), new OnAttachEndpointOperationCallback() {
#Override
public void onAttach(SyncResponseResultType result, EndpointKeyHash resultContext) {
}
});
kaaClient.attachUser("user1", "1234", new UserAttachCallback() {
public void onAttachResult(UserAttachResponse response) {
System.out.println("Attach User Success - " + response.getResult());
}
});
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
LOG.error("FATA", e);
}
LOG.debug("End Point key hash - " + kaaClient.getEndpointKeyHash());
while (true) {
kaaClient.addLogRecord(new LoggerSchema() {{
setData("");
setMessageType("");
}});
Thread.sleep(10);
}
}
}
Thanks,
Rizwan
As I see, you use constant addition of log records for upload to the Kaa server. The delay is just 10 milliseconds which might be too short for the Raspberry PI system you are running the application on.
Depending on the configuration, the Kaa Client might add considerable processing overhead for each log record with processing in other Java threads causing CPU to constantly spin adding and processing new records.
Try increasing the delay in your 'while (true)' loop and check the CPU usage with different log upload settings.
Should this information be not enough for you to fix the issue, please add logs from the Kaa client and Kaa server for investigation.
I have a spring mvc webapp which uses BIT reports. BIRT reports uses java.util.logging. I am looking for a way to redirect the java.util.logging to log4.
The instructions at this link detail how to do it but I'm having some troubles getting the solution to work.
http://wiki.eclipse.org/BIRT/FAQ/Deployment#Q%3a_Can_I_use_Log4j_with_BIRT.3F
I've added the class as described. Then I added logging.properties into my webapp /resources directory with the following contents.
handlers=com.myer.reporting.logging.Log4jHandler
I don't think the system parameter applies since I am using a webapp?
Anyway I know it is not working because in my application logging directory I get the standard birt logs every time the application server re-starts.
Can someone help me with clarifying these instructions.
thanks
I don't believe those instructions are acceptable for web application. Where there is a single JUL for the whole web server / servlet container.
If you generate report using BIRT API, BIRT allows you to set your own logger. See the method EngineConfig.setLogger(). It works at least in BIRT 4.3.1. We do as follows (it redirects BIRT logs to SLF4J, but the idea should be the same for Log4J):
EngineConfig config = new EngineConfig();
// set logger that forwards log messages to SLF4J
// as of BIRT 4.3.1 the custom logger will be accepted only if it or one of its parent in the BIRT's root logger list.
// see http://git.eclipse.org/c/birt/org.eclipse.birt.git/commit/engine/org.eclipse.birt.report.engine/src/org/eclipse/birt/report/engine/api/impl/EngineLogger.java?h=Kepler&id=1cb9507c8ce997bf5407a73d9c23487cef002fa9
java.util.logging.Logger julLogger = java.util.logging.Logger.getLogger("org.eclipse.birt" + ".myapp.Slf4jBridge");
julLogger.setUseParentHandlers(false);
Handler logHandler = new Slf4jLogHandler();
logHandler.setLevel(Level.FINEST);
julLogger.addHandler(logHandler);
config.setLogger(julLogger);
And the Slf4jLogHandler is implemented as follows:
public class Slf4jLogHandler extends Handler {
private Formatter julFormatter = new SimpleJulFormatter();
#Override
public void publish(LogRecord record) {
if (record == null) {
return;
}
ClassLoader hanlderClassLoader = this.getClass().getClassLoader();
ClassLoader contextClassLoader = Thread.currentThread().getContextClassLoader();
if (hanlderClassLoader != contextClassLoader) {
// do not log in foreign contexts
/*
* This check is necessary if several web applications with "JUL to SLF4J" bridge are deployed in the same Servlet container.
* Each application has its own instance of SLF4J logger, but they all are mapped to the same JUL logger,
* because the JUL logger is loaded by the root classloader. Whereas SLF4J loggers are loaded by their respective
* webapp classloaders. Thus comparing classloaders is the only known way to find out whom the JUL log record belongs to.
*/
return;
}
String loggerName = record.getLoggerName();
if (loggerName == null) {
loggerName = "unknown";
}
Logger slf4jLogger = LoggerFactory.getLogger(loggerName);
/*
* JUL levels in descending order are:
* <ul>
* <li>SEVERE (highest value)
* <li>WARNING
* <li>INFO
* <li>CONFIG
* <li>FINE
* <li>FINER
* <li>FINEST (lowest value)
* </ul>
*/
if (record.getLevel().intValue() <= Level.FINEST.intValue()) {
if (slf4jLogger.isTraceEnabled()) {
slf4jLogger.trace(julFormatter.format(record), record.getThrown());
}
} else if (record.getLevel().intValue() <= Level.FINE.intValue()) {
if (slf4jLogger.isDebugEnabled()) {
slf4jLogger.debug(julFormatter.format(record), record.getThrown());
}
} else if (record.getLevel().intValue() <= Level.INFO.intValue()) {
if (slf4jLogger.isInfoEnabled()) {
slf4jLogger.info(julFormatter.format(record), record.getThrown());
}
} else if (record.getLevel().intValue() <= Level.WARNING.intValue()) {
if (slf4jLogger.isWarnEnabled()) {
slf4jLogger.warn(julFormatter.format(record), record.getThrown());
}
} else if (record.getLevel().intValue() <= Level.SEVERE.intValue()) {
if (slf4jLogger.isErrorEnabled()) {
slf4jLogger.error(julFormatter.format(record), record.getThrown());
}
} else if (record.getLevel().intValue() == Level.OFF.intValue()) {
// logger is switched off
} else {
slf4jLogger.warn("Unexpected log level {}.", record.getLevel().intValue());
if (slf4jLogger.isErrorEnabled()) {
slf4jLogger.error(julFormatter.format(record), record.getThrown());
}
}
}
#Override
public void flush() {
// noop
}
#Override
public void close() throws SecurityException {
// noop
}
}
This approach works even if there are several web apps using BIRT on the same server.
I use a ServletContextListener, that install SLF4JBridgeHandler as unique handler for j.u.l. logger:
public class InstallJULHandlerListener implements ServletContextListener {
#Override
public void contextInitialized(ServletContextEvent arg0) {
// Optionally remove existing handlers attached to j.u.l root logger
SLF4JBridgeHandler.removeHandlersForRootLogger(); // (since SLF4J 1.6.5)
// add SLF4JBridgeHandler to j.u.l's root logger, should be done once
// during the initialization phase of your application
SLF4JBridgeHandler.install();
}
#Override
public void contextDestroyed(ServletContextEvent arg0) {
}
}
I'm face a problem since few days and I can't get solution. below is my app structure:
I have ejbapp.jar inside MyearDeployedOnJboss7.ear at the same level of equinox-server-side-app.war (built using warproduct) and I want to load class from MyJarToLaoadForEjbapp.jar which is in iModernizeWebClient_1.0.0.jar which is in plugins folder of equinox-server-side-app.war (I want show image of app structure but I cannot send image because forum rules need 10 score to be able to do that)
My question is how to allow ejbapp.jar load classes from "MyJarToLaoadForEjbapp.jar" inside MyWebClient_1.0.0.jar's plugin folder which is in the equinox-server-side-app.war.
I think using servletbridge classloader but no idea how to use it.
in my launch.ini I've:
osgi.*=#null org.osgi.*=#null eclipse.*=#null osgi.parentClassloader=app osgi.contextClassLoaderParent=app
I resolved my proble using Servlet HttpServiceTracker from the OSGI spec. how to do it : write HttpServiceTracker liket that :
public class HttpServiceTracker extends ServiceTracker {
private static final Logger logger = Logger
.getLogger(HttpServiceTracker.class.getName());
public HttpServiceTracker(BundleContext context) {
super(context, HttpService.class.getName(), null);
}
public Object addingService(ServiceReference reference) {
HttpService httpService = (HttpService) context.getService(reference);
logger.info("default context path : "
+ org.eclipse.rap.ui.internal.servlet.HttpServiceTracker.ID_HTTP_CONTEXT);
try {
logger.info("will register servlet ");
httpService.registerServlet("/programLauncherServlet",
new ProgramLauncherServlet(), null, null);
logger.info("servlet has been registred with http context ");
// httpService.registerResources( "/", "/html", null );
} catch (Exception e) {
//e.printStackTrace();
logger.info("The alias '/programLauncherServlet' is already in use");
}
return httpService;
}
public void removedService(ServiceReference reference, Object service) {
logger.info("will unregister servlet ");
HttpService httpService = (HttpService) service;
httpService.unregister("/programLauncher");
super.removedService(reference, service);
logger.info("servlet has been unregistred");
}
in your plugin activator class at method start :
#Override
public void start(BundleContext context) throws Exception {
super.start(context);
Activator.plugin = this;
BundleContext osgiContext = BundleReference.class
.cast(AnyClassOfYourProject.class.getClassLoader()).getBundle()
.getBundleContext();
serviceTracker = new HttpServiceTracker(osgiContext);
serviceTracker.open();
LOGGER.info("servlet published !!");
LOGGER.info("Bundle started.");
}
and for unregister the servlet at the stop method :
public void stop(BundleContext context) throws Exception {
Activator.plugin = null;
serviceTracker.close();
serviceTracker = null;
LOGGER.info("servlet unregistered from context !!");
super.stop(context);
}
that's all. your servlet is accessible outside your eclipse bundle and you can call methods inside the bundle.