Toon posts:

[JAVA] Kan klasse niet laden

Pagina: 1
Acties:

Verwijderd

Topicstarter
Ik ben bezig met het maken van een jingle systeem. Dit systeem moet gebruik maken van een zogenaamde faderstart om die jingles te starten. Hiervoor hebben we een schakelaartje gesoldeerd, en die op een LPT poort aangesloten. Met behulp van deze ( _/-\o_ ) link heb ik het voor elkaar gekregen die schakelaar uit te lezen en zo uit te vinden of dat ding open of dicht staat. Dit gebeuren maakt gebruik van JNI.

De klasse die de uiteindelijke link verzorgt:
Java:
1
2
3
4
5
6
7
public class Lpt
{   public native boolean openLPT();
    public native void closeLPT();
    public native void writeLPT(int address, int data);
    public native byte readLPT(int address);
    static {System.loadLibrary("lptport");}
}


Deze klasse zit dus NIET in een package. Als ik dat wel wil doen krijg ik een java.lang.UnsatisfiedLinkError.

Nu wil ik die klasse vanuit mijn programma benaderen, en dus vanuit een klasse die wel in een package zit. Hier gaat het dus mis.
- Stel ik importeer niks: JBuilder geeft de foutmelding "Class Lpt not found"
- Met de regel "import Lpt" geeft JBuilder geen foutmelding, maar tijdens het compilen krijg ik de volgende melding:
"LptTracker.java": Error #: 200 : '.' expected at line 5, column 11
- met "import .Lpt", "import *.Lpt" en "import Lpt." krijg ik de melding "Identifier expected".
- Met "import Lpt.*" (ik ben inmiddels best wanhopig) wordt het helemaal feest:
Cannot access directory Lpt
Ambiguous name: Lpt is both a class and a package
Class Lpt not found

  • TrendKiller
  • Registratie: Januari 2001
  • Laatst online: 02-07 13:03
Kan je wat meer code laten zien?

Dit lijkt mij eerder dat die dll die je wil laden niet gevonden wordt. Ben je zeker dat die dll in dezelfde dir staat?

Als je de file 'Lpt' in een package plaatst, dan moet je in de directory waar de gecompileerde classe komt te staan, ook de dll's plaatsen. Als je dit niet doet, dan moet je in de classe 'Lpt' bij System.loadLibrary het juiste pad naar de dll plaatsen, dus bv "C:\het_pad\de_file.dll"

[ Voor 49% gewijzigd door TrendKiller op 26-08-2003 16:13 ]


Verwijderd

Topicstarter
ok, meer code:
Java:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
package fnb.apollo.core;

import java.util.*;
import Lpt; // gaat mis

public class LptTracker extends Observable implements Runnable{

  public static final int CLOSED = -52;
  public static final int OPEN = -56;

  private int currentStatus = 0;
  private Lpt lpt;

  public LptTracker() {
    lpt = new Lpt();
  }

  public void run(){
    if (lpt.openLPT()){
      currentStatus = lpt.readLPT(957);
      while (true) {
        int newStatus = lpt.readLPT(957);
        if (newStatus != currentStatus){
          currentStatus = newStatus;
          setChanged();
          notifyObservers();
        }
        try {
          Thread.sleep(20);
        }
        catch (InterruptedException ex) {
        }
      }
    } else {
      System.out.println("Could not open LPT");
    }
  }

  public int getStatus(){
    return currentStatus;
  }
}


Werkende code:
Java:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
public class LptTest {
  public LptTest() {
    Lpt lpt = new Lpt();
    if (lpt.openLPT()){
      System.out.println("open");
      boolean b = true;
      int s3 = lpt.readLPT(958);
      System.out.println(" S3: "+s3);
      while(b){
        int ns3 = lpt.readLPT(958);
        if (ns3 != s3){
          s3 = ns3;
          System.out.println("s3 changed to: "+ns3);
        }
      }
    } else {
      System.out.println("not open");
    }
  }

  public static void main(String[] args){
    LptTest test1 = new LptTest();
  }
}


Output van het werkende (onderste) stuk code:
open
S3: -56
s3 changed to: -52
s3 changed to: -56
s3 changed to: -52

  • marcusk
  • Registratie: Februari 2001
  • Laatst online: 26-09-2023
Je moet Lpt niet importeren, maar hij moet wel in je classpath staan. Misschien is het makkelijker (iig netter) als je de klasse een package geeft.

Verwijderd

Topicstarter
De klasse in een package zetten geeft een runtime error:
java.lang.UnsatisfiedLinkError: openLPT
at fnb.apollo.core.Lpt.openLPT(Native Method)
at fnb.apollo.core.LptTracker.run(LptTracker.java:19)
at java.lang.Thread.run(Thread.java:536)

  • hammerhead
  • Registratie: April 2000
  • Laatst online: 21-08 18:06
Moet je dan niet iets extra's opgeven aan de JVM met behulp van:
code:
1
java -Djava.library.path=/pad/naar/dir/waar/native/bibs/staan .....rest....


Weet dat ik dat hier wel moet gebruiken om gebruik te maken van een aantal native routines... Overigens moet je onder windows dus niet / gebruiken maar \ in het pad :) Als je een IDE gebruikt neem ik aan dat je dit ook wel ergens kunt opgeven.

Aviation is proof that given the will, we have the capacity to achieve the impossible.
--Eddie Rickenbacker


Verwijderd

Topicstarter
Volgens P&W beleid regel 4.9 mijn oplossing. Veel te moeilijk, maar wel sneller dan het probleem op een normale manier oplossen:

Een interface in een package die ik wel kan lezen:
Java:
1
2
3
4
5
6
7
8
package fnb.apollo.core;

public interface LptInterface {
  public boolean openLPT();
    public void closeLPT();
    public void writeLPT(int address, int data);
    public byte readLPT(int address);
}


Een uitbreiding op die klasse:
Java:
1
2
3
4
5
6
7
public class Lpt implements fnb.apollo.core.LptInterface{
  public native boolean openLPT();
  public native void closeLPT();
  public native void writeLPT(int address, int data);
  public native byte readLPT(int address);
  static {System.loadLibrary("lptport");}
}


en een zelfgemaakte classloader:
Java:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
public class CustomClassloader extends ClassLoader{
  
  public Class loadClass(String className, File file){
    Class returnValue = null;
    try {
// byteBuffer = de inhoud van het bestand
      returnValue = this.defineClass(className, byteBuffer, 0,
                                     byteBuffer.length);
    }
    catch (IOException ex) {}
    catch (ClassFormatError ex) {}
    return returnValue;
  }
}


En verder:
Java:
1
2
3
4
5
6
7
    CustomClassloader ccl = new CustomClassloader();
    Class lptClass = ccl.loadClass("Lpt",new File("D:/project/Apollo/classes/Lpt.class"));
    try {
      lpt = (LptInterface) lptClass.newInstance();
    }
    catch (IllegalAccessException ex) {}
    catch (InstantiationException ex) {}

  • pgussow
  • Registratie: Maart 2003
  • Laatst online: 18-08-2025
De UnsatisfiedLinkError krijg je omdat ie je DLL niet kan vinden. Oftewel: OF het absolute pad gebruiken in je System.loadLibrary OF je DLL in het pad zetten...

  • hammerhead
  • Registratie: April 2000
  • Laatst online: 21-08 18:06
pgussow schreef op 29 August 2003 @ 13:19:
De UnsatisfiedLinkError krijg je omdat ie je DLL niet kan vinden. Oftewel: OF het absolute pad gebruiken in je System.loadLibrary OF je DLL in het pad zetten...
Dat kun je dan toch ook nog oplossen door java.library.path goed te zetten... Als je daarin het pad naar je DLL zet moet het als het goed is ook gewoon werken. Ik werk hier onder Unix, dus niet met DLL's maar met .so's, en als ik het pad naar die .so bestanden in java.library.path zet gaat alles goed, als ik dat niet doe krijg ik idd een unsatisfied link error

Aviation is proof that given the will, we have the capacity to achieve the impossible.
--Eddie Rickenbacker


Verwijderd

Topicstarter
pgussow schreef op 29 August 2003 @ 13:19:
De UnsatisfiedLinkError krijg je omdat ie je DLL niet kan vinden. Oftewel: OF het absolute pad gebruiken in je System.loadLibrary OF je DLL in het pad zetten...
Dan snap ik iets niet. Als ik de klasse die de native code aanroept NIET in een package zet gaat alles goed, maar zodra ik het WEL in een package zet krijg ik die linkage error. En volgens (mijn interpretatie van) jouw reply zou dat niets uit moeten maken. Wat zie ik over het hoofd?

Maar het werkt nu...

  • Soultaker
  • Registratie: September 2000
  • Laatst online: 01:56
Verwijderd schreef op 02 September 2003 @ 12:41:
Als ik de klasse die de native code aanroept NIET in een package zet gaat alles goed, maar zodra ik het WEL in een package zet krijg ik die linkage error.
Dat klopt ook; de native code implementeert dan andere methoden dan jij in Java declareert. Het zou werken als je de native implementatie zou aanpassen, zodat met de package rekening gehouden wordt.

Het is vrij logisch dat als de Java class loader zoekt naar de methode "aap.Noot.mies" hij die niet kan vinden, als in de DLL een methode genaamd "Noot.mies" gedefinieerd staat. Hoe zou de JVM kunnen raden dat dat dezelfde is?
Pagina: 1