[java]Class files in package vinden

Pagina: 1
Acties:
  • 113 views sinds 30-01-2008
  • Reageer

  • zwippie
  • Registratie: Mei 2003
  • Niet online

zwippie

Electrons at work

Topicstarter
Ik wil graag weten welke class-files er in een package zitten. Hier staat een codevoorbeeld om dit te doen, ik heb het ietsje aangepast. Het probleem is dat deze code nooit de gewenste output geeft.
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
package test;

import java.io.File;
import java.net.URL;

public class PackageList {
    
    private static void find(final String pckgname) {        
        String name = new String(pckgname);
        if (!name.startsWith("/")) {
            name = "/" + name;
        }
        
        name = name.replace('.','/');
        
        final URL url = PackageList.class.getResource(name);
        final File directory = new File(url.getFile());
        
        if (directory.exists()) {
            final String[] files = directory.list();
            for (int i = 0; i < files.length; i++) {
                if (files[i].endsWith(".class")) {
                    System.out.println(files[i].substring(0,files[i].length()-6));
                }
            }
        } else {
            System.out.println("No such dir: " + directory.getPath());
        }
    }
    
    public static void main(String[] args) {
        find("test");
        System.out.println();
        find("test2");
    }
}

output:
code:
1
2
3
4
5
No such dir: C:\Program%20Files\eclipse\workspace\test\test

Exception in thread "main" java.lang.NullPointerException
    at test.PackageList.find(PackageList.java:17)
    at test.PackageList.main(PackageList.java:34)

Package 'test' bestaat, maar directory.exists() geeft false. Dit terwijl hij wel een url kan construeren naar de directory. De directory bestaat dus wel, maar java kan/wil hem niet lezen?!

Als ik het probeer met de niet bestaande package 'test2' wordt de variable url null: het bestand kan niet worden gevonden, url.getFile() geeft nu een NullPointerException. Dat is wel volgens verwachting.

Ik heb dit getest in Windows XP met de JDK 1.4.2 en 1.5.0, beide met hetzelfde (negatieve) resultaat. Getest in respectievelijk Eclipse 3.0.2 en 3.1.

URI's, URL's, verschillende File constructors: ik heb vanalles geprobeerd en gezocht maar kom er niet uit. Classpath staat ook goed, aangezien hij de directory's prima kan vinden en ik zelfs niet eens een class laadt. Ik heb uitgebreid gedebugged maar kan geen aanwijzingen vinden.

Heeft er iemand een idee wat hier mis gaat?

How much can you compute with the "ultimate laptop" with 1 kg of mass and 1 liter of volume? Answer: not more than 10^51 operations per second on not more than 10^32 bits.


Verwijderd

Kan je niet beter een File openen aan de hand van een naam?
dus File directory = new File("directoryName");
(wel een String invullen als c:\directoryname\folderName)
dan wel controleren of het een folder is.. directory.isDirectory()
dan kan je hierop de list() aanroepen ed
Kan je hier wat mee?

  • zwippie
  • Registratie: Mei 2003
  • Niet online

zwippie

Electrons at work

Topicstarter
url.getFile() geeft de filename van de URL reeds als String, dus niet als File-object zoals de naam wel doet vermoeden.

De reden dat ik geen "hardgecodeerde" foldernaam geef is dat ik adhv de packagenaam het pad wil vinden, waar deze ook op de schijf staat. De locatie van de package is te achterhalen door getResource() te gebruiken, deze retourneert een URL.

How much can you compute with the "ultimate laptop" with 1 kg of mass and 1 liter of volume? Answer: not more than 10^51 operations per second on not more than 10^32 bits.


  • Creepy
  • Registratie: Juni 2001
  • Laatst online: 03-05 20:49

Creepy

Tactical Espionage Splatterer

Gok: C:\Program%20Files is heel iets anders dan C:\Program Files voor een filesysteem (onder Windows en Linux in elk geval ;) ).

"I had a problem, I solved it with regular expressions. Now I have two problems". That's shows a lack of appreciation for regular expressions: "I know have _star_ problems" --Kevlin Henney


  • Daos
  • Registratie: Oktober 2004
  • Niet online
Het werkt hier gewoon: Bij find("test") komt er "PackageList" op het scherm en bij find("test2") komt er de nullpointer exception.

Ik vind het erg vreemd. .getResource() geeft null als de directory niet bestaat. Als programma bij directory.exists() komt bestaat het directory en de exist() moet dus altijd waar geven. (Behalve als de package in een jar zit).


Waarom heb je zoiets nodig? Je kan gewoon code schrijven die er vanuitgaat dat alles er is. Als dat niet het geval is wordt er automatisch een NoClassDefFound exception gegooit die je in bv de main kan afvangen.

  • zwippie
  • Registratie: Mei 2003
  • Niet online

zwippie

Electrons at work

Topicstarter
Creepy schreef op woensdag 27 juli 2005 @ 14:43:
Gok: C:\Program%20Files is heel iets anders dan C:\Program Files voor een filesysteem (onder Windows en Linux in elk geval ;) ).
Reeds uitgebreid mee gespeeld. ;) Ik heb voor bijna alle varianten van url.toXXX en file.getXXXPath etc geprobeerd om ze te openen door de desbetreffende String uit de debugger te kopieren naar een Windows Explorer venster. Sommige varianten werken, anderen niet.
Aangezien er met de huidige code wél een File object kan worden aangemaakt, ga ik er vanuit dat de URL iig een bruikbaar iets oplevert, ook onder Windows.
Toch zal ik hier nog eens naar kijken.
Daos schreef op woensdag 27 juli 2005 @ 14:55:
Het werkt hier gewoon: Bij find("test") komt er "PackageList" op het scherm en bij find("test2") komt er de nullpointer exception.
Wow! :) Kun je me vertellen welke JDK en welk OS je gebruikt? Dan weet ik of ik moet kijken naar mijn code of naar de randvoorwaarden bij de uitvoering daarvan.
Waarom heb je zoiets nodig? Je kan gewoon code schrijven die er vanuitgaat dat alles er is. Als dat niet het geval is wordt er automatisch een NoClassDefFound exception gegooit die je in bv de main kan afvangen.
In het uiteindelijke programma kan de gebruiker kiezen tussen verschillende 'strategieën'. Dit zijn eigenlijk klasses die voldoen aan een bepaalde interface. Ik schrijf zelf verschillende strategieën en die sla ik op in een bepaalde package. Omdat ik de namen van deze verschillende klassen niet wil hardcoden in het programma wil ik het op deze manier doen.

How much can you compute with the "ultimate laptop" with 1 kg of mass and 1 liter of volume? Answer: not more than 10^51 operations per second on not more than 10^32 bits.


  • Daos
  • Registratie: Oktober 2004
  • Niet online
zwippie schreef op woensdag 27 juli 2005 @ 15:48:
...

Wow! :) Kun je me vertellen welke JDK en welk OS je gebruikt? Dan weet ik of ik moet kijken naar mijn code of naar de randvoorwaarden bij de uitvoering daarvan.
JDK1.3.1 op Windows95. Het ligt aan de spatie in Program Files in combinatie met de Java versie:

code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
C:\>"C:\JBUILDER7\JDK1.3.1\bin\java" -classpath "C:\Mijn documenten\jbproject\FindPackage\classes"  test.PackageList
PackageList

Exception in thread "main" java.lang.NullPointerException
        at test.PackageList.find(PackageList.java:17)
        at test.PackageList.main(PackageList.java:34)


C:\>"C:\Program Files\java\jre1.5.0_04\bin\java" -classpath "C:\Mijn documenten\jbproject\FindPackage\classes"  test.PackageList
No such dir: C:\Mijn%20documenten\jbproject\FindPackage\classes\test

Exception in thread "main" java.lang.NullPointerException
        at test.PackageList.find(PackageList.java:17)
        at test.PackageList.main(PackageList.java:34)


C:\>"C:\Program Files\java\jre1.5.0_04\bin\java" -classpath "C:" test.PackageList
PackageList

Exception in thread "main" java.lang.NullPointerException
        at test.PackageList.find(PackageList.java:18)
        at test.PackageList.main(PackageList.java:35)

[ Voor 23% gewijzigd door Daos op 27-07-2005 17:01 ]


  • zwippie
  • Registratie: Mei 2003
  • Niet online

zwippie

Electrons at work

Topicstarter
Daos, veel dank voor deze info!

Na grondiger spitwerk op het internet blijkt dat java.io.File nogal problemen heeft met bepaalde URL's. Ik zal er nog eens dieper induiken. De apidocs vind ik een beetje te kort schieten op dit gebied.

(@Creepy: toch goedgegokt! :P )

How much can you compute with the "ultimate laptop" with 1 kg of mass and 1 liter of volume? Answer: not more than 10^51 operations per second on not more than 10^32 bits.


  • Daos
  • Registratie: Oktober 2004
  • Niet online
Je moet in de string die uit url.getFile() komt alle "%20" vervangen door " ". Dit kan door .replaceAll(..) erachter te zetten.

Probeer ook eens "url.toURI().getPath()".

[ Voor 13% gewijzigd door Daos op 27-07-2005 17:34 ]


  • zwippie
  • Registratie: Mei 2003
  • Niet online

zwippie

Electrons at work

Topicstarter
Wederom _/-\o_

Ik zat al te graven in de bugdatabase waar Class.getResource() inderdaad niet goed blijkt om te gaan met URL's.
Deze replaceAll workaround werkt voorlopig, al zijn er misschien nog andere tekens zoals de + of de # die ook speciale aandacht nodig hebben (weet ik niet zeker).

De File.toUri().toUrl() kwam ik ook diverse malen tegen, maar die heb je nodig in plaats van File.toUrl().

Anyway, ik kan weer even verder, bedankt! :)

edit: Ah ok, url.toURI().getPath() schrijf je, ik zal nog eens kijken.

[ Voor 9% gewijzigd door zwippie op 27-07-2005 17:42 ]

How much can you compute with the "ultimate laptop" with 1 kg of mass and 1 liter of volume? Answer: not more than 10^51 operations per second on not more than 10^32 bits.


  • Robtimus
  • Registratie: November 2002
  • Laatst online: 19:30

Robtimus

me Robtimus no like you

Class.getResource() returned null als de resource die je wilt hebben niet gevonden kan worden. Dit staat niet bij Class.getResource(), maar wel bij ClassLoader.getResource(). Altijd dus checken op null, anders krijg je vaker die nullpointer exception.

More than meets the eye
There is no I in TEAM... but there is ME
system specs


  • Nick_S
  • Registratie: Juni 2003
  • Laatst online: 22-04 03:55

Nick_S

++?????++ Out of Cheese Error

Misschien een kanttekening, maar hiermee hoeft het niet zo te zijn, dat je alle klassen uit een package te voorschijn haalt.

Een package kan bijvoorbeeld in twee directories zitten, waardoor het voor een classloader wel lijkt, dat het 1 package is.

Voorbeeld:

Directory C:\java en directorie C:\packages staan op je klasspath, met in de directorie c:\java de package com.nick.bla en daarin de klassen A, B, C, D en in de directory C:\package de package com.nick.bla en daarin de klassend E, F, G en H. Nu bestaat de package com.nick.bla uit 8 klassen, terwijl je met deze methoden er maar 4 vind. (Ik weet helaas ook niet, hoe je het wel zou moeten oplossen. Reflection zat ik aan te denken, maar dat werkt niet met packages)

Gewoon ter info en misschien helemaal niet boeiend, maar het is mogelijk.

'Nae King! Nae quin! Nae Laird! Nae master! We willna' be fooled agin!'

Pagina: 1