O que é um caminho de classe e como faço para defini-lo?

324

Eu estava apenas lendo esta linha:

A primeira coisa que o método format () faz é carregar um modelo Velocity do caminho de classe chamado output.vm

Por favor, explique o que se entende por caminho de classe neste contexto e como devo definir o caminho de classe.

Blankman
fonte

Respostas:

530

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.jarem seu caminho de classe. A VM procurará a org/javaguy/coolframeworkpeça dentro do arquivo jar e encontrará sua classe.

Portanto, os caminhos da classe contêm:

  • Arquivos JAR e
  • Caminhos para o topo das hierarquias de pacotes.

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 -cpparâ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 .shou .batque calcula o caminho de classe e o passa para Java por meio do -cpparâ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).

Bokmann
fonte
12
Outro blog bem explicado sobre O que é PATH e CLASSPATH em Java - Path vs ClassPath
KNU
Em python, há uma pasta chamada Lib, na qual você pode armazenar qualquer módulo para usar a qualquer momento com uma simples declaração de importação. Isso é diferente de definir a variável de ambiente CLASSPATH para um diretório para pacotes java de terceiros? Mesmo que fosse global, não haveria necessidade de alterar a variável, além de adicionar mais pacotes.
21716 Josie Thompson
Boa resposta, mas para os manequins aqui: Por que você não precisa usar o comando -cp para cada nova classe que criar? Isso certamente é resolvido automaticamente pelo seu sistema, certo? Mas como? Às vezes, encontro um problema em que "algo" não pode ser encontrado no meu caminho de classe - acho que é porque não o adicionei ao cp, mas por que esse erro ocorre apenas às vezes em vez de sempre? Pergunto isso porque, para ser honesto, eu não nunca manualmente incluir qualquer coisa com o comando cp e não saberia o que fazer com um erro como esse
Vic Torious
2
@Vic O caminho de classe precisa conter o diretório acima da hierarquia de diretórios correspondente ao nome do pacote. Portanto, se eu tiver 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.hotfwno 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.
precisa saber é
@Vic Para um exemplo e uma explicação mais concreta, consulte Mastering the Java CLASSPATH (por excelente comentário de KNU )
Tjalling
67

Pense nisso como a resposta do Java para a variável de ambiente PATH - os sistemas operacionais pesquisam EXEs no PATH, o Java pesquisa classes e pacotes no caminho da classe.

Stephen C
fonte
13

O caminho da classe é o caminho no qual a Java Virtual Machine procura classes, pacotes e recursos definidos pelo usuário nos programas Java.

Nesse contexto, o format()método carrega um arquivo de modelo desse caminho.

Desintegr
fonte
5

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.

Romain
fonte
2

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

lft93ryt
fonte
1
Embora esses comandos podem ser úteis para trabalhar com variáveis de ambiente, isso não responder à pergunta
Hulk
1

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.

Bimalendu nath
fonte
1

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
Unnati Solanki
fonte
0

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.


fonte
0

Para usuários do Linux, e para resumir e adicionar o que outros disseram aqui, você deve saber o seguinte:

  1. $ 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).

  2. 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.

  3. 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.

  4. 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

Adam Winter
fonte