sexta-feira, 30 de novembro de 2012

JAXB : unexpected element (uri:"http://...", local:"..."). Expected elements are (none)

Após a geração do código Java com o utilitário xjc a partir dos XSDs, e efectuado o código de marshall/unmarshall, ao usar o respectivo código ocorrem erros como os a seguir descritos.

Unmarshall


Erro durante o unmarshall:

unexpected element (uri:"http://.../.../...", local:"MinhaBase"). Expected elements are (none)


Aparentemente poderá ser um problema no XML a descodificar. Contudo se se tiver a certeza que o problema não está no XML a descodificar, então poderá estar a ocorrer um problema relacionado com a ausência da anotação @XmlRootElement na classe base do esquema gerado. Para verificar isto basta abrir a classe base do esquema gerado e verificar se a tag @XmlRootElement está presente. Se estiver o problema é outro que o descrito a seguir.

Resumidamente, isto não é um bug do JAXB. A ausência da anotação está relacionada com a impossibilidade do xjc determinar com exactidão qual a classe raiz do esquema. Em caso de dúvida o xjc não coloca esta tag.

A solução não é nada complicada.

Basta alterar a linha de código (onde está reader poderá estar outro tipo qualquer que seja aceite):

resultadoUnmarshal = (MeuTipoBase) unmarshaller.unmarshal(reader);

Por:

JAXBElement root = unmarshaller.unmarshal(new StreamSource(reader), MeuTipoBase.class);
resultadoUnmarshal = root.getValue();



Marshall

Erro durante o marshall:

com.sun.istack.internal.SAXException2: unable to marshal type "pt.MeuTipoBase" as an element because it is missing an @XmlRootElement annotation

Aqui nota-se claramente que o problema está relacionado com a falta da anotação @XmlRootElement na classe base. Ver este artigo para mais detalhes.

A solução aqui é também simples.

Em primeiro lugar é necessário abrir a classe ObjectFactory onde está a classe MeuTipoBase.

Procurar por algo semelhante a

@XmlElementDecl(namespace = "http://.../.../...", name = "MinhaBase")
public JAXBElement create
MinhaBase(MeuTipoBase, value) {
        return new JAXBElement<
MeuTipoBase>(_MINHA_BASE_QNAME, MeuTipoBase.class, null, value);
}


Ver a classe ObjectFactory facilita na obtenção dos parametros correctos para o objecto QName que terá de ser criado.


No nosso código substituir a linha (ou linha semelhante)

marshaller.marshal(instanciaAcodificar, System.out);

Por

marshaller.marshal(new JAXBElement(new QName("http://.../.../..", "MinhaBase"), MeuTipoBase.class, null, instanciaAcodificar), System.out);


Os parametros usados para criar a instância de QName são as que estão na linha do ObjectFactory

@XmlElementDecl(namespace = "http://.../.../...", name = "MinhaBase")


A não ser que o problema esteja entre a cadeira e o teclado, terão estes problemas resolvidos.

sexta-feira, 23 de novembro de 2012

Como não executar testes no maven

Por vezes é necessário não executar os testes num projecto maven. 
Ou porque não é o ambiente apropriado, ou porque se está com pressa e não se quer que 
os testes executem, etc.
 
Através da linha de comandos é simples.
Basta especificar a opção: -DskipTests

Caso se esteja por exemplo no Eclipse e se esteja com problemas com falhas nos testes 
e se quer que o maven do Eclipse não execute os testes, então pode-se criar uma nova 
configuração de Run para o maven e aí indicar que se quer saltar os testes.
 

Para evitar no próprio projecto (pom.xml) que os testes sejam executados, basta 
incluir na parte dos plugins o seguinte bloco:

 
 <plugin>
     <groupId>org.apache.maven.plugins</groupId>
     <artifactId>maven-surefire-plugin</artifactId>
     <version>2.12</version>
     <configuration>
       <skipTests>true</skipTests>
     </configuration>
   </plugin>

quinta-feira, 22 de novembro de 2012

Obter conteúdo de um CLOB (de texto) em Oracle SQL

Maneira simples de se ver o que está num CLOB (desde que seja um CLOB de texto).

SELECT DBMS_LOB.substr(coluna_clob, 3000)
FROM tabela_com_clob 

Problemas de build no maven

Durante a execução de mvn clean install ocorre o erro seguinte:


Downloading: https://........................pom
 

Exception in thread "pool-1-thread-1" ---------------------------------------------------java.lang.NoSuchMethodError: org.apache.maven.wagon.shared.http4.AbstractHttpClientWagon.getReadTimeout()I

Este erro ocorre devido a um bug na versão do maven 3.0.3. A solução é actualizar o maven para a versão 3.0.4 (ou superior caso já exista).