java - OSGI rammer hænger, når du læser indfødt bibliotek

Indlæg af Hanne Mølgaard Plasc

Problem



Situation: Open source OSGI ramme SMILA (http://www.eclipse.org/smila/) startede som Windows Service ved hjælp af Apache Commons-Daemon (http://commons.apache.org/daemon/). Forsøger at indlæse en DLL via System.loadLibrary() fra OSGI-bunden, mens Manifest.mf inkluderer Bundle-NativeCode: path/to/dll.


Miljø: Windows Server 2003, Java 1.6


Fejl: Under indkaldelsen af ​​System.loadLibrary() hænger hele Java-processen. Når tjenesten er stoppet System.loadLibrary() færdiggøres og kodekørsel, indtil OSGI-rammen lukkes.


Fejlen opstår ikke på Windows Server 2008, eller hvis OSGI-rammen ikke er startet som tjeneste.


DLL'en selv er fjernet til ingen funktionalitet til testning. Al import er statisk, og det eneste afhængige bibliotek er kernel32.ddl.


Kan nogen forestille sig, hvorfor dette sker, og hvordan man løser det?





Manifest indeholdende DLL:


Manifest-Version: 1.0
Bundle-ManifestVersion: 2
Bundle-Name: NTFS Utils Acl Win32 Library
Bundle-SymbolicName: com.eccenca.utils.ntfs.acl.win32
Bundle-Version: 2.2.0
Bundle-Vendor: brox IT-Solutions GmbH
Fragment-Host: com.eccenca.utils.ntfs
Eclipse-PlatformFilter: (& (osgi.os=win32) (osgi.arch=x86))
Bundle-NativeCode: ntfsacl/Release/NtfsAcl.dll
Bundle-RequiredExecutionEnvironment: JavaSE-1.6+


Manifest indeholdende kode:


Manifest-Version: 1.0
Bundle-ManifestVersion: 2
Bundle-Name: NTFS Utils Acl
Bundle-SymbolicName: com.eccenca.utils.ntfs
Bundle-Version: 2.2.0
Bundle-Vendor: brox IT-Solutions GmbH
Export-Package: com.eccenca.processing.acl,
 com.eccenca.utils.ntfs
Import-Package: org.apache.commons.io;version="1.4.0",
 org.apache.commons.lang,
 org.apache.commons.logging;version="1.1.1",
 org.eclipse.smila.blackboard;version="0.8.0",
 org.eclipse.smila.datamodel,
 org.eclipse.smila.processing;version="0.8.0",
 org.eclipse.smila.processing.pipelets;version="0.8.0",
 org.eclipse.smila.utils.config;version="0.8.0",
 org.eclipse.smila.utils.service;version="0.8.0",
 org.osgi.framework;version="1.4.0"
SMILA-Pipelets: com.eccenca.processing.acl.AccessListConverterPipelet
Bundle-RequiredExecutionEnvironment: JavaSE-1.6


Kode snipped med System.loadLibrary() påkaldelse:


public class ACLList {
  private static final org.apache.commons.logging.Log LOG = 
      org.apache.commons.logging.LogFactory.getLog(ACLList.class);

  static {
    try {
      LOG.debug("Start loading library");
      System.loadLibrary("NtfsAcl");
      if (LOG.isInfoEnabled()) {
        LOG.info("NTFS ACL library was succesfully loaded");
      }
    } catch (Throwable e) {
      LOG.error(e);
    }
  }

  private ACLList() {
  }

  public static native ArrayList<ACLEntry> getAccessFor(String path, 
      String serverName) throws IOException;

}

Bedste reference


Der er to mulige problemer med den situation, du beskrev; Jeg ved ikke præcis, hvordan Equinox håndterer nativ kode, så jeg vil bare præsentere dem for jer begge.


Bundle-NativeCode kræver mindst en parameter



Du bruger en Bundle-NativeCode header, der blot definerer et bibliotek, og det ser ud til at du bruger Eclipse-PlatformFilter til at angive, hvad det pågældende bibliotek er beregnet til. Afsnit 3.10 i specifikationen viser, at du har brug for mindst en parameter for at biblioteket skal vælges. [15]


Du kan ændre din Bundle-NativeCode header for at læse


Bundle-NativeCode: ntfsacl/Release/NtfsAcl.dll;osname=win32


og din bundle vil kunne finde det rigtige bibliotek.


Indlæs kun fra dit eget bundpakke



At dømme efter din kode kan det være muligt at definere biblioteket i et bundt og forsøge at indlæse det i en anden; det virker ikke, et bundt kan kun indlæse et bibliotek, som det indeholder.