Respostas:
Ao programar em Java, você disponibiliza outras classes para a classe que está escrevendo, colocando algo assim na parte superior do arquivo de origem:
import org.javaguy.coolframework.MyClass;
Ou às vezes você 'importa em massa' coisas dizendo:
import org.javaguy.coolframework.*;
Então, mais tarde no seu programa, quando você diz:
MyClass mine = new MyClass();
A Java Virtual Machine saberá onde encontrar sua classe compilada.
Seria impraticável fazer com que a VM visse todas as pastas da sua máquina, portanto, você deve fornecer à VM uma lista de locais a procurar. Isso é feito colocando os arquivos de pasta e jar em seu caminho de classe.
Antes de falarmos sobre como o caminho de classe está definido, vamos falar sobre arquivos .class, pacotes e arquivos .jar.
Primeiro, vamos supor que MyClass é algo que você criou como parte do seu projeto, e está em um diretório no seu projeto chamado output
. O arquivo .class estaria em output/org/javaguy/coolframework/MyClass.class
(junto com todos os outros arquivos desse pacote). Para chegar a esse arquivo, seu caminho precisaria simplesmente conter a pasta 'output', não toda a estrutura do pacote, pois sua declaração de importação fornece todas essas informações à VM.
Agora vamos supor que você agrupe o CoolFramework em um arquivo .jar e coloque o CoolFramework.jar em um diretório lib em seu projeto. Agora você precisaria colocar lib/CoolFramework.jar
em seu caminho de classe. A VM procurará a org/javaguy/coolframework
peça dentro do arquivo jar e encontrará sua classe.
Portanto, os caminhos da classe contêm:
Como você define seu caminho de classe?
A primeira maneira que todos parecem aprender é com variáveis de ambiente. Em uma máquina unix, você pode dizer algo como:
export CLASSPATH=/home/myaccount/myproject/lib/CoolFramework.jar:/home/myaccount/myproject/output/
Em uma máquina Windows, é necessário acessar as configurações do ambiente e adicionar ou modificar o valor que já existe.
A segunda maneira é usar o -cp
parâmetro ao iniciar o Java, assim:
java -cp "/home/myaccount/myproject/lib/CoolFramework.jar:/home/myaccount/myproject/output/" MyMainClass
Uma variante disso é a terceira maneira, geralmente feita com um arquivo .sh
ou .bat
que calcula o caminho de classe e o passa para Java por meio do -cp
parâmetro
Existe uma "pegadinha" com todas as opções acima. Na maioria dos sistemas (Linux, Mac OS, UNIX, etc), o caractere de dois pontos (':') é o separador de caminho de classe. No windowsm, o separador é o ponto e vírgula (';')
Então, qual é a melhor maneira de fazer isso?
Definir coisas globalmente através de variáveis de ambiente é ruim, geralmente pelos mesmos tipos de razões pelas quais variáveis globais são ruins. Você altera a variável de ambiente CLASSPATH para que um programa funcione e acaba quebrando outro programa.
O -cp é o caminho a percorrer. Geralmente, asseguro-me de que minha variável de ambiente CLASSPATH seja uma string vazia onde desenvolvo, sempre que possível, para evitar problemas globais no caminho de classe (algumas ferramentas não ficam felizes quando o caminho de classe global está vazio - conheço dois mega-mil comuns servidores J2EE e Java licenciados em dólares que têm esse tipo de problema com suas ferramentas de linha de comando).
org.javaguy.coolfw
, com a estrutura de diretórios correspondente /path/to/org/javaguy/coolfw/
, o caminho de classe precisará conter /path/to/
. Se eu adicionar um novo pacote org.javaguy.hotfw
no mesmo projeto, a classe resultante (geralmente) termina em /path/to/org/javaguy/hotfw/
. Isso requer que o caminho da classe contenha /path/to/
, o que já existe. Portanto, o novo pacote (e as classes nele contidas) não exigem novas adições ao caminho de classe.
O caminho de classe nesse contexto é exatamente o que é no contexto geral: em qualquer lugar que a VM sabe que pode encontrar classes a serem carregadas e recursos também (como output.vm no seu caso).
Eu entenderia que o Velocity espera encontrar um arquivo chamado output.vm em qualquer lugar em "no package". Pode ser uma pasta JAR, regular, ... A raiz de qualquer um dos locais no caminho de classe do aplicativo.
Configurando a variável de sistema CLASSPATH
Para exibir a variável CLASSPATH atual, use estes comandos no Windows e UNIX (shell Bourne): No Windows: C:\> set CLASSPATH
No UNIX: % echo $CLASSPATH
Para excluir o conteúdo atual da variável CLASSPATH, use estes comandos: No Windows: C:\> set CLASSPATH=
No UNIX: % unset CLASSPATH; export CLASSPATH
Para definir a variável CLASSPATH, use estes comandos (por exemplo): No Windows: C:\> set CLASSPATH=C:\users\george\java\classes
No UNIX: % CLASSPATH=/home/george/java/classes; export CLASSPATH
Classpath é uma variável de ambiente do sistema. A configuração dessa variável é usada para fornecer a raiz de qualquer hierarquia de pacotes ao compilador java.
CLASSPATH é uma variável de ambiente (isto é, variáveis globais do sistema operacional disponível para todos os processos) necessárias para que o compilador e o tempo de execução Java localizem os pacotes Java usados em um programa Java. (Por que não chamar PACKAGEPATH?) Isso é semelhante a outra variável de ambiente PATH, usada pelo shell do CMD para encontrar os programas executáveis.
O CLASSPATH pode ser definido de uma das seguintes maneiras:
CLASSPATH can be set permanently in the environment: In Windows, choose control panel ⇒ System ⇒ Advanced ⇒ Environment Variables ⇒ choose "System Variables" (for all the users) or "User Variables" (only the currently login user) ⇒ choose "Edit" (if CLASSPATH already exists) or "New" ⇒ Enter "CLASSPATH" as the variable name ⇒ Enter the required directories and JAR files (separated by semicolons) as the value (e.g., ".;c:\javaproject\classes;d:\tomcat\lib\servlet-api.jar"). Take note that you need to include the current working directory (denoted by '.') in the CLASSPATH.
To check the current setting of the CLASSPATH, issue the following command:
> SET CLASSPATH
CLASSPATH can be set temporarily for that particular CMD shell session by issuing the following command:
> SET CLASSPATH=.;c:\javaproject\classes;d:\tomcat\lib\servlet-api.jar
Instead of using the CLASSPATH environment variable, you can also use the command-line option -classpath or -cp of the javac and java commands, for example,
> java –classpath c:\javaproject\classes com.abc.project1.subproject2.MyClass3
O membro estático de uma classe pode ser chamado diretamente sem criar instância do objeto. Como o método principal é estático, o Java virtual Machine pode chamá-lo sem criar nenhuma instância de uma classe que contenha o método principal, que é o ponto inicial do programa.
Para usuários do Linux, e para resumir e adicionar o que outros disseram aqui, você deve saber o seguinte:
$ CLASSPATH é o que o Java usa para procurar em vários diretórios para encontrar todas as classes diferentes necessárias para o seu script (a menos que você diga explicitamente o contrário com a substituição -cp). O uso de -cp exige que você acompanhe todos os diretórios manualmente e copie e cole essa linha sempre que executar o programa (IMO não preferível).
O caractere de dois pontos (":") separa os diferentes diretórios. Existe apenas um $ CLASSPATH e ele possui todos os diretórios. Portanto, quando você executa "export CLASSPATH = ....", deseja incluir o valor atual "$ CLASSPATH" para anexá-lo. Por exemplo:
export CLASSPATH=.
export CLASSPATH=$CLASSPATH:/usr/share/java/mysql-connector-java-5.1.12.jar
Na primeira linha acima, você inicia o CLASSPATH com apenas um simples 'ponto', que é o caminho para o seu diretório de trabalho atual. Com isso, sempre que você executa java, ele procura classes no diretório de trabalho atual (aquele em que você está). Na segunda linha acima, $ CLASSPATH pega o valor que você inseriu anteriormente (.) E anexa o caminho a um dirver mysql. Agora, o java procurará o driver E as suas classes.
echo $CLASSPATH
é super útil, e o que ele retorna deve ler como uma lista separada por dois pontos de todos os diretórios e arquivos .jar, você deseja que o java procure as classes necessárias.
O Tomcat não usa CLASSPATH. Leia o que fazer sobre isso aqui: https://tomcat.apache.org/tomcat-8.0-doc/class-loader-howto.html