Salve a tutti, spero di aver scelto la sezione corretta per farvi questa domanda.
Ho un problema con un web service che legge alcune informazioni da un file xml e le stampa. Vi mostro il codice e alla fine vi spiego quale penso sia il problema, nella speranza che qualcuno mi aiuti a comprendere cosa sto sbagliando.

Questo è un frammento del file xml (per farvi comprendere la maniera in cui è strutturato:
codice:
<?xml version="1.0" encoding="UTF-8"?>
 <prodotti>
 	<prodotto id="01">
  		<nome>Navel</nome>
  		<categoria>Arance</categoria>
  		<pezzatura>
  			<confezione tipo = "cassa" peso = "15" prezzo= "15"/>
  			<confezione tipo = "sacchetto" peso = "3" prezzo="6"/>
  			<confezione tipo = "plateau" peso = "10" prezzo="12"/>
  		</pezzatura>
   	</prodotto>
	<prodotto id="03">
  		<nome>Limoni_di_Sorrento</nome>
  		<categoria>Limoni</categoria>
  		<pezzatura>
  			<confezione tipo = "sacchetto" peso = "3" prezzo="7.50"/>
  			<confezione tipo = "plateau" peso = "7" prezzo="14"/>
  		</pezzatura>
  	</prodotto>
</prodotti>
Per prima cosa ho creato due bean per gestire il tipo di oggetti che dovranno essere estrapolati dal file xml.

Prodotto.java:
codice:
public class Prodotto { 	 	
 	private int id;
 	private String nome;
 	private String categoria;
 	private Confezione[]
 	confezioni;
 	 	
 	public int getID() {
 	 	return id;
 	}
 	public void setID(int i) {
 	 	id = i;
 	}

 	public String getNome() {
 	 	return nome;
 	}
 	public void setNome(String n) {
 	 	nome = n;
 	}

 	public String getCategoria() {
 	 	return categoria;
 	}
 	public void setCategoria(String c) {
	 	categoria = c;
 	}

 	public Confezione[] getConfezione() {
	 	return confezioni;
 	}
 	public void setConfezioni(Confezione[] conf) {
	 	confezioni = conf;
 	}
 }
Confezione.java:
codice:
public class Confezione {

	String tipo;
	int peso;
	float prezzo;
	
	public String getTipo() {
		return tipo;
	}
	public void setTipo(String t) {
		tipo = t;
	}
	
	public int getPeso() {
		return peso;
	}
	public void setPeso(int p) {
		peso = p;
	}
	
	public float getPrezzo() {
		return prezzo;
	}
	public void setPrezzo(float pr) {
		prezzo = pr;
	}
	
}
A questo punto ho creato una classe che eseguisse concretamente le operazioni:

codice:
public class ProdottoDB {

	Prodotto[] prodotti;
	Confezione[] confezioni;

	public ProdottoDB(Document doc) throws Exception {
		NodeList list = doc.getElementsByTagName("prodotto");
		int length = list.getLength();
		prodotti = new Prodotto[length];
		Prodotto p = null;

		for (int i = 0; i < length; i++) {
			Element elem = (Element)list.item(i);

			p = new Prodotto();
			p.setID(Integer.parseInt(elem.getAttribute("id")));
			p.setNome(getValue(elem, "nome"));
			p.setCategoria(getValue(elem, "categoria"));

			
			NodeList listConf = elem.getElementsByTagName("confezione");
			confezioni = new Confezione[listConf.getLength()];
			
			for (int j = 0; j < listConf.getLength(); j++) {
				Element elemConf = (Element)listConf.item(j);

				Confezione c = new Confezione();
				c.setTipo(elemConf.getAttribute("tipo"));
				c.setPrezzo(Float.parseFloat(elemConf.getAttribute("prezzo")));
				c.setPeso(Integer.parseInt(elemConf.getAttribute("peso")));

				confezioni[j] = c;
				System.out.println("confezioni");
			}

			p.setConfezioni(confezioni);
			prodotti[i] = p;
		}
	}

	public Prodotto[] getProdotti() {
		return prodotti;
	}

	public float getPrezzo(int id, String categoria) {
		for (int i = 0; i < prodotti.length; i++) {
			if (id == prodotti[i].getID()) {
				Confezione[] c = prodotti[i].getConfezione();
				for (int j=0; j<c.length; j++) {
					if (categoria.equals(c[j].getTipo()))
						return c[j].getPrezzo();
				}
			}
		}
		return -1;
	}

	/*
	 * Legge il valore di un nodo Element 
	 */
	private String getValue(Element elem, String name) {
		NodeList l = elem.getElementsByTagName(name);
		if (l == null || l.getLength() == 0)
			return null;
		elem = (Element)l.item(0);
		return elem.getFirstChild().getNodeValue();
	}
}
Lato server il codice dovrebbe essere il seguente:
codice:
public class TerramicaService {

	private static String file = "Terramica/ProdottiTerramica.xml";

	public static Prodotto[] elenco() throws Exception {

		MessageContext msgCtx =  MessageContext.getCurrentMessageContext(); 
		ServletContext ctx = (ServletContext) msgCtx.getProperty(HTTPConstants.MC_HTTP_SERVLETCONTEXT);
		String rpath = ctx.getRealPath(file);

		BufferedInputStream in = new BufferedInputStream(new FileInputStream(rpath));
		DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
		factory.setNamespaceAware(true);
		DocumentBuilder builder = factory.newDocumentBuilder();
		Document doc = builder.parse(in);

		ProdottoDB db = new ProdottoDB(doc);
		Prodotto[] prod = db.getProdotti();
		return prod;
	}

	public float prezzo(int id, String tipo) throws Exception {
		MessageContext msgCtx =  MessageContext.getCurrentMessageContext(); 
		ServletContext ctx = (ServletContext) msgCtx.getProperty(HTTPConstants.MC_HTTP_SERVLETCONTEXT);
		String rpath = ctx.getRealPath(file);

		BufferedInputStream in = new BufferedInputStream(new FileInputStream(rpath));
		DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
		factory.setNamespaceAware(true);
		DocumentBuilder builder = factory.newDocumentBuilder();
		Document doc = builder.parse(in);

		ProdottoDB db = new ProdottoDB(doc);
		float prezzo = db.getPrezzo(id, tipo);
		return prezzo;
	}
}
Mentre il client è questo:
codice:
public class TerramicaClient {

	public static void main(String[] args) throws Exception {

		BufferedReader console = new BufferedReader(new InputStreamReader(System.in));

		System.out.println("Scegliere l'operazione da eseguire: ");

		System.out.println("1 - Elenco prodotti: "); 
		System.out.println("2 - Ricerca prezzo: ");
		int sel = Integer.parseInt(console.readLine());
		//
		//System.out.println("I prodotti non sono disponibili");

		if (sel==1) {
			ArrayList<Prodotto> prods = elenca();
			for (Prodotto p : prods) {
				System.out.println("ID: " + p.getID());
				System.out.println("Categoria: " + p.getCategoria());
				System.out.println("Nome: " + p.getNome());

				Confezione[] confs = p.getConfezione();
				for (int i=0; i<confs.length; i++) {
					System.out.println("Tipo confezione: " + confs[i].getTipo());
					System.out.println("Peso confezione: " + confs[i].getPeso());
					System.out.println("Prezzo confezione: " + confs[i].getPrezzo());
				}
			}
		}
		
		if (sel==2) {
			System.out.println("ID?: ");
			int id = Integer.parseInt(console.readLine());
			System.out.println("Tipo?: ");
			String tipo = console.readLine();
			
			float res = prezzo(id, tipo);
			
			System.out.println("Prezzo: " + res);
		}
	}

	private static ArrayList<Prodotto> elenca() throws Exception {

		ArrayList<Prodotto> prs = new ArrayList<Prodotto>();

		ServiceClient serviceClient = new ServiceClient();

		OMFactory fac = OMAbstractFactory.getSOAP12Factory();
		OMNamespace omNs = fac.createOMNamespace("http://www.terramica.it", "tns");
		OMElement method = fac.createOMElement("elenco", omNs);

		Options options = serviceClient.getOptions();
		EndpointReference targetEPR = new EndpointReference("http://localhost:8081/axis2/services/TerramicaService");
		options.setSoapVersionURI(Constants.URI_SOAP12_ENV);
		options.setTo(targetEPR); 

		// invocazione del servizio utilizzando la MEP in-out
		OMElement result = serviceClient.sendReceive(method);

		// recupera il risultato
		Iterator values = result.getChildrenWithName(new QName("http://service.terramica.it", "return"));
		while (values.hasNext()) {
			OMElement omElement = (OMElement) values.next();
			Prodotto prod = (Prodotto) BeanUtil.deserialize(Prodotto.class, omElement, new DefaultObjectSupplier(), "prodotto");
			prs.add(prod);
		}
		return prs;
	}

	private static float prezzo(int id, String categoria) throws Exception {

		ServiceClient serviceClient = new ServiceClient();

		OMFactory fac = OMAbstractFactory.getSOAP12Factory();
		OMNamespace omNs = fac.createOMNamespace("http://service.terramica.it", "tns");

		OMElement method = fac.createOMElement("prezzo", omNs);
		OMElement arg0 = fac.createOMElement("id", omNs);
		arg0.addChild(fac.createOMText(arg0, String.valueOf(id)));
		method.addChild(arg0);
		OMElement arg1 = fac.createOMElement("tipo", omNs);
		arg1.addChild(fac.createOMText(arg1, categoria));
		method.addChild(arg1);

		Options options = serviceClient.getOptions();
		EndpointReference targetEPR = new EndpointReference("http://localhost:8081/axis2/services/TerramicaService");
		options.setSoapVersionURI(Constants.URI_SOAP12_ENV);
		options.setTo(targetEPR); 

		// invocazione del servizio utilizzando la MEP in-out
		OMElement result = serviceClient.sendReceive(method);

		// recupera il risultato
		float response = Float.parseFloat(result.getFirstElement().getText());

		return response;
	}
}
Purtroppo il risultato non è quello corretto anche se eclipse non segnala errori nel codice. Il messaggio che compare è il seguente:
codice:
ID: 1
Categoria: Arance
Nome: Navel
Exception in thread "main" 
java.lang.NullPointerException
	at it.terramica.client.TerramicaClient.main(TerramicaClient.java:46)
Facendo un po' di debug quello che mi sembra di capire è che per qualche motivo gli oggetti di tipo confezione non vengano salvati nella struttura dati corrispondente. Tramite TCPMon però ho verificato che il messaggio di risposta contiene tutti i dati necessari. A questo punto mi sono bloccato perchè non riesco a capire come risolvere la situazione... spero che qualcuno possa darmi una mano a capire dov'è l'errore!