Pular para o conteúdo principal

Postagens

return void();

É uma pequeneza mas eu gostaria muito que as linguagens da família do C permitissem retornar void quando a função retorna void . Escrever da forma a seguir me aborrece. public class Foo  {    public void log (String msg) { }    public void bar (String x, String y) { }    public void bar (String x)    {      if (x == null)      {        log("x was null");        return;      }      bar(x, "default");    } } Eu ficaria mais feliz escrevendo assim: public class Foo  {    public void log (String msg) { }    public void bar (String x, String y) { }    public void bar (String x)    {      if (x == null) return log("x was null");      bar(x, "default");     } }

JNDI e Plan 9

Acabei de realizar quão similar é o J2EE e o Plan 9 quando observados pela lente da arquitetura de componentes: no Plan 9, o sistema de arquivos é tão capaz quanto o JNDI no J2EE. Um componente no qual eu estou trabalhando agora depende de um componente de banco de dados e de um componente de correio eletrônico. O modo de ligação entre esses componentes se dá através de JNDI: meu componente faz referência aos nomes "dataSource" e "mailSession" no seu contexto local de nomes. Na configuração do componente em uma instalação, esses nomes locais são ligados aos nomes globais que o administrador preparou para oferecer as dependências. É claro que tanto o meu componente quanto suas dependências mantém um contrato entre si, na forma das interfaces java EntityManager e Session. No Plan 9, meu componente seria um programa que faz referência a dois arquivos no seu file system -- um arquivo que repr...

Aplicação J2EE não deve criar arquivos..?

Recentemente surgiu a necessidade para um web service  para upload  de arquivos. Uma aplicação de HTTP com GET e PUT seria suficiente. Lendo uns artigos por aí, encontrei novamente esse discurso: "aplicações J2EE não devem escrever em arquivos". O fundamento do discurso está no fato de um componente para um ambiente gerenciado programar o ambiente gerenciado e não o sistema operacional, de modo que não deve fazer suposições sobre coisas como threads  ou arquivos. Os detalhes do argumento, porém, são péssimos. Dizer -- o componente não deve usar arquivos porque se a implantação ocorre em um cluster  os dados não serão vistos com consistência -- é uma falácia. Se você implantará o componente em um cluster  usará um sistema de arquivos compartilhado. O erro implícito nessa "sabedoria" seria igualmente cometido por um administrador de cluster  que usasse um banco de dados independente para cada nó.

GWT DevMode com EJB

Este ano estamos iniciando nossa convivência com sistemas interativos via web e escolhemos o Google Web Toolkit para nos apoiar, convictos em jamais usar pré-processamento de HTML no servidor. Enquanto este toolkit (na versão 2.4) nos pareceu desde o início uma coisa totalmente excelente, uma preocupação se manteve firme: o ciclo de desenvolvimento ótimo do GWT exige o uso do DevMode. O DevMode do GWT é um truque excelente que permite ao desenvolvedor usar um depurador Java para rastrar a execução do programa que roda no user agent . Como GWT é fundamentalmente um compilador de Java para Javascript, depurar o código-fonte de produção seria no mínimo desagradável. A configuração padrão do DevMode (na versão 2.4) inclui o web container Jetty para servir o HTML, JS, CSS, Servlets e tudo o mais que compõe o programa. O Jetty é um container simples e não inclui, entre outras coisas, uma implementação de JPA ou EJB. Ora, como este projeto pode permanecer confortável? Eventualmen...

Pensamento

E se a interface do sistema de arquivos focasse primeiro nos arquivos e depois nos nomes, e não o contrário? Ao invés de criar um arquivo com nome tal, os programas primeiro criam arquivos, da mesma forma como alocam memória, e posteriormente criam ligações desse arquivo para locais na árvore de nomes. Um programa que criasse um arquivo mas nunca criasse ligações teria um arquivo temporário fatalmente destruído após o término do programa. Uma referência válida para o arquivo em um programa adquire o arquivo e portanto ele não pode ser destruído; transmitir essa referência a outro programa por interprocess communication  se torna uma forma de object remoting  paralela a shared memory . Isto evidenciaria melhor a distinção no sistema de arquivos entre os arquivos propriamente ditos e os nomes; no Unix, entre os inodes  e os paths . A interface de arquivos e a interfaces de nós na árvore seria logicamente associada porém claramente distinta. Esta distinção é útil a...

Pela milionésima vez este erro

Cometi pela milionésima vez o mesmo erro e deixo este artículo na tentativa de impedir a próxima: não, não interessa se a operação overlapped diz que completou imediatamente, haverá uma completion packet esperando na completion port . Apenas ignore.

Porting C to ... C

Chegou, então, a hora de ressuscitar um programa desenvolvido pelo fundador da empresa em um inominável sistema UNIX rodando em i386 no passado remoto. O programa, cujo sistema de construção permitia a configuração para inúmeras variantes do UNIX de então, permaneceu compilável com mínimas modificações até o Fedora 17. Impressionante. Infelizmente, ao executar o programa, segmentation fault a torto e a direito. Com a ajuda de um debugger , alcançamos a seguinte iteração, simplificada para este artigo: for (int i = 0; i < name_list_size; ++i) {   p = (char *) getenv(name_list[i]);   if (p != NULL)     if (*p != NULL)       strcpy(value_list[i], name_list[i]); } Simples, certo? O programa levantava SIGSEGV ao avaliar a expressão *p . Como é possível? Certamente getenv retorna um endereço válido ou NULL . Certamente p não é NULL quando avalia-se *p . Qual é o tipo de p ? char * p . Por acaso o programa está s...