Tecnologia e Educação
Blog de Jarley Nóbrega
Blog de Jarley Nóbrega
07/12/09
Uma singela homenagem para a maior torcida do Brasil. Vi o jogo ontem com a galera da Fla-Recife, no Clube das Águias da Aeronáutica. Infelizmente, não deu para ir para o Maraca por conta de todos os problemas com a compra dos ingressos. Esse ano saímos da fila no Brasileirão. Ano que vem queremos a Libertadores e o Mundial de Clubes!
03/11/09
A cada seis meses, mais especificamente em Abril e Outubro, eu tenho uma estranha rotina: investir horas dos meus fins de semana para fazer o meu notebook funcionar após atualizar o S.O. com a última versão do Ubuntu. A lista de problemas já é bem conhecida minha: o acesso à rede sem fio deixa de funcionar, o plugin do Firefox para suportar vídeos em flash precisa ser reinstalado, o som do Skype precisa ser reconfigurado, um monte de pequenas aplicações precisam ser atualizadas na mão (a Canonical restringe a atualização de um monte de programas), entre outras coisas menores.
Como usuário veterano de Linux, acho normal passar algumas horas recompilando drivers, alterando arquivos de configuração, etc. É um preço que se paga por ter um S.O. estável e seguro. O problema é quando a coisa foge completamente de controle, como aconteceu com a versão 9.10, lançada em 29/10. Provavelmente esse release será conhecido como a pior coisa que a Canonical colocou no ar, desde que começaram as distribuições do Ubuntu a cada seis meses. Em um artigo publicado no The Register, com o singelo título de “Early adopters bloodied Ubuntu’s Karmic Koala“, foram citados os dados de uma enquete que apontam que 20% dos usuários encontraram problemas na atualização de difícil resolução. Em outro post do mesmo jornal, alguns usuários especializados sugerem que se espere pelo menos um mês para fazer a atualização, tempo considerado crucial para a Canonical corrigir as besteiras incorporadas nessa versão.
Os problemas da 9.10 vão desde o não reconhecimento do HD, passando por incompatibilidades com o chipset gráfico (que não existiam na 9.04, claro), chegando a questões de segurando envolvendo a arquitetura de criptografia do S.O. No meu caso, além dos velhos problemas conhecidos (vide o primeiro parágrafo desse post), dessa vez tive que lidar com o não reconhecimento de minhas placas de rede e um travamento irritante causado por interrupções geradas pelo kernel. Como todo early adopter de tecnologia, vou tentar mais uma vez resolver esses problemas, mas confesso que dessa vez fiquei p*** o suficiente para pensar seriamente em tentar outra distro (alguém já experimentou o Mandriva?).
Ao longo da semana eu irei postar o status da resolução dos problemas.
P.S.: e os caras da Canonical lançaram essa versão logo na semana em que o Windows 7 chegou às lojas. Belo tiro no pé…
———
Update: deixei de lado o mecanismo de atualização do Ubuntu, fiz um backup (+50GB) e instalei o S.O. do zero. O resultado foi um sistema limpo, estável e que reconheceu 100% de meus dispositivos de hardware. Só falta colocar o som do Skype para funcionar. Em resumo, não confie na atualização automática. Prefira fazer uma instalação limpa.
26/10/09
Pois é. Só mesmo as minhas corridas de rua para tirar a poeira do blog. Ontem consegui completar a minha primeira meia-maratona, depois de alguns meses de treino. Confesso que senti muito o forte calor e quase “quebrei” no Km 18. Consegui terminar a prova em 02:12:33 (tempo líquido, extra-oficial), um tempo bem acima do que eu esperava. Tinha a expectativa de terminar em menos de 2 horas, mas depois que passei dos 14 Km meu ritmo começou a cair muito rápido.
Da prova em si, algumas coisas precisam melhorar para o próximo ano. A principal delas, o péssimo isolamento da prova, mais uma vez a cargo da CTTU. Na ponte do Pina, cansei de ver carros invadindo a faixa de corrida e motoristas desrespeitando o isolamento na frente dos guardas. Acho que a CTTU deveria ver como o Exército isola as suas corridas. O kit final também não era lá essas coisas. Ficou faltando um isotônico para os corredores que completaram a prova. De positivo, vale destacar a boa hidratação da corrida, com pontos de água a cada 2 Km (para a prova de 10 Km) e e 3Km (para a meia).
Semana que vem retorno aos treinos. Será que dá para encarar a meia de João Pessoa no final de Novembro?
23/08/09
Mais uma prova de 10 Km completada. Corri hoje a 35a Corrida Duque de Caxias, organizada pelo Exército. Meu tempo (extra-oficial) ficou em 55’25”, bem melhor que a última Corrida das Pontes, com um pace médio de 5,5 min/Km.
A organização da corrida foi impecável! Quando fui retirar o kit da prova no dia anterior achei que a organização deixaria a desejar, pois tive que esperar mais de uma hora para pegar a camisa e o meu número de inscrição. Fiquei surpreso quando me informaram que o chip para marcação dos tempos só seria entregue no dia da corrida. Fiquei imaginando a confusão que seria.
Mas eu estava enganado. A retirada do chip foi rápida e organizada. Os organizadores montaram um esquema para validar os equipamentos: fizeram um cercado na área da largada com um único ponto de acesso. Quando o corredor entrava nessa área, o chip era validado na hora.
A largada foi bem tranquila, iniciada com um tiro de canhão. Vale destacar o perfeito isolamento do percurso feito pelos soldados do Exército. Acho que nem a Corrida das Pontes teve o trajeto todo livre para os corredores. No mais, a hidratação da prova foi boa, com pontos de abastecimento de água a cada 2 KM. Para minha surpresa, consegui passar sem problemas pelo ponto mais difícil da prova: a subida do viaduto do Forte das Cinco Pontas. Debaixo de um sol forte, consegui chegar inteiro, antes de uma hora de prova.
Parabéns para os organizadores da corrida. Em 2010 estarei lá de novo!
04/08/09
Um excelente post de Chuck Connel na Dr. Dobb’s, defendendo a tese que a Engenharia de Software (ES) não faz parte da Ciência da Computação (!). Achei muito interessante o ponto de vista dele, mostrando que a ES não precisa ter um rigor matemático em suas atividades, basicamente, porque software é feito com “criatividade, visão, pensamento multidisciplinar e humanidade”. Isso me lembra alguns colegas de trabalho em um passado recente, tentando provar por fim da força que Análise por Pontos de Função é algo confiável
. O trecho onde ele fala que essas técnicas de estimativas são meramente subjetivas, devido aos fatores humanos presentes em sua formulação, é um excelente argumento na defesa de metodologias mais ágeis para tentar prever os diversos aspectos da construção de software.
Veja abaixo o post de Connell. O
—————————————–
“A few years ago, I studied algorithms and complexity. The field is wonderfully clean, with each concept clearly defined, and each result building on earlier proofs. When you learn a fact in this area, you can take it to the bank, since mathematics would have to be inconsistent to overturn what you just learned. Even the imperfect results, such as approximation and probabilistic algorithms, have rigorous analyses about their imperfections. Other disciplines of computer science, such as network topology and cryptography also enjoy similar satisfying status.
Now I work on software engineering
, and this area is maddeningly slippery. No concept is precisely defined. Results are qualified with “usually” or “in general”. Today’s research may, or may not, help tomorrow’s work. New approaches often overturn earlier methods, with the new approaches burning brightly for a while and then falling out of fashion as their limitations emerge. We believed that structured programming was the answer. Then we put faith in fourth-generation languages, then object-oriented methods, then extreme programming, and now maybe open source.
But software engineering is where the rubber meets the road. Few people care whether P equals NP just for the beauty of the question. The computer field is about doing things with computers. This means writing software to solve human problems, and running that software on real machines. By the Church-Turing Thesis, all computer hardware is essentially equivalent. So while new machine architectures are cool, the real limiting challenge in computer science is the problem of creating software. We need software that can be put together in a reasonable amount of time, for a reasonable cost, that works something like its designers hoped for, and runs with few errors.
With this goal in mind, something has always bothered me (and many other researchers): Why can’t software engineering have more rigorous results, like the other parts of computer science? To state the question another way, “How much of software design
and construction can be made formal and provable?” The answer to that question lies in Figure 1.

The topics above the line constitute software engineering. The areas of study below the line are the core subjects of computer science. These latter topics have clear, formal results. For open questions in these fields, we expect that new results will also be formally stated. These topics build on each other — cryptography on complexity, and compilers on algorithms, for example. Moreover, we believe that proven results in these fields will still be true 100 years from now.
So what is that bright line, and why are none of the software engineering topics below it? The line is the property “directly involves human activity”. Software engineering has this property, while traditional computer science does not. The results from disciplines below the line might be used by people, but their results are not directly affected by people.
Software engineering has an essential human component. Software maintainability, for example, is the ability of people to understand, find, and repair defects in a software system. The maintainability of software may be influenced by some formal notions of computer science — perhaps the cyclomatic complexity of the software’s control graph. But maintainability crucially involves humans, and their ability to grasp the meaning and intention of source code. The question of whether a particular software system is highly maintainable cannot be answered just by mechanically examining the software.
The same is true for safety. Researchers have used some formal methods to learn about a software system’s impact on people’s health and property. But no discussion of software safety is complete without appeal to the human component of the system under examination. Likewise for requirements engineering. We can devise all sorts of interview techniques to elicit accurate requirements from software stakeholders, and we can create various systems of notation to write down what we learn. But no amount of research in this area will change the fact that requirement gathering often involves talking to or observing people. Sometimes these people tell us the right information, and sometimes they don’t. Sometimes people lie, perhaps for good reasons. Sometimes people are honestly trying to convey correct information but are unable to do so.
This observation leads to Connell’s Thesis:
Software engineering will never be a rigorous discipline with proven results, because it involves human activity.
This is an extra-mathematical statement, about the limits of formal systems. I offer no proof for the statement, and no proof that there is no proof. But the fact remains that the central questions of software engineering are human concerns:
All of these problems revolve around people.
My thesis explains why software engineering is so hard and so slippery. Tried-and-true methods that work for one team of programmers do not work for other teams. Exhaustive analysis of past programming projects may not produce a good estimation for the next. Revolutionary software development tools each help incrementally and then fail to live up to their grand promise. The reason is that humans are squishy and frustrating and unpredictable.
Before turning to the implications of my assertion, I address three likely objections:
The thesis is self-fulfilling. If some area of software engineering is solved rigorously, you can just redefine software engineering not to include that problem.
This objection is somewhat true, but of limited scope. I am asserting that the range of disciplines commonly referred to as software engineering will substantially continue to defy rigorous solution. Narrow aspects of some of the problems might succumb to a formal approach, but I claim this success will be just at the fringes of the central software engineering issues.
Statistical results in software engineering already disprove the thesis.
These methods generally address the estimation problem and include Function Point Counting, COCOMO II, PROBE, and others. Despite their mathematical appearance, these methods are not proofs or formal results. The statistics are an attempt to quantify subjective human experience on past software projects, and then extrapolate from that data to future projects. This works sometimes. But the seemingly rigorous formulas in these schemes are, in effect, putting lipstick on a pig, to use a contemporary idiom. For example, one of the formulas in COCOMO II is PersonMonths = 2.94 × SizeB, where B = 0.91 + 0.01 × Σ SFi, and SF is a set of five subjective scale factors such as “development flexibility” and “team cohesion”. The formula looks rigorous, but is dominated by an exponent made up of human factors.
Formal software engineering processes, such as cleanroom engineering, are gradually finding rigorous, provable methods for software development. They are raising the bright line to subsume previously squishy software engineering topics.
It is true that researchers of formal processes are making headway on various problems. But they are guilty of the converse of the first objection: they define software development in such a narrow way that it becomes amenable to rigorous solutions. Formal methods simply gloss over any problem centered on human beings. For example, a key to formal software development methods is the creation of a rigorous, unambiguous software specification. The specification is then used to drive (and prove) the later phases of the development process. A formal method may indeed contain an unambiguous semantic notation scheme. But no formal method contains an exact recipe for getting people to unambiguously state their vague notions of what software ought to do.
To the contrary of these objections, it is my claim that software engineering is essentially different from traditional, formal computer science. The former depends on people and the latter does not. This leads to Connell’s Corollary:
We should stop trying to prove fundamental results in software engineering and accept that the significant advances in this domain will be general guidelines.
As an example, David Parnas wrote a wonderful paper in 1972, On The Criteria To Be Used in Decomposing Systems into Modules. The paper describes a simple experiment Parnas performed about alternative software design strategies, one utilizing information hiding, and the other with global data visibility. He then drew some conclusions and made recommendations based on this small experiment. Nothing in the paper is proven, and Parnas does not claim that anyone following his recommendations is guaranteed to get similar results. But the paper contains wise counsel and has been highly influential in the popularity of object-oriented language design.
Another example is the vast body of work known as CMMI from the Software Engineering Institute at Carnegie Mellon. CMMI began as a software process model and has now grown to encompass other kinds of projects as well. CMMI is about 1000 pages long — not counting primers, interpretations, and training materials — and represents more than 1000 person-years of work. It is used by many large organizations and has been credited with significant improvement in their software process and products. But CMMI contains not a single iron-clad proven result. It is really just a set of (highly developed) suggestions for how to organize a software project, based on methods that have worked for other organizations on past projects. In fact, the SEI states that CMMI is not even a process, but rather a meta-process, with details to be filled in by each organization.
Other areas of research in this spirit include design patterns, architectural styles, refactoring based on bad smells, agile development, and data visualization. In these disciplines, parts of the work may include proven results, but the overall aims are systems that foundationally include a human component. To be clear: Core computer science topics (below the bright line) are vital tools to any software engineer. A background in algorithms is important when designing high-performance application software. Queuing theory helps with the design of operating system kernels. Cleanroom engineering contains some methods useful in some situations. Statistical history can be helpful when planning similar projects with a similar team of people. But formalism is just a necessary, not sufficient, condition for good software engineering. To illustrate this point, consider the fields of structural engineering and physical architecture (houses and buildings).
Imagine a brilliant structural engineer who is the world’s expert on building materials, stress and strain, load distributions, wind shear, earthquake forces, etc. Architects in every country keep this person on their speed-dial for every design and construction project. Would this mythical structural engineer necessarily be good at designing the buildings he or she is analyzing? Not at all. Our structural engineer might be lousy at talking to clients, unable to design spaces that people like to inhabit, dull at imagining solutions to new problems, and boring aesthetically. Structural engineering is useful to physical architects, but is not enough for good design. Successful architecture includes creativity, vision, multi-disciplinary thinking, and humanity.
In the same way, classical computer science is helpful to software engineering, but will never be the whole story. Good software engineering also includes creativity, vision, multi-disciplinary thinking, and humanity. This observation frees software engineering researchers to spend time on what does succeed — building up a body of collected wisdom for future practitioners. We should not try to make software engineering into an extension of mathematically-based computer science. It won’t work, and can distract us from useful advances waiting to be discovered.”
25/07/09
Scala é uma linguagem de programação que adota o paradigma funcional, tendo como principal característica a execução de seus scripts através de uma máquina virtual Java (JVM). Scala é enquadrada na categoria das linguagens dinâmicas, com forte integração com as bibliotecas criadas para a plataforma Java.
As Origens
Em paralelo a todo esse trabalho em cima de generics, Odesky começou a criação de uma nova linguagem de programação em 2001. A linguagem era a Scala e foi utilizada como referência para as suas aulas no EPFL. Em 2003, a linguagem teve o seu primeiro release disponível para a comunidade de programadores. Em 2006, a versão 2.0 de Scala foi lançada e vem evoluindo rapidamente com a colaboração de Lex Spoon, Burak Emir, Adriaan Moors, Philipp Haller, entre outros. Odesky continua como líder do projeto e principal commiter das alterações significativas na linguagem, atualmente em sua versão 2.7.5.
Pré-requisitos
O próximo passo é baixar a última versão do Scala no endereço http://www.scala-lang.org/downloads. Essa opção não é necessária se você decidir usar a linguagem a partir de uma IDE, como o Eclipse. Para maiores detalhes dessa opção veja a seção “Instalando Scala no Eclipse”.
Instalando Scala
A maneira mais simples e recomendável para instalar Scala é utilizar a ferramenta lzPack, disponível na página de downloads da linguagem. Esse utilitário está disponível em http://www.scala-lang.org/downloads, e a sua execução é relativamente simples, independente do sistema operacional utilizado.
Para os usuários do Windows, certifique-se que o JDK tenha sido instalado corretamente, com a varíavel de ambiente JAVA_HOME devidamente configurada. Em seguida, basta dar um duplo clique no arquivo scala-2.7.x.final-installer.jar e verificar se a tela mostrada na Figura 1.1 apareceu normalmente.

Para os usuários das várias distribuições Linux, o processo é basicamente o mesmo. Baixe o instalador e execute-o com o comando sudo java -jar scala-2.7.x.final-installer.jar. Se você não estiver utilizando um ambiente gráfico (Gnome ou KDE), o instalador irá executar em modo texto. De forma semelhante, siga as instruções até completar todo o processo de instalação. Para usuários do Ubuntu, ainda é possível instalar Scala a partir do utilitário apt-get ou do gerenciador de pacotes Synaptic. Para instalar em linha de comando digite sudo apt-get install scala.
Para verificar se tudo correu sem problemas, abra uma janela de prompt (ou terminal no Linux) e digite scala no Windows ou ./scala no Linux. Deverá ser exibida uma tela semelhante à Figura 1.2 abaixo.

Para sair da ferramenta de linha de comando do Scala, digite exit.
Uma alternativa para os usuários da IDE Eclipse é fazer a instalação do Scala diretamente dentro dessa ferramenta de desenvolvimento. Essa opção apresenta algumas vantagens para o uso regular de Scala como linguagem de programação, como por exemplo, o uso de um editor de código sensível ao contexto, recursos de autocomplete, marcadores de erros, indentação do código, entre outras características típicas de ambientes integrados de desenvolvimento.
Durante a escrita desse capítulo, utilizei a versão mais recente do Scala IDE para o Eclipse 3.5 ou superior (as versões mais antigas do Eclipse executam esse plugin com várias restrições). Para instalar o plugin para essa versão do Eclipse, vamos utilizar a ferramenta de instalação da IDE. Após entrar no Eclipse, navegue pelo menu Help, e escolha a opção Install New Software. Após a exibição da tela de instalação, no campo Work with, digite a URL do repositório do plugin: http://www.scala-lang.org/scala-eclipse-plugin e clique em Add. A tela mostrada na Figura 1.3 deverá ser exibida.

No campo Name marque a opção Scala e clique em Next, seguindo o processo de instalação até o fim. Para testar a instalação, crie um novo projeto, clicando em File -> New ->…-> Scala Project. A tela mostrada na Figura 1.4 é apresentada. Digite o nome do projeto como Hello e clique em Finish.

object HelloWorld { def main(args : Array[String]) : Unit = { println(”Hello World Scala!”) } }

Instalando Scala no Netbeans
Durante a escrita desse capítulo só existiam plugins Scala para o Netbeans em estágio de desenvolvimento, o que pode ser fonte de erros e chateação para quem for utilizá-los. Como pré-requisito principal para instalação, é exigida a versão 6.7 do Netbeans ou superior. Para iniciar a instalação, baixe a última versão do plugin da URL http://sourceforge.net/projects/erlybird/files/nb-scala/nb-scala%206.7v1/nb-scala-6.7v1.zip/download. Descompacte o plugin em um diretório de sua máquina e entre no Netbeans. Escolha a opção Ferramentas -> Plugins. Clique na aba Baixados, selecione todos os arquivos com extensão .nbm e instale o plugin do Scala a partir do diretório onde ele foi descompactado.
Para testar a instalação, crie um novo projeto Scala escolhendo as opções Arquivo -> Novo Projeto. Em seguida, escolha Scala e Scala Application e pressione Next. No campo Project Name digite Hello e confirme. Para o nosso exemplo simples do HelloWorld o Netbeans já cria um objeto Main, com o código necessário para imprimir o texto. Clique no objeto e execute-o. Deverá ser mostrada uma tela semelhante à da Figura 1.6, com a execução da aplicação.

25/07/09
Conforme eu tinha prometido para os meus alunos há vários semestres, vou iniciar aqui no blog uma série de tutoriais em cima de duas tecnologias que venho estudando. O primeiro tutorial irá abordar os princípios da linguagem de programação Scala. O segundo irá mostrar as principais características do framework Jboss Seam.
A idéia desses tutoriais é mostrar o que cada ferramenta tem de mais produtivo para os programadores de aplicações. Na difícil tarefa de administrar o meu tempo útil, vou tentar escrever sobre esses dois temas de modo simultâneo. Caso o formato de blog mostre-se inadequado para essas publicações, poderei no futuro migrar todo o conteúdo para uma página exclusiva, com mais recursos para os usuários.
O material das minhas disciplinas regulares continuam publicadas no Moodle de meu portal.
21/07/09
Tentando fazer o papel de advogado do diabo, repasso o interessante post de Mario Fusco. No texto ele fala de 10 razões para começar a pensar em uma linguagem que substitua Java.
“Don’t get me wrong. During my professional life I have written tons of Java code and of course I think it is a great language still. For sure it has been a great improvement from C++ and Smalltalk. But now even Java is starting to feel the weight of its 15 years.
Indeed during my experience I had to face up with some mistakes, flaws and lacks in its design and specification that made my Java programmer life less pleasant. With millions of Java programmers and billions of lines of code out in the world, I am far to say that Java is going to be dead in the near future. Anyway after the rise of some JVM compatible languages (my favorite is Scala), these issues are becoming even less tolerable and I am starting thinking that it is time to slowly move away from Java (but not from the JVM). More in detail, in my opinion, the 10 most important problems of the Java language are:
1. Lack of closure: I don’t think I have to explain this. Functional programming exists since decades, but in the last years they are gaining more and more interests, mostly because it allows to write naturally parallelizable programs. I partially agree with Joshua Bloch that underlined the problems of introducing them in Java as a second thought (the BGGA proposal was truly awful), but anyway their lack makes impossible to have any kind of real functional programming in Java.
2. Lack of first class function: this issue is in some way related to the former one but I believe it is even worse. The only way to achieve a similar result in Java is by using the ugly and sadly famous one-method anonymous inner classes, but it looks actually a poor solution. Even in C# has been provided a better one by the implementation of the delegate mechanism.
3. Primitive types: it should be beautiful if everything in Java was an Object, but they didn’t design it in that way. That leaded to some issue, like the impossibility to have a Collection of int partially resolved in Java 5 through the autoboxing feature (see below). It also generated some confusion between passing by value and passing by reference. Indeed a primitive data type is passed to a method by value (a copy of the data type is duplicated, and passed to the function) while true objects are passed by reference.
4. Autoboxing and autounboxing: this feature has been introduced in Java 5 to overcome the problems caused by the presence of primitive types. It allows to silently convert a primitive type in the corresponding object, but often it is cause of other problems. For example an Integer can have null value, but the same doesn’t apply to int, so in this case when the Integer is changed in an int the JVM can’t do anything else than throw a difficult to debug NullPointerException. Moreover it is cause of other strange behavior like in the following example where it is not so easy to understand why the test variable is false:
Integer a = new Integer(1024);
Integer b = new Integer(1024);
boolean test = a < b || a == b || a > b;
5. Lack of generics reification: generics are one of the cool features introduced with Java 5, but in order to mantain the compatibility with the older version of java they miss some important characteristic. In particular it is not possible to introspect their generic type at runtime. For example if you have a method that accepts as parameter a List<?> and you pass to it a List<String> you are not allowed to know at runtime the actual type of the generic. For the same reason you cannot create array of generics. It means that despite it looks quite natural the following statement won’t compile:
List<String>[] listsOfStrings = new List<String>[3];
6. Unavoidable generics warnings: have you ever found yourself in the impossibility to get rid of a bothering warning about generics? If you make a large use of generics like me, I bet you did. And the fact that they felt the need to introduce a special annotation to manage this situation (@SuppressWarnings(“unchecked”)) is symptomatic of the dimension of this problem and, in my opinion, that generics could have been designed better.
7. Impossibility to pass a void to a method invocation: I admit that the need to pass a void to a method could look weird at a first glance. Anyway I like DSL and while implementing a special feature of my DSL library (lambdaj) I had the need to have a method with a simple signature like this: void doSomething(Object parameter) where the parameter passed to this method is the result of another method invocation done with the only purpose to register the invocation itself and execute it in the future. With my big surprise, and apparently without a good reason, since the println method returns void, I am not allowed to write something like this:
doSomething(System.out.println(“test”));
8. No native proxy mechanism: proxy is a very powerful and widely used pattern, but Java offers a mechanism to proxy only interfaces and not concrete classes. This is why a library that provide this feature like cglib is employed in so many main stream frameworks like Spring and Hibernate. Moreover cglib implements this feature by creating at runtime a Class that extends the proxied one, so this approach has a well known limitation in the impossibility to extend and then proxy a final Class like String.
9. Poor switch … case statement: the switch … case as specified in java allows to switch only on int and (starting from java 5) enum. That looks extremely few powerful especially if compared with what offered by a more modern language like Scala.
10. Checked exception: like primitive types, checked exception have been one of the original sins of Java. They oblige programmers to do one of the following two equally horrible things: fill your code with tons of poorly readable and error prone try … catch statement where often the most meaningful thing to do is to wrap the catched exception in a runtime one and rethrow it; or blurring your API with lots of throws clause making them less flexible and extensible.
The real problem here is that the only way to fix the biggest part of the issues I mentioned is to take a painful decision and define a specification of the language that drops the backward compatibility with the current one. I guess they will never do that, even if I believe it should not be extremely difficult to write a program that allows to automatically translate the old Java sources in order to make them compatible with this new hypothetic release. And in the end, this is the reason why I decided to start looking for a better JVM compatible language.”
—
Esse post gerou uma boa discussão nos fórums do The Server Side, com um monte de gente se posicionando contra ou a favor. No meu ponto de vista, boa parte das fragilidades apontadas no texto podem ser resolvidas através de bibliotecas que estendem a linguagem. E falando francamente, não acho as alegações de Mario boas o suficiente para promover uma mudança de plataforma, principalmente quando levamos em consideração todo o legado construído na última década. Os problemas apontados por ele são reais, mas não impactam em nada na produtividade e extensibilidade das aplicações desenvolvidas em Java.
Uma das maiores reclamações da comunidade em torno de Java era que as ferramentas de desenvolvimento não seriam tão eficientes e produtivas como as encontradas para a plataforma .Net. Quem acompanhou as últimas versões do Eclipse e do Netbeans sabe que os recursos para construção de aplicações a partir de modelos ou templates já fazem parte do dia a dia de todo desenvolvedor. Para melhorar um pouco mais as coisas, novos frameworks surgem quase que diariamente com o objetivo de melhorar continuamente a maneira de desenvolver aplicações na linguagem (atualmente estou desenvolvendo meus projetos usando o Seam. Complexo e completo).
A discussão é boa, mas eu ainda pretendo investir algumas horas de meu tempo para melhorar as minhas habilidades como desenvolvedor Java. Mas como nada é eterno, não custa nada começar a olhar algumas coisas como Scala, Ruby on Rails, Grails e outras linguagens e frameworks da moda
10/07/09
Aproveitando toda a repercussão do anúncio do Chrome OS por parte do Google, transcrevo abaixo o excelente post de Kent Back sobre o assunto.
——-
“I’ve been reading reactions to the Chrome OS announcement today and so far everything I’ve read has missed the point, or at least the point I see. Here’s my take on Chrome OS. It’s a story, though, not a soundbite.

When Chrome came out I took a look at the architecture and thought, “Hmm… separate address spaces for each tab. That looks like an operating system.” So I decided to try it, to simulate using Chrome as my operating system. I made it my default browser (in spite of Microsoft’s periodic attempts to change my preference) and expanded it to full screen. From then on I did everything I could on the web.
The best part of a year later I can say Chrome is a little clunky as a desktop. Multiple windows are more work than they should be (I wish they’d automatically size to their contents). Some of the web GUIs aren’t as polished as native interfaces. However, there is a whole lot I don’t miss about Windows apps. Overall the advantages outweigh the disadvantages.
I still use a handful of native apps regularly: Skype, Eclipse, iTunes, and Outlook. I’d be happy to have web-based replacements (actually I only use Outlook out of inertia, not because Gmail wouldn’t do a just fine job). If I had them, I wouldn’t miss my old desktop at all.

Negative reactions to Chrome OS seem to be based on how much worse it is than its competitors. Christensen provides an alternative perspective on the situation. The existing desktops are overkill for most users’ needs. The more features added to the desktops, the smaller percentage most people find useful. An alternative that is better at stuff users care about would be welcome.
This is a story that has played out thousands of times: digital photography was worse than chemical photography, wireless LANs were worse than wired LANs, microcomputers were worse than minicomputers were worse than mainframes, Java was worse than C++. Now Chrome OS is worse than Windows and the Mac and Linux desktops.
Innovations that start out worse need to be better at something new that matters. Imagine never having to install an application again. Never having to back up. Never having to reinstall the OS because it’s just gotten way too weird. I’d give up a lot to gain that. That was the point of telling you about my experiment: I’ve seen the future and it’s not so bad.
The next step in the innovator’s dilemma script is predictable. The existing participants will ignore Chrome (they may fuss, but they aren’t going to introduce something even simpler, even better, even cheaper–that’s just not how they think). Chrome OS will grow better and better, and be attractive on bigger and bigger hardware. More and more of the necessary apps will migrate to the browser or be replaced by inferior-but-good-enough entrants (do you hear that, Skype?) Since Chrome OS is genuinely better along some dimensions, the motivation is there for users, for application developers, and for Google to continue the march.
After a decade of nibble, nibble, nibble, Apple and Microsoft will occupy highly-profitable but miniscule markets. If I had to guess I would say that Apple will have the very best high end desktops and Microsoft will be strong on servers. By that time, though, Chrome OS will have grown bloated with seemingly-indispensible features and will be ripe for a little nibble, nibble, nibble of its own.

Disruption isn’t inevitable. Relational databases successfully fended off clearly-superior object databases (although the stupidification of data poses a fresh disruptive threat). To remain strong in desktop operating systems, though, Apple or Microsoft or the Linux desktops would have to abandon their current profit model, find a fresh ultra-simplification twist, and run the new business far from rational-but-doomed headquarters (Merlin, Oregon has a lovely abandoned sawmill site ready for development, in case you’re interested). They aren’t likely to do so, though, because it makes no sense.
The current desktops are dead, even though they will linger for a decade or more. Welcome, Chrome OS. Here’s to a worse future.”
——–
26/06/09
Muito interessante o post de Klaus Peter Laube sobre a sua experiência no uso do Joomla e do WordPress como ferramentas para publicar conteúdo na Web. No artigo, ele relata porque prefere o WP como solução de publicação, enfatizando a simplicidade da ferramenta. Por outro lado, a complexidade na customização dos componentes do Joomla e os problemas de segurança ocorridos no passado fazem dessa solução um opção para sites mais complexos.
Como eu utilizo as duas ferramentas, tenho uma opinião parecida com a de Klaus:
Apesar de não ser muito fã de PHP, utilizo essas duas ferramentas para gerenciar o conteúdo de meu portal e do meu blog, além de utilizá-la como ferramenta de LMS através do Moodle. A facilidade de criação, customização e publicação de conteúdo dessas ferramentas explicam a sua enorme popularidade entre os web designers. Por outro lado, penso que soluções mais robustas, do tipo “mission-critical” devam ter uma plataforma com o mesmo grau de robustez e confiabilidade. Nos últimos meses venho estudando várias soluções de CMS para a plataforma Java. Ao final, depois de testar mais de 15 soluções open-source, minhas escolhas ficaram restritas à duas ferramentas:
Apesar das duas soluções para o mundo Java possuírem portlets para o gerenciamento de blogs, confesso que nada é comparável à flexibilidade e a facilidade de uso do WordPress. Esse é um campo onde as soluções Java precisarão de algum tempo para produzir uma ferramenta que concorra com o bom e velho WP.