ShowTime.java MainClass.txtExcelente artigo de como criar um installer para Mac de uma aplicação Java. Como esse artigo me salvou legal, copio ele aqui, só pra não perder.
How to Create a Mac OS X Installer for a Java Application
(Updated for Mac OS X 10.5 — Leopard)
With some simple steps you can turn your Java Swing program (.jar) into a proper Mac OS X application with a native installer. The instructions below step you through the process from scratch with a sample program called
ICONS
↓ 1) Install Xcode
Apple's Xcode suite includes development tools you'll need to bundle and package a Java program. First, download Xcode for Mac Development (version 3.1.1 or later) and open the downloaded .dmgfile. Now run the "XcodeTools.mpkg" file and complete the Xcode installation with all the default options.
Before continuing to the next step, it's a good idea to perform a "Software Update..." to make sure your OS files are current.2) Launch Unix Terminal
Using "Finder" go into "Applications" and then open the "Utilities" folder. Scroll down until you see "Terminal". Open "Terminal" and you're now at the Unix prompt.
3) Make Project Folder
At the Unix prompt, enter these two commands:
cd ItsShowtime4) Write Some Java Code
Mac OS X comes with a simple but effective text editor called Pico. Use the following command to create and edit a new Java file:
Use 5) Compile Java Program
Back at the Unix prompt, compile your Java program into a class file:
ls -la6) Make Executable JAR
Before we make an executable JAR file, we need a manifest file to indicate which class contains the "main" function. We'll use Pico again:
Exit Pico and use the following "jar" command to create the "ShowTime.jar" file:
ls -la
While the manual commands for steps #5 and #6 above work fine, you can automate them using Ant with this build.xml file.7) Create Application Icon
The default icon for an executable JAR is a coffee cup. To add a custom icon, we need to use the "Icon Composer".
Download and save (
Then move the file into the "ItsShowtime" folder with the following command:
Steps:
Next we'll create a Mac application (with your new icon).8) Bundle the JAR
Using "Finder", navigate into the "Developer:Applications:Utilities" folder and double-click "Jar Bundler".
Steps:
You now have a proper Mac application. Next we'll create an installer for your application.9) Create Mac Installer
Using "Finder", navigate into the "Developer:Applications:Utilities" folder and double-click "PackageMaker".
Steps:
Your installer is done, but it's not yet download friendly.10) Put Installer on a Web Page
Before putting the installer on the web, we need to zip it up into a single file. Use "Finder" to navigate to the "ItsShowtime" folder. Create a zip of "ShowTimeInstaller.pkg" using the "Compress" option on the
Instalador para Mac de uma aplicação Java
Postado por
Felipe Nascimento
28 de julho de 2009
às
23:07
Original em: http://www.centerkey.com/mac/java/
SCREENSHOT
"It's Showtime!" which simply displays the current time. Once you have successfully completed the tutorial with the sample Java program, modify the steps to work for your Java program.mkdir ItsShowtime
The first command creates a folder called "ItsShowtime", and the second command moves you into the new folder.pico ShowTime.java
Enter the following code:javac ShowTime.java
We could run the class file directly, but a class file is cumbersome. Instead we will create an executable JAR file.pico MainClass.txt
Our manifest file will only have one line:jar cmf MainClass.txt ShowTime.jar *.class
Now test your executable JAR with the following command:java -jar ShowTime.jar
The "It's Showtime!" window with the current time should display in the upper left corner of the screen. Click the red dot to exit the program.mv ../Desktop/ShowTime.png .
Now we can create the icon file.Logging com Grails 1.1
Postado por
Felipe Nascimento
29 de junho de 2009
às
22:50
Hoje fiquei tentando entender a configuração do Logging no grails 1.1...pois mudou um pouco.
Tem um bom exemplo aqui, que eu reproduzo abaixo.
log4j = {
appenders {
console name:'console', threshold:Level.ERROR,
layout:pattern(conversionPattern: '%p %d{ISO8601} %c{4} %m%n')
rollingFile name:"rollingFileTrace", threshold:Level।TRACE, maxFileSize:1048576,
file:logFile+'Trace।log', layout:pattern(conversionPattern: '%p %d{ISO8601} %c{5} %m%n')
rollingFile name:"rollingFileDebug", threshold:Level।DEBUG, maxFileSize:1048576,
file:logFile+'Debug.log', layout:pattern(conversionPattern: '%p %d{ISO8601} %c{5} %m%n')
rollingFile name:"rollingFileError", threshold:Level.ERROR, maxFileSize:1048576,
file:logFile+'Error.log', layout:pattern(conversionPattern: '%p %d{ISO8601} %c{5} %m%n')
}
error console, rollingFileDebug, rollingFileError, rollingFileTrace:
'org.codehaus.groovy.grails.web.servlet', // controllers
'org.codehaus.groovy.grails.web.pages', // GSP
'org.codehaus.groovy.grails.web.sitemesh', // layouts
'org.codehaus.groovy.grails."web.mapping.filter', // URL mapping
'org.codehaus.groovy.grails."web.mapping', // URL mapping
'org.codehaus.groovy.grails.commons', // core / classloading
'org.codehaus.groovy.grails.plugins', // plugins
'org.codehaus.groovy.grails.orm.hibernate', // hibernate integration
'org.springframework'
debug rollingFileDebug, rollingFileTrace:'org.hibernate',
'com.britetab',
'BootStrap',
'org.apache.ddlutils'
trace rollingFileTrace:'org.hibernate.SQL',
'org.hibernate.type',
'flex.messaging.services'
warn console,rollingFileDebug,rollingFileTrace:'org.mortbay.log',
'org.hibernate.tool.hbm2ddl'
root {
trace 'rollingFileTrace'
debug 'rollingFileDebug','rollingFileTrace'
error 'console','rollingFileError','rollingFileDebug','rollingFileTrace'
additivity = true
}
}
Infraestrutura e arquitetura do Digg
Postado por
Felipe Nascimento
23 de março de 2009
às
19:08
Muito interessante a apresentação de Joe Stump, que é o arquiteto líder do Digg.
Ele apresenta diversos problemas de escalabilidade enfrantados pelo Digg, e mostra algumas das estratégias e tecnologias usadas e ainda serão usadas. Ex.:
Será que um dia eu trabalharei num site que precisa de tanto? Mas o que é tanto? Bom, no caso deles (Digg), os números são mais ou menos esses:
- 35.000.000 milhões de Uniques por mês
- 3.500.000 de usuários
- 15.000 requests / segundo
- Centenas de servidores
Abcs
Web Sites de Alta Performance, Parte 3: Faça menos Requests HTTP
Postado por
Felipe Nascimento
28 de fevereiro de 2009
às
18:21
Este é o terceiro post da série Web Sites de Alta Performance. Esta série é baseada no livro de Steve Souders, High Performance Web Sites. Você pode ler a parte 1 e parte 2.
Portanto, uma primeira otimização que ataca estes 80% - 90% é diminuir o número de Requests HTTP que a sua página faz.
Quando você acessa uma página web, colocando o endereço da página no browser, esta página carrega o seu HTML que, por sua vez, faz outros Requests HTTP para carregar os demais componentes necessários: arquivos javascript, arquivos CSS, imagens, flash, etc. Para cada componente, é um novo Request Http que está sendo feito. E uma requisição Http tem todo um overhead do próprio protocolo Http. Ao diminuir o número de Requests, você está diminuindo o tempo total de carregamento da sua página.
Para conseguir diminuir o número de Requests, algumas coisas podem ser feitas:
- Uso de Image Maps:
Image Map permite que se tenha apenas uma imagem com múltiplos links nesta imagem. Ou seja, não é necessário, ao criar uma toolbar por exemplo, ter várias imagens, uma para cada link. É possível ter apenas uma imagem maior, cujas partes desta imagem possuem diferentes links. Isso é feito através do uso de Image Map. - Combinar arquivos em um único:
Ao invés de fazer 4 requisições para 4 diferentes arquivos de JavaScript (JS), você pode combinar os 4 arquivos em um único, e fazer apenas uma requição Http. Em sendo um engenheiro de software, isso me parece estranho, pois vai contra a modularização. Mas, se pudermos ter esta modularização em tempo de desenvolvimento, e e combinar estes arquivos em tempo de deploy, teremos assim o melhor dos dois mundos.
A mesma coisa vale para arquivos CSS: é possível combinar os diferentes arquivos CSS em um único. Combinar arquivos pode ser desafiador quando os scripts e arquivos css variam de página para página, mas tentar fazer esta junção em um único arquivo pode ser vantajoso. Se você conseguir fazer esta combinação automaticamente como parte do seu processo de Deploy, isso pode ficar transparente para o desenvolvedor, e assim conseguir fazer menos Requests HTTP, melhorando a performance final da sua página.
Numa situação ideal, sua página poderia ter apenas um arquivo javascript e um arquivo CSS.
Em algumas situações em que a página faz uso de diferentes bibliotecas javascript e ainda possui scripts próprios, a combinação pode dar ganhos em torno de 40% no carregamento da página. - CSS Sprites
CSS sprites é uma técnica usada para se criar apenas um arquivo de imagem que conbina várias imagens que serão usadas independentes umas das outras através de estilos CSS. Ou seja, existe apenas um arquivo de imagem que é resultado da combinação de algumas imagens a serem usadas independentemente. Para conseguir usar cada parte da grande imagem de forma a mostrar apenas a parte que interessa de cada vez, usa-se estilos CSS. Por exemplo:
Desta forma, podemos ter uma imagem grande de, por exemplo, 200px por 200px, mas estamos apresentando apenas uma parte dela, de 26 por 26 px.
O uso de CSS Sprites, combinado com o uso de Cache de imagens, é uma excelente forma de usar múltiplos ícones em uma página, porém fazendo apenas um Request para carregar a única imagem grande. Você pode ver mais a respeito deste assunto no artigo de Dave Shea chamado "CSS Sprites: Image Slicing's Kiss of Death".
A conclusão aqui, então, é: FAÇA MENOS REQUESTS HTTP.
Web Sites de Alta Performance, Parte 2: Visão Geral de HTTP
Postado por
Felipe Nascimento
às
16:54
Este é o segundo post da série Web Sites de Alta Performance. Esta série é baseada no livro de Steve Sourders, High Performance Web Sites. Caso não tenha lido o primeiro, leia aqui.
A versão mais usada do protocolo é o HTTP/1.1. Mas ainda hoje alguns browsers e servidores ainda usam o HTTP/1.0. Este é um protocolo cliente/servidor feito de requisições e respostas (Requests e Responses). O browser envia um Request por uma determinada URL, e o servidor que hospeda esta URL retorna com um Response. Os tipos de Requests são GET, POST, HEAD, PUT, DELETE, OPTIONS e TRACE. Focaremos no tipo GET que é o mais comum.
Um Request do tipo GET possui uma URL seguida de headers. Um Response contém um código de status (Status Code), headers e um corpo (body). Veja um exemplo abaixo, onde a primeira parte é o Request, e a segunda o Response:
GET /js/algumScript.js
HTTP/1.1
Host: meudominio.com
User-Agent:Mozilla/5.0(...) Gecko/20061206 Firefox/1.5.0.9
------------------------------------------------------------
HTTP/1.1
Content-Type: application/x-javascript
Last-Modified:Wed, 22 Feb 2006 04:15:54 GMT
Content-Length: 355
var f = function(){}....
Compressão
O tamanho da Response pode ser reduzido usando algum tipo de compressão caso ambos, browser e servidor, tenham suporte para tal compressão. O browser diz que tem suporte a compressão para o servidor usando o header Accept-Encoding. O servidor, por sua vez, diz ao browser que a Response está com compressão ao usar o header Content-Encoding. Por exemplo, o browser pode enviar a Request com o header:
Accept-Encoding: gzip,deflate
Enquanto que o servidor envia a Response com o seguinte header:
Content-Encoding: gzip
Não entrarei em mais detalhes agora, fica aqui apenas esta visão geral mesmo.
Requests Condicionais
Caso o browser tenha uma cópia de um componente (CSS, Javascript, Imagem, ...) no seu cache, mas não sabe ao certo se esta cópia ainda está válida, um Request Condicional é enviado pelo browser. Caso a cópia do cache ainda seja válida, então o browser usa esta cópia local e não baixa novamente o componente, tornando o tempo de resposta mais rápido para o usuário final.
Normalmente o browser sabe se o componente é válido ou não através da data que o componente foi modificado pela última vez. E ele sabe esta data através do header Last-Modified presente na Response. Veja no exemplo de Response acima que foi usado deste header.
Para realizar um Request condicional, o browser envia o Request com o header If-Modified-Since, cujo valor é a data presente na última response no header Last-Modified. Caso o componente não tenha sido modificado desde esta data, o servidor envia um Response com status code "304 Not Modified", e não envia body nenhum, resultando num Response mais rápido. No HTTP/1.1 ainda existem os headers ETag e If-None-Match para a realização de Requests condicionais. Mas não falarei em detalhes desses no momento.
Expires
Os Requests condicionais e status code 304 ajudam muito no tempo de resposta dos componentes de uma página, porém eles ainda precisam de um ciclo Request/Response entre o browser e servidor. o header Expires elimina esta necessidade deixando bem claro para o browser o prazo de validade do componente, e assim deixando para o browser a mensagem de que ele pode usar a cópia local que ele tem, até a data presente no Expires, sem fazer nenhum Request.
Keep-Alive
O protocolo HTTP é baseado no protocolo Transmission Control Protocol (TCP). No início, nas primeiras implementações de HTTP, cada Request precisava abrir uma nova conexão Socket. Isso era ineficiente pois muitos Requests HTTP de uma mesma página são feitos para um mesmo servidor. As conexões persistentes (Persistent Connections), tambéem conhecidas como Keep-Alive no HTTP/1.0, foram criadas, então, para resolver esta ineficiência de abrir e fechar várias conexões Socket para um mesmo servidor. Portanto, browsers e servidores podem usar o header Connection para indicar o suporte ao Keep-Alive. Tanto o Request como o Response podem conter:
Connection: Keep-Alive
No HTTP/1.1, o header Connection: Keep-Alive não é mais necessário, mas muitos browsers e servidores ainda usam.
No HTTP/1.1, o que é apropriado de ser usado é o chamado Pipelining, que permite múltiplos Requests numa mesma conexão Socket, e é mais performático do que Persistent Connections. Porém, Pipelining não é suportado pelo Internet Explorer, pelo menos até a versão 7 do IE. E também não é ativado por padrão no Firefox até a versão 2. Por enquanto, então, Keep-Alive ainda é a forma mais eficiente de usar conexões socket para HTTP. Ao se tratar de HTTPS, isso é aida mais importante, pois estabelecer uma nova conexão HTTPS é ainda mais demorado.
O protocolo HTTP tem ainda muitos outros detalhes que podem ajudar a tornar suas páginas mais rápidas, mas não vou entrar em outros detalhes aqui.
Este post foi apenas uma visão geral do protocolo HTTP. Não mostrei ainda como aplicar algumas técnicas que fazem uso dos conceitos apresentados aqui. Isso fica para os próximos capítulos desta série. Abcs
Web Sites de Alta Performance, Parte 1: A Regra do 80-20 da uma Página Web
Postado por
Felipe Nascimento
24 de fevereiro de 2009
às
18:42
Este post é o primeiro de uma série que irei denominar de Web Sites de Alta Performance. Esta série é inspirada e baseada no livro High Performance Web Sites de Steve Souders, na posição de Chief Performance Yahoo!. O livro é fino, leve e bastante objetivo. Esta série tem o objetivo de resumir as técnicas apontadas por Souders.
Assim como diversos engenheiros de software que conheço, eu já me dediquei bastante a otimizações no lado do servidor, como melhorias no uso de memória e índices de bancos de dados, etc. Porém, para a maioria de páginas web, menos de 20% do tempo de resposta para o usuário final é gasto levando o HTML de resposta do servidor para o browser. Portanto, ao otimizar algo no lado do servidor, você estará otimizando algo que consome menos de 20% do tempo total de resposta.
Para conseguir resultados visíveis para seus usuários, é preciso atacar a causa dos 80% restantes do tempo de resposta. Esta série mostra conceitos que explicam o funcionamento de páginas web e algumas técnicas capazes de tornar suas páginas mais rápidas.
Analisando a performance de uma página
Para você conseguir ver como uma página qualquer é carregada e o tempo que ela gasta para ser carregada, vou sugerir o uso do browser Chrome do Google. Ele possui uma ferramenta de análise recursos carregados pelo browser (resources). Ao abrir o Chrome, acesse o site que deseja. Vá ao menu cujo ícone é uma folhinha (ao lado direito da barra de endereço do Chrome), selecione Desenvolvedor e em seguida Console Javascript. O Console possui dois itens principais: Elements e Resources. Clique em Resources. Agora, vá para a janela do browser e e dê um Refresh. Após carregar a página novamente, volte para a janela do Console e veja o resultado.
É possível ver muito claramente quais são todos os recursos carregados pelo browser para que a página final seja apresentada corretamente para o usuário: Html da página em si, imagens, arquivos CSS, arquivos Javascript. Cada recurso desse é um request feito ao servidor para que ele seja encontrado e baixado. Uma ferramenta de análise desses recursos sendo baixados é muito importante para podermos ver como nossa página está hoje e como ela estará depois de aplicadas as técnicas que serão expostas nesta série de posts do meu blog. Acho que o Firefox também deve ter algum plugin que fornece este tipo de informação.
É possível ver muito claramente quais são todos os recursos carregados pelo browser para que a página final seja apresentada corretamente para o usuário: Html da página em si, imagens, arquivos CSS, arquivos Javascript. Cada recurso desse é um request feito ao servidor para que ele seja encontrado e baixado. Uma ferramenta de análise desses recursos sendo baixados é muito importante para podermos ver como nossa página está hoje e como ela estará depois de aplicadas as técnicas que serão expostas nesta série de posts do meu blog. Acho que o Firefox também deve ter algum plugin que fornece este tipo de informação.
O que essas ferramentas irão fornecer é uma visão como a da figura abaixo (que é a análise do carregamento da home do www.yahoo.com):
Afinal, porque uma página demora para ser apresentada?
Ao analisar o carregamento de uma página (com uma dessas ferramentas citadas acima), é possível ver que uma página comum (como por ex.: www.yahoo.com), ao ser carregada pela primeira vez no browser (sem nada no cache), gasta pelo menos 80% do tempo de carregamento total com os componentes da página (imagens, arquivos css e javascript, etc). Quando eu digo carregamento total, quero dizer:
- Request de cada componente;
- Requests que não ocorrem em paralelo (scripts não são baixados em paralelo);
- Parse de Html, CSS e Javascript;
- Renderização final
Ver onde que o tempo é gasto é desafiador. Mas ver onde que ele não é gasto é fácil: o tempo de carregamento de uma página não é gasto em sua maioria no download do documento HTML que é gerado pelo processamento do servidor, incluindo lógica de programação no servidor, acesso a banco de dados, etc.
Portanto, a regra para se manter em mente aqui é: APENAS DE 10% - 20% DO TEMPO DE CARREGAMENTO DE UMA PÁGINA É GASTO COM A GERAÇÃO DO HTML QUE VAI PARA O BROWSER. OS OUTROS 80% - 90% SÃO GASTOS CARREGANDO OS DEMAIS COMPONENTES DA PÁGINA.
Servindo JavaScript e CSS com velocidade
Postado por
Felipe Nascimento
5 de fevereiro de 2009
às
13:01
Vale a leitura.
São dicas de como diminuir o tamanho dos arquivos Javascript e CSS, e como fazer algumas coisas para os browsers fazerem o Cache corretamente desses arquivos.
Abcs
Assinar:
Postagens (Atom)