Classpath

olá pessoal,

Gostaria que me explicasse a seguinte questao:

Dado o classpath padrão:

/foo

E esta estrutura de diretórios:

foo | test | xcom |-- A.class |-- B.java

E estes dois arquivos:

[code]package xcom;
public class A { }

package xcom;
public class B extends A{ }[/code]

Qual opção permiteque B.java compile? (Marque todas as corretas)

A. Definir o diretório atual como xcom e depois chamar
javac B.java

B. Definir o diretório atual como xcom e depois chamar
javac -classpath . B.java

C. Definir o diretório atual como test e depois chamar
javac -classpath . xcom/B.java

D. Definir o diretório atual como test e depois chamar
javac -classpath xcom B.java

E. Definir o diretório atual como test e depois chamar
javac -classpath xcom:. B.java

A resposta é a letra C.

Letra A: nao procura a A.class necessário para B compilar. ERRADA
Letra B: diretorio atual é xcom, o . é usado para procurar .class no diretório atual(xcom) entao pq esse item nao é correto ?
Letra C: diretório atual é test, como ele vai encontrar .class no diretório atual(test) ?

Letra D: ERRADA
Letra E: ERRADA

Na explicacao, diz que se o diretório atual for xcom, nao vai encontrar A.class, nao entendi por que ? pois tem o . para procurar pelo .class no diretorio atual.

Obrigado

Caro Cadu,

Acredito que seja porque:

B) Esta errada porque a classe A é do pacote xcom, e o java deve procurala pelo caminho completo e não só pelo nome dela, então ele deve fazer xcom.A.class e não A.class.

C) Mesma explicação que a anterior. Como dentro do diretório test esta uma pasta que se chama xcom, ele acha a classe.

Se eu estiver errado me corrijam, por favor.

Errado, o compiler só procura no diretório atual, para tanto é necessário indicar que a classe em questão está no diretório xcom

Thiago,

Mas se ela faz parte de um pacote, o no “diretório atual” praticamente nunca vai existir uma classe sempre pacote, ele procura o nome da classe totalmente qualificado.

Eu até testei esse código porque estava nessa dúvida e acabei chegando nessa conclusão.

Então, o javac vai procurar os fontes que estão no CLASSPATH, mas depois vai descendo os diretórios de acordo com o pacote informado até encontrar o código-fonte.

B está errado porque, estando dentro de “xcom”, não dá pra compilar a classe de pacote “xcom” (a menos que houvesse uma outra pasta “xcom” dentro de “xcom”). Daria pra compilar se a classe java estivesse no pacote raiz. Estaria certo se você estivesse dentro do pacote xcom e digitasse:

javac -classpath B.java

ou seja, o classpath fica um nível acima, no diretório raiz.

C está certo porque o CLASSPATH está no nível do pacote raiz.

Nossa,

Isto está complicado.

Leonardo, o que vc se refere como diretorio raiz é quando ele diz que o diretório atual é test(entao o raiz é test), quando o diretório atual é xcom(entao o raiz é xcom), é isso ??

Valeu.

Cara, é o seguinte:

 Resposta correta: 
           C. Definir o diretório atual como test e depois chamar javac -classpath . xcom/B.java


 Quando você cria uma classe por exemplo:

  [code]
       package nomedopacote;
       public class NomeDaClasse() { }
  [/code]

  Você tem que colocar esse arquivo "NomeDaClasse.java" dentro de um diretório chamado "nomedopacote", ok? Porém, este diretório pode estar dentro de outro diretório, por exemplo:
      
     C:\nomedopacote\NomeDaClasse.java  -> Correto.
     C:\algumdiretorio\nomedopacote\NomeDaClasse.java -> Correto
     C:\algumdiretorio\outrodiretorio\nomedopacote\NomeDaClasse.java -> Correto

A regra para compilar e executar um arquivo em Java, é você sempre chamar a classe FORA DO SEU PACOTE, aonde o compilador possa enxergar tanto o pacote (pasta) quanto o arquivo. Você não pode tentar compilar dentro do diretório “nomedopacote”, por que esta pasta estaria invisível para o compilador; portanto, você DEVE COMPILAR E EXECUTAR DE FORA DA PASTA.

 (Aquele "." (javac -cp [b].[/b] xcom/B.java) significa que o compilador deve considerar o diretório do arquivo Java).

Formas de compilação correta para o exemplo acima:

 Posicionar no diretório "C:\" e executar "javac -cp . nomedopacote/NomeDaClasse.java" -> OK.
 Se tentar fazer isso dentro do diretório "nomedopacote" dará erro, por que o diretório não está visível para o compilador...

 Posicionar no diretório "C:\algumdiretorio\" e executar "javac -cp . nomedopacote/NomeDaClasse.java" -> OK.
 Se tentar fazer isso dentro do diretório "C:\" dará erro, por que o diretório não está visível para o compilador...

 Posicionar no diretório "C:\algumdiretorio\outrodiretorio\" e executar "javac -cp . nomedopacote/NomeDaClasse.java" -> OK.
 Se tentar fazer isso dentro do diretório "C:\algumdiretorio" dará erro, por que o diretório não está visível para o compilador...

Leia o capítulo 10 do livro SCJP 5 de Kathy Sierra e Bert Bates que isso é explicado de uma forma mais abrangente !

Abraço,