• Nenhum resultado encontrado

GitHub: Um Estudo Exploratório

3.4 Apoio Ferramental

Como descrito anteriormente todos os passos do processo de mineração puderam ser total ou parcialmente automatizados. As ferramentas citadas anteriormente, apoiando cada um dos passos, compõem a suite de ferramentas que chamamos ExMinerSuite, ex- tensão da ferramenta ExMiner utilizada em um estudo anterior, e que foi desenvolvida para apoiar o presente estudo. A Figura abaixo apresenta as principais ferramentas que compõem esta suite.

Figura 12: Principais ferramentas que compõem a suite ExMinerSuite.

cumentação Javadoc nas versões 5, 6, 7 e 8 das edições SE e EE do Java, em busca de classes de exceção. Recebe como entrada a URL da página inicial da documentação da edição e versão do Java desejadas, e a partir daí, com o auxílio da biblioteca jsoup, visita cada uma das páginas. O Quadro 3.1 apresenta o pseudocódigo de como a classificação dos tipos excepcionais Java foi realizada. Ao final da execução, o resultado será uma base de dados populada com todas as classes de exceções do Java.

A ferramenta MavenArtifactFinder é responsável por automatizar o processo de localização e download dos artefatos adequados, a partir do repositório Maven. Recebe como entrada o nome e versão do artefato desejado, seguindo o padrão de nomenclatura de artefatos Maven. Fazendo uso do serviço de pesquisa do Maven, os artefatos são trans- feridos. Para cada artefato desejado, uma requisição ao serviço de pesquisa do Maven é realizada. O serviço retorna uma lista contendo todos os artefatos que atendem aos critérios da busca. A lista resultante é percorrida em busca do primeiro artefato que dis- ponibilizar além do artefato desejado, o arquivo com a extensão .pom, e um artefato com o código fonte da biblioteca.

ExceptionFinder é a ferramenta responsável por automatizar o processo de iden-

tificação das classes de exceção definidas por cada biblioteca alvo. Da mesma forma que a MavenArtifactFinder, recebe como entrada o nome e versão do artefato desejado, seguindo o padrão de nomenclatura de artefatos Maven. A execução inicia invocando o MavenArtifactFinder para recuperar o artefato de código fonte e o arquivo .pom de cada biblioteca. Com o auxílio da API Apache Maven Invoker, todas as dependências definidas no arquivo .pom são resolvidas. Em seguida, o arquivo contendo o código fonte é des-

Quadro 3.1 Algoritmo para Identificar o Tipo das Exceções Java.

Entrada: Página inicial da edição e versão desejada, contendo a listagem de todas as classes documentadas;

1. Percorre a página e armazena temporariamente todos os links da página inicial; 2. Para cada link, executa as seguintes ações:

2.1. Carrega a página do link;

2.2. Percorre a página em busca de uma seção que defina a hierarquia da classe; 2.3. Ao localizar uma seção de hierarquia, extrai cada um dos elementos,

armazenando-os em uma coleção temporária;

2.4. Verifica se existe a classe java.lang.Throwable na coleção de classes da hie- rarquia;

2.5. Se existir a classe java.lang.Throwable, caracteriza-se uma classe de exceção, portanto executa:

2.5.1. Verifica se existe a classe java.lang.Error na coleção de classes da hie- rarquia;

2.5.1.1. Se existir, classifica a exceção analisada como uma subclasse desta; 2.5.2. Verifica se existe a classe java.lang.RuntimeException na coleção de

classes da hierarquia;

2.5.2.1. Se existir, classifica a exceção analisada como uma subclasse desta; 3. Retorna todas as exceções Java encontradas na documentação e com suas respectivas

super classes.

compactado e com o auxílio do framework JavaParser, todos os arquivo com a extensão .java são percorridos em busca das classes de exceção, isto é, classes que herdam direta ou indiretamente da classe java.lang.Throwable. Uma vez localizada uma classe de ex- ceção, seu supertipo é extraído e armazenado juntamente com o nome da classe na base de dados de exceções.

A quarta ferramenta, chamada de DocExceptionInterfaceFinder, é responsável por realizar a identificação de toda documentação excepcional das bibliotecas alvo. Da mesma forma que as duas ferramentas apresentadas anteriormente, também recebe o nome e versão do artefato desejado, seguindo o padrão de nomenclatura de artefatos Maven. A execução invoca o MavenArtifactFinder para recuperar o artefato de código fonte de cada biblioteca e em seguida o descompacta. No passo seguinte, arquivos com a extensão .java são percorridos com o auxílio do framework JavaParser. À medida que os arquivos são percorridos, informações como nome da classe e do método, assinatura e documentação JavaDoc, são coletadas e persistidas na base de dados. Com o auxílio de expressões regula-

res, quando localizado um bloco de documentação JavaDoc, a documentação excepcional também é extraída.

3.5

Dataset utilizado

O conjunto de dados utilizado em nossas análises conta com mais de 66 mil stack traces. Destas, estamos interessados apenas naquelas que lançam exceções de tempo de execução (do inglês, runtime exceptions). Observamos que a grande maioria das stack tra- ces relacionadas à exceções runtime estão associadas à exceções da API Java. A Tabela 2 apresenta as dez exceções runtime mais recorrentes nas stack traces, juntamente com a quantidade de repositórios e stack traces diferentes onde foram identificadas.

Tabela 2: Top 10 exceções mais recorrentes das stack traces, considerando apenas exceções runtime.

Exceção #Repo. #Stacks

java.lang.NullPointerException 1269 10431 java.lang.IllegalArgumentException 517 1494 java.lang.ClassCastException 320 747 java.lang.RuntimeException 317 2187 java.lang.IllegalStateException 297 11130 java.lang.ArrayIndexOutOfBoundsException 273 818 java.util.ConcurrentModificationException 152 370 java.lang.IndexOutOfBoundsException 136 2308 java.lang.NumberFormatException 108 216 java.lang.UnsupportedOperationException 107 192

Observamos que muitas das exceções identificadas fazem parte do conjunto de exce- ções descritas na especificação Java19 como sendo lançadas em decorrência de terminação

abrupta durante a avaliação de alguma expressão. Dessa forma, tais exceções não precisam ser lançadas explicitamente em algum código feito pelos desenvolvedores. Ao longo deste trabalho nos referenciaremos a esse conjunto como exceções lançadas implicitamente. Es- sas exceções estão listadas na Tabela 3.

No contexto deste trabalho, julgamos que as exceções lançadas implicitamente po- dem não ser de interesse da maioria dos desenvolvedores de software que utilizam as bibliotecas alvo de nossa investigação. Por exemplo, a tentativa de acesso à uma ope- ração ou atributo de um objeto que não tenha sido devidamente instanciado, resul- tará em uma exceção de acesso à referência nula, ou mais precisamente na exceção

Tabela 3: Exceções lançadas em caso de terminação abrupta durante avaliação de uma expressão.

Exceções Lançadas Implicitamente pela JVM java.lang.ArithmeticException java.lang.ArrayIndexOutOfBoundsException java.lang.ArrayStoreException java.lang.ClassCastException java.lang.NegativeArraySizeException java.lang.NullPointerException java.lang.OutOfMemoryError

java.lang.NullPointerException. No entanto, entendemos também que para os in- tegrantes das equipes mantenedoras das respectivas bibliotecas, tais exceções podem ser muito valiosas, uma vez que isso pode indicar a existências de um erro de codificação da biblioteca.

Diante deste cenário, optamos por focar no primeiro grupo de desenvolvedores, para o qual vislumbramos que seja mais interessante identificar exceções lançadas não im- plicitamente. Diante desta decisão, restringimos a análise para desconsiderar as exceções lançadas implicitamente. A Tabela 4 apresenta as dez exceções runtime que não são lança- das implicitamente, mais recorrentes nas stack traces de nossa base de dados, juntamente com a quantidade de repositórios e stack traces diferentes onde foram identificadas. Já a Tabela 5 lista as dez exceções runtime mais frequentes, que não são da API Java.

Tabela 4: Top 10 exceções mais recorrentes das stack traces, considerando apenas exceções runtime, não lançadas implicitamente.

Exceção #Repo. #Stacks

java.lang.IllegalArgumentException 517 1494 java.lang.RuntimeException 317 2187 java.lang.IllegalStateException 297 11130 java.util.ConcurrentModificationException 152 370 java.lang.IndexOutOfBoundsException 136 2308 java.lang.NumberFormatException 108 216 java.lang.UnsupportedOperationException 107 192 java.lang.StringIndexOutOfBoundsException 107 158 java.util.NoSuchElementException 72 141 java.lang.SecurityException 26 159

Quanto aos métodos que geraram as exceções presentes nas stacks, observamos que a grande maioria também eram oriundos da API Java. Na Tabela 6, que exibe os dez métodos que mais geraram exceções runtime, é possível observar que apenas o décimo método mais frequente não é da API Java. Na Tabela 7 destacamos apenas os métodos

Tabela 5: Top 10 exceções não Java, mais recorrentes das stack traces, considerando apenas exceções runtime.

Exceção #Repo. #Stacks

org.apache.commons.lang.UnhandledException 19 43 com.mongodb.MongoException 13 57 org.eclipse.core.runtime.AssertionFailedException 13 17 org.springframework.beans.factory.NoSuchBean- DefinitionException 12 35 org.json.JSONException 12 28 org.elasticsearch.index.mapper.MapperParsing- Exception 9 36 org.hibernate.exception.GenericJDBCException 9 15 org.mozilla.javascript.EvaluatorException 8 14 org.yaml.snakeyaml.error.YAMLException 7 24 org.hibernate.exception.ConstraintViolationException 7 17

que não integram a API java.

Tabela 6: Top 10 métodos presentes na base do GitHub, que mais geraram exceções runtime, desconsiderando exceções implícitas do Java.

Método #Repo. #Stacks

java.lang.NumberFormatException.forInputString 49 64 java.util.ArrayList.rangeCheck 48 80 java.lang.String.substring 47 65 java.util.HashMap$HashIterator.nextEntry 42 94 java.util.AbstractList$Itr.checkForComodification 25 26 java.util.ArrayList$Itr.checkForComodification 24 63 java.lang.String.charAt 14 26 java.lang.Enum.valueOf 13 16 org.hibernate.ejb.AbstractEntityManagerImpl.convert 13 15 java.net.URI.create 12 22

Como podemos observar, nossa base de dados possui uma grande quantidade de stack traces, relacionadas com as mais variadas exceções. Foi possível ver também que muitas exceções estão presentes em diversos repositórios e e aparecem em muitas stack traces diferentes. Diante disso, acreditamos que nossa base possui um conjunto de dados sufici- entemente interessante para que possamos realizar nosso estudo.

Documentos relacionados