Programação Orientada a Objetos: Uma Abordagem com Java/Princípios da programação na linguagem Java/Ambiente Java

Ambiente Java editar

O ambiente de desenvolvimento de software Java, Java SDK (Software Development Kit — antigamente, denominado JDK), é formado essencialmente pelas classes fundamentais da linguagem Java e por um conjunto de aplicativos que permite, entre outras tarefas, realizar a compilação e a execução de programas escritos na linguagem Java. Não é um ambiente integrado de desenvolvimento, não oferecendo editores ou ambientes de programação visual. No entanto, são suas funcionalidades que permitem a operação desses ambientes.

O Java SDK contém um amplo conjunto de APIs que compõem o núcleo de funcionalidades da linguagem Java. Uma Application Programming Interface (API) é uma biblioteca formada por código pré-compilado, pronto para ser utilizado no desenvolvimento de suas aplicações.

Ferramentas do Java Development Kit editar

As ferramentas essenciais do ambiente de desenvolvimento de sofware Java são: o compilador Java, javac; o interpretador de aplicações Java, java; e o interpretador de applets Java, appletviewer.

Um programa fonte em Java pode ser desenvolvido usando qualquer editor que permita gravar textos sem caracteres de formatação. Um arquivo contendo código Java constitui uma unidade de compilação, podendo incluir comentários, declaração relacionadas a pacotes e pelo menos uma definição de classe ou interface.

O resultado dessa compilação, se o programa fonte estiver sem erros, será a criação de um arquivo com extensão .class contendo o bytecode que poderá ser executado em qualquer máquina virtual Java, disponível para diferentes sistemas operacionais.

Além das ferramentas essenciais, o Java SDK oferece os aplicativos de desenvolvimento javadoc, um gerador de documentação para programas Java; jar, um manipulador de arquivos comprimidos no formato Java Archive, que opera juntamente com extcheck, o verificador de arquivos nesse formato; jdb, um depurador de programas Java; javap, um disassembler de classes Java; e javah, um gerador de arquivos header para integração a código nativo em C.

Java oferece também aplicativos para o desenvolvimento e execução de aplicações Java em plataformas de objetos distribuídos. Há também ferramentas para permitir o desenvolvimento de aplicações distribuídas, incorporando também o conceito de assinaturas digitais, como keytool, que gerencia chaves e certificados; jarsigner, que gera e verifica assinaturas associadas a arquivos Java; e policytool, uma interface gráfica para gerenciar arquivos que determinam a política de segurança do ambiente de execução.

Geração de código portátil editar

Um dos grandes atrativos da plataforma tecnológica Java é a portabilidade do código gerado. Esta portabilidade é atingida através da utilização de bytecodes. Bytecode é um formato de código intermediário entre o código fonte, o texto que o programador consegue manipular, e o código de máquina, que o computador consegue executar.

Na plataforma Java, o bytecode é interpretado por uma máquina virtual Java. A portabilidade do código Java é obtida à medida que máquinas virtuais Java estão disponíveis para diferentes plataformas. Assim, o código Java que foi compilado em uma máquina pode ser executado em qualquer máquina virtual Java, independentemente de qual seja o sistema operacional ou o processador que executa o código.

A Máquina Virtual Java (JVM) é, além de um ambiente de execução independente de plataforma, uma máquina de computação abstrata. Programas escritos em Java e que utilizem as funcionalidades definidas pelas APIs dos pacotes da plataforma Java executam nessa máquina virtual. Uma das preocupações associadas a execuções nessas máquinas virtuais é oferecer uma arquitetura de segurança para prevenir que applets e aplicações distribuídas executem fora de seu ambiente seguro (sandbox) a não ser quando assim habilitados. Um framework de segurança é estabelecido através de funcionalidades dos pacotes java.security e seus subpacotes java.security.acl, java.security.cert, java.security.interfaces e java.security.spec.

A máquina virtual Java opera com o carregamento dinâmico de classes, ou seja, bytecodes são carregados pela máquina virtual Java à medida que são solicitados pela aplicação. Em uma aplicação operando localmente, o carregador de classes da máquina virtual procura por essas classes nos (sub-)diretórios especificados a partir da variável do sistema CLASSPATH. Se encontrada, a classe é carregada para a máquina virtual e a operação continua. Caso contrário, a exceção ClassNotFoundException é gerada. O carregamento do código de uma classe para a JVM é realizado pelo class loader da máquina virtual. O class loader, em si uma classe Java que provê essa funcionalidade, deve obedecer a uma política de segurança estabelecida para aquela máquina virtual. O estabelecimento de uma política de segurança deve obedecer a um modelo de segurança específico. No modelo de segurança estabelecido a partir do JDK 1.2 (JDK security specification), todo código sendo carregado para uma máquina virtual Java requer o estabelecimento de uma política de segurança, visando evitar que algum objeto realize operações não-autorizadas na máquina local. Com a inclusão do conceito de política de segurança, é possível estabelecer permissões diferenciadas para as aplicações. A política de segurança padrão é estabelecida em um arquivo do sistema, java.policy, localizado no diretório <java_home>/lib/security/. Cada usuário pode estabelecer adições a essa política através da criação de um arquivo particular de estabelecimento de política, .java.policy, em seu diretório home. Por exemplo, para permitir conexões soquete de qualquer máquina com origem no domínio unicamp.br a portas não-notáveis, o arquivo .java.policy deveria incluir

grant { 
permission java.net.SocketPermission "*.unicamp.br:1024-", "accept,connect"; 
};

A sintaxe para o arquivo de políticas (Policy files syntax) permite estabelecer domínios de permissão com base na origem do código ou na sua assinatura. A ferramenta policytool permite criar um arquivo de políticas através de uma interface gráfica. Para forçar a aplicação dessas políticas alternativas de segurança, um SecurityManager deve ser criado.

Applets, por default, utilizam um SecurityManager estabelecido pelo navegador em cujo contexto estão executando. Outras aplicações devem criar explicitamente esse objeto. Por exemplo, para criar um SecurityManager padrão para aplicações usando RMI (Remote Method Invocation), a seguinte linha de código deveria ser incluída antes de executar qualquer operação envolvendo classes remotas:

System.setSecurityManager(new RMISecurityManager());

Se o cliente RMI estiver em um applet, então não é necessário criar um SecurityManager, uma vez que o próprio navegador estabelece a política de segurança para applets remotos.

Desenvolvimento de aplicações editar

Aplicações Java são programas autônomos, cujo código gerado a partir de um programa fonte pode ser interpretado diretamente pela Máquina Virtual Java. Como tudo em Java está estruturado através de classes e objetos, para desenvolver uma aplicação é preciso desenvolver pelo menos uma classe que contenha um método denominado main. Assim, uma classe que vá estabelecer o ponto de partida para a execução de uma aplicação na JVM deve conter pelo menos esse método.

Esse exemplo clássico define uma aplicação que simplesmente envia uma string para a saída padrão, identificada pelo objeto público System.out:

public class Hello { 
    public static void main(String[] args) {
        System.out.println("Oi!"); 
        System.exit(0);
    }
}

Uma vez que o programa tenha sido salvo em um arquivo com extensão .java, é preciso compilá-lo. Para compilar um programa Java, a ferramenta oferecida pelo kit de desenvolvimento Java é o compilador Java, javac. Na forma mais básica de execução, o javac é invocado da linha de comando tendo por argumento o nome do arquivo com o código Java a ser compilado:

> javac Hello.java

A unidade de compilação é o arquivo com extensão .java; esse arquivo pode conter a definição de várias classes, mas apenas uma delas pode ser pública. A classe pública em um arquivo fonte define o nome desse arquivo, que obrigatoriamente deve ter o mesmo nome dessa classe. Para cada definição de classe na unidade de compilação, o compilador Java irá gerar um arquivo com bytecodes com a extensão .class, tendo como nome o próprio nome da classe. Uma vez que um programa Java tenha sido compilado e esteja pronto para ser executado, isto se dá através do comando java — o interpretador Java, que ativa a máquina virtual Java, carrega a classe especificada e ativa seu método main. Por exemplo, para interpretar o arquivo Hello.class contendo o bytecode correspondente ao código fonte do arquivo Hello.java, utiliza-se a linha de comando

> java Hello

Observe que a extensão .class não é incluída nessa linha de comando — se o for, uma mensagem de erro será gerada, pois para a máquina virtual Java o caráter ’.’ está associado à definição de uma hierarquia de pacotes.

Se a máquina virtual Java do interpretador não encontrar um método de nome main com a assinatura correta (public, static, void e com um argumento do tipo String[]) na classe especificada, uma exceção será gerada em tempo de execução:

Exception in thread "main" java.lang.NoSuchMethodError: main

Essa mensagem pode ser emitida pela ausência completa de um método main na classe ou por uma declaração incorreta para o método.

Deve se observar que ambientes integrados de desenvolvimento tornam o uso desses aplicativos transparentes para o desenvolvedor, acelerando bastante o processo de desenvolvimento.

Se um programa Java for desenvolvido como applet, ele não poderá ser executado diretamente através do interpretador Java mas sim através da ativação de uma página HTML. Para executar esse tipo de aplicação pode-se utilizar um navegador; porém, o ambiente de desenvolvimento Java oferece a aplicação appletviewer que extrai da página HTML apenas o espaço de exibição do applet e permite controlar sua execução através de comandos em sua interface gráfica.