Translate

sexta-feira, 27 de setembro de 2013

Controlar para enfraquecer

A célebre frase "dividir para conquistar" de Júlio Cesar foi assimilada nos últimos tempos como o ato de pegar um problema, reparti-lo em menores fragmentos e então resolvê-lo por estas partes fragmentadas.

O Henry Ford e suas referências liam a frase de Júlio Cesar pela óptica da organização produtiva e desde então vivenciamos até a década de 80 um período extremamente industrial e construtivo para o cenário mundial.

Naquele tempo existia a carreira profissional para dentro de uma empresa porque suas organizações tinham tamanho em escala de desafios para permitirem isso para profissional ao longo de seu ciclo produtivo.

Porém, com a onda de competições ocorrida nos anos 90 a partir da integração dos mercados internacional, fenômeno chamado de globalização, as organizações se reorganizaram para competição por preços menores, uma espécie de pregão mundial gerado pela abertura de fronteiras internacionais e agravantes como vantagens cambiais que exigiu muitas habilidades das empresas nacionais a desenvolverem uma administração baseada em redução de custo enquanto o governo tentava equilibrar a balança comercial para evitar desvantagens cambiais com algum sucesso todavia.

Me lembro ainda de presenciar reuniões onde algum grande gênio recebia promoções quando achava algum processo passível numa visão leviana de redução de custos e assim tornava-se uma espécie de herói da administração financeira da empresa sem relevar os efeitos sistêmicos de sua solução bitolada e assinada pela empresa.

Este hábito foi tão repetido e massageava tanto o ego dos administradores que viam como forma de competição somente a redução de custos até isso deformar, na década de 2000, o sentido das organizações.

Entramos naquela década e as  empresas ali já reduziam o quadro profissional e acumulavam papéis adicionais aos menos providos de qualificação ainda prematuros sob um discurso de que o profissional era diferenciado, capaz e estava sendo reconhecido com mais papéis e um pouco de aumento. Uma estratégia um tanto quanto promissora para a empresa de fato e para o profissional somente no âmbito utópico, porque apesar de um pequeno aumento, o colocava numa situação de mal estar ou perplexidade quando passava semanas com vários papéis sendo exercidos e acatados como o mínimo a ser feito para permanecer empregado.

A partir dos anos 2000 foi dada a largada para o Você S.A. e empresas, consultores, palestrantes e cientistas pessoais ensinavam-nos a sermos como uma mala de viagem internacional, ou seja, cheios de selos, conhecimentos culturais, do noticiário mundial do último ano para ser relevado como cidadão, habilidades inúmeras e atitude de um tapado garrido convicto numa promoção na escala organizacional.

Bom, mais de 10 anos se passou e as organizações sólidas e verdadeiras foram enterradas na utopia de espaços virtuais e a máxima do você é o guerreiro letrado na arte da guerra e tudo pode naquele que lhe enfraquece. A empresa tornou-se o deserto de muitos profissionais altamente capacitados mas sem perspectiva real dentro de organizações já enxutas e ao mesmo tempo este fenômeno deu aval, em estágio ainda prematuro, para profissionais aceitarem desafios aquém de seus limites porque uma organização reduzida transfere até a responsabilidade de acerto para o profissional não importando se está atitude incompetente da empresa será uma tocha incendiária da motivação do profissional.

O que vivenciamos hoje pode ser por praxe verdadeira o abandono do planejamento social por parte dos nossos governantes, mas as empresas poderiam mudar isso dentro de "casa" se reconhecem sua capacidade de blindar organizações saudáveis em momentos de crise nacional ou competitividade baseada em reduzir custos com demissões em massa ou a transferência de todas responsabilidade ao pequeno quadro profissional sem oferecê-los recursos, não me admira o povo brasileiro ser envaidecido como povo criativo, mas e dai se não conseguimos competir de fato ou fortalecer a nação com soberania?

Só sairemos deste ciclo vicioso quando cada figura chave reconhecer em seu leque de responsabilidades não a produção de bens para consumo, mas o dever de formar pessoas e investir em pessoas para obter no relativo longo prazo resultados em espécie de fortalecimento nacional de mão-de-obras capacitadas e educadas para contribuírem como famílias a exercerem junto com empresas e outras organizações não governamentais uma força regulatória deste governo que aproveita de uma década de decadência para realizar negociações de patrimônios e conquistas do povo brasileiro pela óptica de violarem o povo a fim de um enriquecimento financeiro astronômico até que as empresas e o povo acordem desta letargia.

País soberano depende de mais esforço do que vaidade e cresças em indicadores isolados de análise propositalmente para se criar uma ilusão de economia saudável.

Enquanto isso, o povo nesta sonolência mórbida e cega, alguns aproveitam deste estado para o exercício do controle e zelo pelo inexistente poder a sufocar o estado colaborativo e coletivo pautado da velha máxima de que a união faz sim a força para dividirmos o problema calamitoso o qual passamos para conquistar efetivamente.

Todavia, com a transferência crônica de responsabilidades as empresas sequer reconhecem o pedido sufocado de seu quadro profissional de aliança colaborativa e promovem o exercício reflexivo do mestre e o escravo.

domingo, 8 de setembro de 2013

Converter Java para C++

Durante uma pesquisa corriqueira sobre JVMs, me deparei "acidentalmente" com um conversor de códigos em Java para código em C++ bastante interessante chamado J2C.

O J2C segundo o seu site garante a conversão na maior parte das vezes, certamente, códigos complexos como algorítimos utilizadores de ServerSocketChannel, SocketChannel e outras APIs sofisticadas do Java podem não ser de tanta confiança converter somente sem avaliar o comportamento do código em sua versão C++, mas para algorítimos corriqueiros, a conversão é certa e excelente.

Importante: O Java tem a garbage colletor (gc) e faça uma conversão consciente porque não existe coleta automática de objetos em C++.

O IDE dele é o Eclipse, portanto você deve possuir uma versão recente e compatível com JDK6.

O site do projeto J2C está em https://code.google.com/a/eclipselabs.org/p/j2c/.

A partir dele, você deve:

  1. baixar o JAR mais recente do J2C;
  2. após baixar o JAR, copie-o para a pasta $ECLISE_HOME$\dropins;
  3. abra o Eclipse (no meu caso testei no Windows 7 com o Eclipse Juno);
  4. clique sobre algum projeto Java na janela "Package Explorer";
  5. você deve ver uma opção chamada "Translate to C++".

Esta ferramenta exige como você criar um pasta vazia de mesmo nome do seu projeto precedido pela letra "c". Exemplo: Se você tem um projeto chamado "OlaMundo", então deve ter uma pasta paralela e vazia chamada "cOlaMundo".

A classe Java 6 a seguir é simplesmente feita para ser convertida.

HelloWorld em Java 6 antes da conversão

public class HelloWorld {

public static void main(String[] args) {

System.out.println("Olá mundo!");

}

}

HelloWorld em versão C++ após conversão

// Generated from /UmProjetoJava6/src/HelloWorld.java
#include <HelloWorld.hpp>

#include <java/io/PrintStream.hpp>
#include <java/lang/NullPointerException.hpp>
#include <java/lang/String.hpp>
#include <java/lang/System.hpp>

template<typename ComponentType, typename... Bases> struct SubArray;
namespace java
{
    namespace io
    {
typedef ::SubArray< ::java::io::Serializable, ::java::lang::ObjectArray > SerializableArray;
    } // io

    namespace lang
    {
typedef ::SubArray< ::java::lang::CharSequence, ObjectArray > CharSequenceArray;
typedef ::SubArray< ::java::lang::Comparable, ObjectArray > ComparableArray;
typedef ::SubArray< ::java::lang::String, ObjectArray, ::java::io::SerializableArray, ComparableArray, CharSequenceArray > StringArray;
    } // lang
} // java

template<typename T>
static T* npc(T* t)
{
    if(!t) throw new ::java::lang::NullPointerException();
    return t;
}

HelloWorld::HelloWorld(const ::default_init_tag&)
    : super(*static_cast< ::default_init_tag* >(0))
{
    clinit();
}

HelloWorld::HelloWorld()
    : HelloWorld(*static_cast< ::default_init_tag* >(0))
{
    ctor();
}

void HelloWorld::main(::java::lang::StringArray* args)
{
    clinit();
    npc(::java::lang::System::out())->println(u"Olá mundo!"_j);
}

extern java::lang::Class *class_(const char16_t *c, int n);

java::lang::Class* HelloWorld::class_()
{
    static ::java::lang::Class* c = ::class_(u"HelloWorld", 10);
    return c;
}

java::lang::Class* HelloWorld::getClass0()
{
    return class_();
}

É importante deixar claro que apenas mostrei a versão CPP da conversão, mas a ferramenta J2C gera outras classes e protótipos, subpastas para garantir a conversão. Depois basta ter um compilador de sua necessidade do código em C++ para uma plataforma de sua necessidade.

Para maiores informações, consulte a página oficial do projeto.

Espero ter algum oportunidade para utilizá-la em breve.

quinta-feira, 5 de setembro de 2013

Java - Como obter o id do computador em Windows e Linux Ubuntu

Alguns aplicativos dos tipos desktop, serviço ou licenciadores baseados em processamento fortemente identificado sempre requerem do programador desafios novos para pegar a identidade física do computador.

Quando surge o problema de pegar uma identidade sempre vem a cabeça do programador mais experiente as seguintes perguntas seguidas por mais perguntas:

1) Se eu pegar o macaddress da placa de rede?
2) Mas se a placa de rede queimar ou for trocada de posição?
3) Posso obter o número mais seguro?
4) Será este número o código de série da CPU porque o FCC cuida para não haver repetição de serial, ok?
5) Mas a máquina pode ser virtual e copiada, o macaddress e código da CPU podem ser clonados e assim o FCC perder controle?
6) Talvez o nome da máquina possar ser menos sujeito a alteração e se tiver clone, não vai funcionar na mesma rede, mas será que numa mudança de política de infra-estrutura não vão mudar o nome da máquina legalmente?
7) Como faço para saber se a máquina é virtual?

Não existe uma fórmula mágica para impedir as alterações das identidades de uma máquina, até de seu processador porque pode ser trocado.

Em caso de máquinas virtuais o problema é agravado mais ainda porque elas podem ser clonadas e funcionarem com identidades idênticas em redes (LAN) diferentes.

Por causa disso a única forma segura de garantir uma identidade única é resolvida através de tags ou tokens em forma de hardware para imprimir uma identidade imutável, no entanto, este método pode ser bastante caro e ainda reduzir bastante a atratividade de seu aplicativo num cenário mundial onde as pessoas buscam fazer as coisas no menor tempo, da forma mais simples e mais barata.

Mas não se desespere, para a maior parte dos casos, obter a identidade na primeira execução do software e persistir em um arquivo, registro do sistema operacional ou banco de dados de maneira ofuscada já é o suficiente para congelar e tornar imutável o conjunto de identidades da máquina. Esta técnica pode ser chamada de congelar ou tirar um snapshot dos identificadores da máquina para não sofrerem uma crise caso uma identidade utilizada para validação de sua aplicação seja legalmente mudada por razões diversas.

A classe a seguir se chama ComputerInfo e possui métodos para obter o número de série da CPU, endereço IP do computador, nome do computador, macaddress do primeiro adaptador de rede e se é um adaptador virtual. Não é objetivo discutir a utilização desta classe porque isso vai variar da necessidade de solução de cada um.

A classe ComputerInfo

Crie um arquivo classe chamado ComputerInfo.java:

import java.io.BufferedReader;
import java.io.File;
import java.io.FileWriter;
import java.io.InputStreamReader;
import java.net.InetAddress;
import java.net.NetworkInterface;
import java.net.SocketException;
import java.net.UnknownHostException;
import java.util.Collections;
import java.util.StringTokenizer;

public class ComputerInfo {

public static final String NO_CPU_ID = "XXXXXXXXXX";

private static ComputerInfo ci = null;

private String cpuSerial;
private String hostName;
private String macAddress;
private String hostAddress;
private boolean virtualAdapter;


private ComputerInfo() {

try {

NetworkInterface netInter = null;

if (OS.OS == OS.WINDOWS) {
InetAddress localHost = InetAddress.getLocalHost();
netInter = NetworkInterface.getByInetAddress(localHost);
} else if (OS.OS == OS.LINUX) {
for (NetworkInterface n : Collections.list(NetworkInterface.getNetworkInterfaces())) {
netInter = n;
break;
}
}

byte[] macAddressBytes = netInter.getHardwareAddress();

String macAddress = "";

// Verifica se obteve macaddress
if (macAddressBytes != null && macAddressBytes.length > 5) {

macAddress = String.format(
"%1$02x%2$02x%3$02x%4$02x%5$02x%6$02x", macAddressBytes[0],
macAddressBytes[1], macAddressBytes[2], macAddressBytes[3],
macAddressBytes[4], macAddressBytes[5]).toUpperCase();
}

InetAddress addr = InetAddress.getLocalHost();

this.cpuSerial = getCPUID();
this.hostName = addr.getHostName();
this.macAddress = macAddress;
this.hostAddress = addr.getHostAddress();
this.virtualAdapter = netInter.isVirtual();

} catch (UnknownHostException e) {
System.err.println(e);
} catch (SocketException e) {
System.err.println(e);
}

}

public static synchronized ComputerInfo getIntance() {

if (ci == null) {
ci = new ComputerInfo();
}

return ci;

}

public String getCpuSerial() {
return cpuSerial;
}

public String getHostName() {
return hostName;
}

public String getMacAddress() {
return macAddress;
}

public String getHostAddress() {
return hostAddress;
}

public boolean isVirtualAdapter() {
return virtualAdapter;
}

public static String getCPUID() {

String result = null;

if (OS.OS == OS.WINDOWS) {
result = getCPUIDForWindows();
} else if (OS.OS == OS.LINUX) {
result = getCPUIDForLinux();
}

return result;

}

private static String getCPUIDForWindows() {

StringBuffer result = new StringBuffer();

try {
File file = File.createTempFile("tmp", ".vbs");
file.deleteOnExit();
FileWriter fw = new java.io.FileWriter(file);

StringBuffer vbs = new StringBuffer();
vbs.append("On Error Resume Next \r\n\r\n");
vbs.append("strComputer = \".\"  \r\n");
vbs.append("Set objWMIService = GetObject(\"winmgmts:\" _ \r\n");
vbs.append("    & \"{impersonationLevel=impersonate}!\\\\\" & strComputer & \"\\root\\cimv2\") \r\n");
vbs.append("Set colItems = objWMIService.ExecQuery(\"Select * from Win32_Processor\")  \r\n ");
vbs.append("For Each objItem in colItems\r\n ");
vbs.append("    Wscript.Echo objItem.ProcessorId  \r\n ");
vbs.append("    exit for  ' do the first cpu only! \r\n");
vbs.append("Next                    ");

fw.write(vbs.toString());
fw.close();
Process p = Runtime.getRuntime().exec(
"cscript //NoLogo " + file.getPath());
BufferedReader input = new BufferedReader(new InputStreamReader(p
.getInputStream()));
String line;
while ((line = input.readLine()) != null) {
result.append(line);
}
input.close();
} catch (Exception e) {

}

if (result == null || result.toString().trim().length() < 1 ) {
result = new StringBuffer();
return NO_CPU_ID;
}

return result.toString().trim();

}

private static String getCPUIDForLinux() {

String result = null;

try {

Process p = Runtime.getRuntime().exec("dmidecode -t 4");

BufferedReader input =
new BufferedReader
(new InputStreamReader(p.getInputStream()));

String line;

while ((line = input.readLine()) != null) {
if (line.length()>3 && line.substring(0, 3).equals(("ID:"))) {
StringTokenizer tokenizer = new StringTokenizer(line, ":");
line = tokenizer.nextToken();
result = tokenizer.nextToken();
}
}
input.close();

if(result==null || result.trim().length()==0) {
result=NO_CPU_ID;
}
}
catch(Exception e){
System.err.println(e);
}
return result.trim();
}

}

A enum OS utilizada como dependência

Crie um arquivo enum (não é classe) chamado OS.java:

public enum OS {

WINDOWS("windows"), LINUX("linux");

public static final OS OS;

private static DGLog logger = new DGLog(br.com.digicon.dnserver.util.OS.class);

private String name;

static {
String tempOS = System.getProperty("os.name"); 

if(tempOS==null) {
tempOS = "N/A";
} else {
tempOS = tempOS.trim().toLowerCase();
}

if(tempOS.indexOf(WINDOWS.name)!=-1){
OS = WINDOWS;
} else if(tempOS.indexOf(LINUX.name)!=-1){
OS = LINUX;
} else {
OS=null;
logger.error("O sistema operacional %s não é compatível a aplicação", tempOS);
}
}
OS(String os) {
name = os;
}

public String toString() {
return this.name;
}

}

Obs.: Esta classe é de autoria do Rafael Lima que contribuiu para a melhoria de ComputerInfo.

Testes da classe ComputerInfo

Agora vamos testar com um método main para isso:

public static void main(String args[]) {

ComputerInfo cii = ComputerInfo.getIntance();

System.out.println(cii.getCpuSerial());
System.out.println(cii.getHostAddress());
System.out.println(cii.getHostName());
System.out.println(cii.getMacAddress());
System.out.println(cii.isVirtualAdapter());
}

Resultados

Após obter a instância por meio de uma função singleton getInstance(), a série de invocações de métodos para obtenção dos identificadores do computador gerou a seguinte sequência de resultados:

BFEBFBFF000300A9
192.168.0.8
BRE1010
005056C00001
false

Boa sorte!