Pergunta: É possível modificar o WSDL para acrescentar uma operação de atualização de estado de um transporte?
Resposta:
Sim, é possível.
Devem só ter a precaução de não quebrar a compatibilidade do contrato,
ou seja, as operações já existentes devem ser especificadas sem alteração.
Sugere-se que se mude o nome ao ficheiro do contrato para broker.2_0.wsdl.
Pergunta: Como se podem representar dados binários em texto?
Resposta: Podem usar codificação de base 64 para transportar dados binários em texto.
Sugerimos a utilização das seguintes funções:
import static javax.xml.bind.DatatypeConverter.parseBase64Binary; import static javax.xml.bind.DatatypeConverter.printBase64Binary;
Pergunta: É necessário proteger as comunicações entre clientes e broker, e com o UDDI?
Resposta: Não é necessário. O que é pedido é para proteger a comunicação entre broker (transporter-client) e transporter (server).
Pergunta: É necessário replicar o UDDI?
Resposta: Pode-se considerar o UDDI como sendo 100% disponível, não sendo necessário efectuar a sua replicação.
Pergunta:[BOA PRÁTICA] Como partilhar código entre vários programas?
O servidor e o cliente devem partilhar o mínimo de código possível.
No entanto, em alguns casos faz sentido partilhar código (ex. UDDINaming, Handlers, etc).
Nestes casos a melhor prática é criar módulos Maven autónomos, com os respectivos testes, que podem depois ser publicados (mvn install) e usados como dependências através das coordenadas (groupId, artifactId, e version).
Esta separação em módulos promove também o desenvolvimento paralelo de código de diferentes componentes do projeto, dado que diferentes membros da equipa podem estar a trabalhar simultaneamente em diferentes partes do projeto.
Pergunta: Como se podem gerar as chaves e certificados digitais? [atualizada]
Resposta: Os pares de chaves das entidades devem ser gerados manualmente, antes do início do funcionamento da comunicação entre servidores.
Para gerar os certificados podem usar as ferramentas keytool e openssl tal como exemplificado neste script.
Exemplo de resultado.
Documentação:
Creating a Sample CA Certificate,
Signing Certificates With Your Own CA
O script automaticamente importa os certificados para as respectivas keystores, ou seja, todas as entidades têm na sua keystore o certificado da CA, o seu próprio certificado e a sua chave privada. A CA pode simplesmente guardar os certificados das outras entidades em ficheiros individuais ou ter a sua própria keystore os certificados de todas as entidades, o seu próprio certificado e a sua chave privada.
Resumidamente, o que cada entidade deve fazer quando pretende autenticar uma mensagem é:
Pergunta: O que é um ficheiro CSR?
Resposta:
Um ficheiro CSR é um 'Certificate Signing Request' e serve para pedir a uma CA para assinar uma chave pública.
Depois de gerados e assinados os certificados, os CSR já não são necessários (e podem ser eliminados).
Pergunta: O que deve constar do relatório?
Resposta: Consultar a informação publicada sobre o relatório.
Pergunta: As instruções de instalação devem ser atualizados para a segunda parte do projeto?
Resposta: Sim, o ficheiro README.md deve ser atualizado com instruções tendo em conta as funcionalidades pedidas de segurança e de tolerância a faltas.
Pergunta: Porque é que algumas chaves têm que ser distribuídas manualmente antes do arranque do sistema?
Resposta: O sistema, para ser seguro, necessita de ter um ponto de partida para a confiança (uma trust root, raíz de confiança). Só depois é seguro trocar chaves entre servidores, desde que certificadas, cujas assinaturas podem ser verificadas com as chaves que fazem parte da trust root.
Pergunta: É necessário entregar instruções de instalação?
Resposta: Sim, é necessário completar o ficheiro README.md com instruções de instalação do projecto que possam ser seguidas nas máquinas dos laboratórios.
Pergunta: Para que serve o transporter-ws-cli?
Resposta: O projeto transporter-ws-cli serve para:
Pergunta: O que deve fazer a classe ...ClientApplication?
Resposta: Esta classe deve ter um método static main que serve apenas para fazer uma invocação simples do servidor. Sugere-se que faça um ping().
Pergunta: Que testes com mocks fazem sentido no código de SD?
Resposta:
Na primeira entrega de SD
os mocks poderão ser úteis para permitir testes unitários (...Test) em objetos que dependam de serviços remotos.
Concretizando,
os mocks permitirão simular os objetos que representam o UDDI e as Transportadoras.
Pergunta: Em que consiste o retorno da operação requestTransport()?
Resposta: O retorno deve ser o identificador do transporte, que pode ser usado mais tarde para consultar o estado do transporte.
Pergunta: De que forma se pode implementar a simulação do estado do Job na Transportadora?
Resposta: Sugere-se a consulta da documentação das seguintes classes:
A atualização pode também ser feita só quando necessário, ou seja, as transições podem ser despoletadas nas operações que consultam estados dos Jobs.Pergunta:
Como se deve comportar e testar o seguinte web service (do transporter-ws) quando o preço dado é 0 ou 1?
@Override
public JobView requestJob(String origin, String destination, int price)
Resposta:
Este caso extremo não será testado. É válido que uma transportadora, quando recebe um pedido com preço 0 ou 1, proponha preço 0.
Restantes valores de preço deverão obedecer ao especificado no enunciado do projeto.
Pergunta: Quando uma transportadora faz uma proposta, existe um valor máximo para o preço?
Resposta:
Quando uma transportador está num caso em que deve fazer uma proposta (ver regras descritas no enunciado - par-ímpar, etc.)
não é necessário limitar o valor da proposta máxima gerada.
No entanto, se o quiserem fazer, podem estipular um valor máximo que faça sentido, como 1000, por exemplo.
Pergunta: O que deve o Broker retornar ao seu cliente no método requestTransport() no caso de todas as transportadoras devolverem null ?
Resposta: O Broker deve passar o transporte para o estado FAILED e deve lançar UnavailableTransportFault.
Pergunta: E quando deve o Broker retornar ao seu cliente no método requestTransport a exceção UnavailablePriceTransportFault ?
Resposta: O Broker deve atirar a exceção referida quando recebe propostas, mas nenhuma abaixo do preço pedido pelo cliente.
Pergunta: O Broker deve registar-se no UDDI?
Resposta: Sim e deve chamar-se UpaBroker, tal como é referido no enunciado.
Pergunta: Existe algum atalho para a página de laboratórios de SD?
Resposta: Sim, existe este: http://tinyurl.com/leic-sod
Pergunta: Para onde devem ser enviadas as dúvidas sobre o projecto?
Resposta:
As perguntas devem ser enviadas para o endereço correspondente ao curso do aluno:
leti-sod@disciplinas.tecnico.ulisboa.pt
leic-tagus-sod@disciplinas.tecnico.ulisboa.pt
leic-alameda-sod@disciplinas.tecnico.ulisboa.pt
Pergunta:[IMPORTANTE] Existe alguma restrição sobre a directoria de instalação do software?
Resposta:
Sim, infelizmente devido a diversos bugs em ferramentas,
o software não funciona corretamente em pastas cujo caminho tenha
espaços e/ou caracteres acentuados (sobretudo em Windows).
Exemplos de pastas problemáticas:
Dado este problema a sugestão é instalar o software numa pasta como C:\java\.
Pergunta: Devem-se instalar exatamente as versões pedidas ou podem ser outras?
Resposta:
Sim, devem procurar instalar as versões pedidas
de forma a terem um ambiente igual (ou o mais parecido possível) com o ambiente de referência (dos laboratórios).
Se não for possível encontrar a versão exata,
podem instalar a versão mais próxima disponível.
Existem riscos em ter diferenças mas,
na maior parte dos casos, não deverão ser impeditivos da realização do projeto.
Em todo o caso, ao testar os exemplos das aulas será possível detetar se há ou não diferenças relevantes.
Pergunta: Como confirmar se estou a usar as versões certas das ferramentas?
Resposta: Abrir uma consola e executar os seguintes comandos:
$ java -version $ javac -version $ mvn -versionStart Eclipse, go to "Help" menu, select "About Eclipse"
Pergunta: Como confirmar se o PATH está correcto?
Resposta: Abrir uma consola Linux e executar
$ echo $PATHAbrir uma consola Windows e executar
$ echo %PATH%
Pergunta: Porque é que o meu Mac não reconhece o endereço localhost?
Resposta:
As seguintes instruções poderão resolver o problema:
http://www.codepotato.co.uk/2012/07/25/enabling-localhost-on-os-x-mountain-lion/
Pergunta: O meu nome de utilizador tem acentos ou espaços e preciso de mudar a localização do repositório local Maven. Como se faz?
Resposta: O repositório local do Maven é a pasta onde são guardadas todas as dependências obtidas pelo Maven.
Por omissão,
a localização do repositório local é:
~/.m2 (Unix/Mac)
C:\Users\Username\.m2 (Windows)
Para alterar a configuração, editar o ficheiro conf\setting.xml que está na pasta de instalação do Maven (tipicamente apontada pela variável de ambiente M2_HOME).
Não esquecer também de atualizar a configuração do repositório Maven no Eclipse. Aceder a Window - Preferences - Maven - User Settings e indicar a nova configuração.
Pergunta: Como posso consultar o effective POM de um projeto Maven?
Resposta: O effective POM é o resultado da combinação do POM do projeto com os valores das propriedades por omissão. É útil para perceber todas as definições que são assumidas pela ferramenta, como valores de propriedades, por exemplo.
Pode-se consulta através do seguinte comando:
$ mvn help:effective-pom
Pergunta: Existe forma de consultar a árvore de dependências de um projeto Maven?
Resposta: Sim, através do seguinte comando:
$ mvn dependency:tree
Pergunta: Como remover o aviso de character encoding do Maven?
Resposta: Acrescentar a seguinte configuração ao pom.xml:
... <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding> ...
Pergunta: Como remover o aviso "Warning: killAfter is now deprecated" do Maven?
Resposta: Para remover este aviso (inofensivo) pode-se acrescentar a seguinte configuração ao pom.xml:
<plugin> <groupId>org.codehaus.mojo</groupId> <artifactId>exec-maven-plugin</artifactId> ... <configuration> <killAfter>-1</killAfter> ... </configuration> </plugin>
Pergunta: Como definir a versão do Java considerada pelo Maven?
Resposta: Acrescentar a seguinte configuração ao pom.xml:
... <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> ... <configuration> <source>1.8</source> <target>1.8</target> ... </configuration> </plugin>Mais informação na seguinte página: http://maven.apache.org/plugins/maven-compiler-plugin/examples/set-compiler-source-and-target.html
Pergunta: Qual a diferença entre exec:java e appassembler ?
Resposta: mvn exec:java corre dentro do maven e tem os argumentos definidos no pom.xml com bons valores por omissão (opção preferida para desenvolvimento).
mvn package appassembler:assemble corre de forma autónoma do Maven e necessita que sejam indicados os argumentos (opção preferida para demonstração)
target/bin/appassembler/... .bat arg0 arg1 ...Via Eclipse também se pode correr, depois de compilado, definindo-se os argumentos nas "Run Configurations".
Pergunta:[BOA PRÁTICA] É possível criar módulos Maven para partilha de código?
Resposta: Sim, é possível.
Para o fazer,
criar um projeto à parte (ex. my-library).
No pom.xml,
definir as coordenadas groupId (ex. example),
artifactId (ex. my-library) e
version (ex. 1.0-SNAPSHOT).
Para disponibilizar o módulo no repositório Maven local (~/.m2), fazer: mvn install.
Para usar o módulo noutro projeto, basta acrescentar a dependência, indicando as coordenadas groupId, artifactId e version tal como se faz em relação a módulos que estão no repositório Maven central (ex. junit, junit, 4.12).
Pergunta: Como executar o programa Java directamente, sem ser através do Maven ou do Eclipse?
Resposta: Caso existam problemas no processamento de entradas e saídas de um programa (o que é comum acontecer com as aplicações de consola que são executadas a partir de outra ferramenta) sugere-se a seguinte solução, que passa por usar o plug-in appassembler para construir ficheiros de lançamento da aplicação, para Windows e Linux.
Pergunta: Como executar o plug-in appassembler de forma automática na fase install?
Resposta: Acrescentar a seguinte configuração ao pom.xml:
... <plugin> <groupId>org.codehaus.mojo</groupId> <artifactId>appassembler-maven-plugin</artifactId> <version>1.9</version> <executions> <execution> <phase>install</phase> <goals> <goal>assemble</goal> </goals> </execution> </executions> <configuration>
Pergunta: É possível ter POMs hierárquicos? Como se usam?
Resposta: O Maven tem dois conceitos hierárquicos: modules e parent.
<project ...> <!-- the parent relation --> <parent> <groupId>example</groupId> <artifactId>parent</artifactId> <version>1.0.0-SNAPSHOT</version> </parent> <artifactId>module1</artifactId> <!-- the modules --> <modules> <module>submodule1</module> <module>submodule2</module> </modules> </project>
A relação parent indica que configurações de propriedades, repositórios e plug-ins devem ser herdadas do projeto pai.
Um module indica que o subprojeto deve ser incluído no processamento do ciclo de vida do projeto de topo.
Pergunta: Como executar testes de integração (classes terminadas em IT)?
Resposta: Caso não exista ainda a definição (definida no pom pai, por exemplo) será necessário adicionar a configuração do plug-in para testes de integração:
<plugin> <artifactId>maven-failsafe-plugin</artifactId> <version>2.18.1</version> <executions> <execution> <goals> <goal>integration-test</goal> <goal>verify</goal> </goals> </execution> </executions> </plugin>
Pergunta: Como posso ler ficheiros (recursos/resources) da aplicação?
Resposta:
Colocar os ficheiros em src/main/resources
(ou em src/test/resources para testes).
Fazer mvn process-resources e
confirmar que ficheiros adicionados são processados e copiados
para a pasta target.
Se se pretender copiar propriedades definidas no Maven
para estes ficheiros é possível usar a opção
filter.
(usando a etiqueta project/build/resources ou
project/build/testResources no pom.xml).
<project ... ... <build> <resources> <resource> <directory>src/main/resources</directory> <filtering>true</filtering> </resource> </resources> <testResources> <testResource> <directory>src/test/resources</directory> <filtering>true</filtering> </testResource> </testResources> ...
Depois de configurado o pom.xml, no código, é possível aceder a um java.io.InputStream para ler os dados binários.
... InputStream is = this.getClass().getResourceAsStream("/file"); ...Adicionalmente, a classe java.io.ByteArrayOutputStream pode ajudar a lidar com dados de tamanho variável.
Pergunta: Como converter de java.util.Date para javax.xml.datatype.XMLGregorianCalendar? E ao contrário?
Resposta:
De XMLGregorianCalendar para Date:
Date d = xgc.toGregorianCalendar().getTime();De Date para XMLGregorianCalendar:
GregorianCalendar gc = new GregorianCalendar(); gc.setTime(d); XMLGregorianCalendar xgc = DatatypeFactory.newInstance().newXMLGregorianCalendar(gc);
Pergunta: Como fazer cálculos com datas?
Resposta:
Usando a classe Calendar, por exemplo.
Date date = new Date(); Calendar cal = Calendar.getInstance(); cal.setTime(date); cal.add(Calendar.MINUTE, 10); Date newDate = cal.getTime();
Pergunta: Como resolver o seguinte problema na compilação:
Exception in thread "main" java.lang.Error: Unresolved compilation problems
Resposta:
As classes foram corrompidas por diferentes compiladores em simultâneo (por ex. Eclipse e Maven).
Para corrigir ir a Eclipse -> Menu 'Project', 'Clean', 'clean all projects". Depois, correr mvn clean.
Pergunta: Como posso gerar um mock que implementa duas interfaces em simultâneo (ex. MyPortType e BindingProvider) ?
Resposta: Consultar a seguinte página do tutorial de JMockit: Mocking multiple interfaces at the same time.
Pergunta: Nos computadores dos laboratórios do Taguspark em Windows, pode ser necessário instalar mais algum plugin em Eclipse?
Resposta:
Poderá ser necessária a instalação de plugins adicionais se não estiver a conseguir correr o código em Windows 10 nos computadores do Taguspark, para além do que é pedido no guia de software.
Se estiver a ter problemas, adicione e instale todos os Connectors do repositório bitstrings.org m2e Connectors.
- No Eclipse:
Pergunta: Consigo compilar e executar os exercícios de código com o Maven no terminal, mas como o faço dentro do Eclipse?
Resposta:
O Eclipse, depois de instalado seguindo o guia, consegue invocar ações de Maven.
Para um projeto Maven no Eclipse, é necessário criar configurações de Maven Build, como é descrito em seguida:
Package Explorer: Right-click no nome do projeto -> Run As -> Run Configurations... -> Maven Build -> New launch configuration
Pergunta: Já segui todas as instruções no guia de software mas mesmo assim o Eclipse não consegue compilar código Java, o que poderá ser o problema?
Resposta:
É possível que, apesar do JDK estar instalado, o Eclipse esteja a apontar para um módulo JRE (Java Runtime Environment), que apenas
permite executar programas Java mas não compilar.
Para resolver esta questão, por exemplo em Windows, é necessário seguir os seguintes passos:
Ir a Window -> Preferences -> Java -> Installed JREs -> Add...
Indicando o diretório do JDK instalado (seguindo o guia deverá chamar-se jdk1.8.0_72), deve obter o seguinte resultado:
Pergunta: Já configurei o Eclipse para usar o JDK 8, mas mesmo assim quando importo um projeto Maven, o Eclipse assume que é para usar J2SE5 ou outra qualquer versão estranha, como corrigir isto?
Resposta:
Para assegurar que o projeto Maven funciona como esperado, recomenda-se dar uma indicação explícita da versão de JDK a usar para o projeto.
Para resolver esta questão, é necessário especificar a versão no pom.xml do projeto, inserindo as tags maven.compiler.source e maven.compiler.target aninhadas na tag properties.
Exemplo concreto, aplicado ao pom.xml do projeto hello-ws-cli_juddi:
...
</dependencies>
<properties>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
...
<build>
...
Pergunta:
Ao executar o Maven no Ubuntu dá-me o seguinte erro:
[INFO] Scanning for projects...
[INFO]
[INFO] ------------------------------------------------------------------------
[INFO] Building java-app 1.0-SNAPSHOT
[INFO] ------------------------------------------------------------------------
Downloading: https://repo.maven.apache.org/maven2/org/codehaus/mojo/exec-maven-plugin/1.4.0/exec-maven-plugin-1.4.0.pom
[INFO] ------------------------------------------------------------------------
[INFO] BUILD FAILURE
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 0.629 s
[INFO] Finished at: 2016-02-24T11:30:56+00:00
[INFO] Final Memory:8M/110M
[INFO] ------------------------------------------------------------------------
[ERROR] Plugin org.codehaus.mojo:exec-maven-plugin:1.4.0 or one of its dependencies could not be resolved: Failed to read artifact descriptor for org.codehaus.mojo:exec-maven-plugin:jar:1.4.0: Could not transfer artifact org.codehaus.mojo:exec-maven-plugin:pom:1.4.0 from/to central (https://repo.maven.apache.org/maven2): java.lang.RuntimeException: Unexpected error: java.security.InvalidAlgorithmParameterException: the trustAnchors parameter must be non-empty -> [Help 1]
[ERROR]
[ERROR] To see the full stack trace of the errors, re-run Maven with the -e switch.
[ERROR] Re-run Maven using the -X switch to enable full debug logging.
[ERROR]
[ERROR] For more information about the errors and possible solutions, please read the following articles:
[ERROR] [Help 1] http://cwiki.apache.org/confluence/display/MAVEN/PluginResolutionException
Como resolvo este problema?
Resposta:
Executando o seguinte comando na shell:
sudo /var/lib/dpkg/info/ca-certificates-java.postinst configure
Pergunta: Como resolver corrigir a versão do Java na RNL para Java 1.8? Erro:
[ERROR] Failed to execute goal org.apache.maven.plugins:maven-compiler-plugin:3.1:compile (default-compile) on project java-app: Fatal error compiling: invalid target release: 1.8 -> [Help 1]
Resposta:
Executando o seguinte comando na shell:
export JAVA_HOME=/usr/lib64/jdk1.8.0_72/
Pergunta: No Eclipse, quando tento compilar o projeto via Maven, obtenho o seguinte erro (por exemplo, no transporter-ws):
[ERROR] Failed to execute goal org.jvnet.jax-ws-commons:jaxws-maven-plugin:2.3:wsimport (default) on project transporter-ws: Execution default of goal org.jvnet.jax-ws-commons:jaxws-maven-plugin:2.3:wsimport failed: String index out of range: -1 -> [Help 1]Como faço para resolver este erro?
Resposta:
Poderá ser necessário atualizar a configuração do Maven dentro do Eclipse:
Ir a Window -> Preferences -> Maven -> Installations, escolher a instalação com
NAME com o valor "EMBEDDED"
(possivelmente já estará com este valor) e depois escolher a
instalação local (poderá ser necessário carregar em Add... e indicar
o diretório da instalação do Maven conforme os passos executados no guia de software)
Pergunta:
Como validar um ficheiro WSDL no Eclipse?
Resposta: Na janela de 'Project explorer', carregar com o botão direito sobre o ficheiro WSDL. Escolher a opção 'validate' e verifique o resultado em 'Markers'.
Pergunta: A ferramenta de geração de código a partir de WSDL não está a funcionar como esperado.
Resposta: O wsimport pode fornecer pouca informação sobre o erro no WSDL.
Nesse caso, confirme:
Pergunta: Porque é que o código Java gerado para uma operação recebe uma classe de argumento em vez dos parâmetros simples?
Resposta:
O JAX-WS tem diferentes estilos de geração de código Java a partir do WSDL.
Caso o nome da 'operation', 'message' e 'element' sejam iguais no WSDL,
o código Java é gerado no wrapper-style,
ou seja, os parâmetros surgem individualmente na operação.
Caso contrário,
o código é gerado no bare-style e
a operação recebe apenas um argumento,
de uma classe gerada,
que depois contém os argumentos que são lidos com gets.
Pergunta:
Ao tentar desenvolver um Web Service pela abordagem contract-first
o WSDL publicado é diferente e foi (re)gerado automaticamente.
Resposta: O atributo wsdlLocation deve estar correctamente definido e o WSDL deve ser incluído correctamente no pacote da aplicação.
Pergunta:
Sempre que o servidor lança uma exceção,
o cliente recebe uma excepção do tipo javax.xml.ws.soap.SOAPFault e
não o tipo definido no WSDL
Resposta:
A classe gerada para cada exceção definida no WSDL contém diferentes métodos construtores.
No entanto, apenas um dos construtores permite que
a exceção que é lançada remotamente seja recebida pelo cliente como uma exceção do tipo pretendido.
... public MyFault(String message, MyFaultType faultInfo) ...Apenas o construtor que recebe a faultInfo permite que o cliente possa reconhecer correctamente a exceção como sendo do tipo MyFault.
Pergunta: No cliente como se define o endereço do Web Service?
Resposta:
Sim. O seguinte exemplo de código ilustra como:
String endpointAddress = "http://..."; BindingProvider bindingProvider = (BindingProvider) port; MaprequestContext = bindingProvider.getRequestContext(); // retrieve old address String oldEndpointAddress = (String) requestContext.get(ENDPOINT_ADDRESS_PROPERTY); // set new address requestContext.put(ENDPOINT_ADDRESS_PROPERTY, endpointAddress);
Pergunta: Quando lanço o meu Web Service e invoco operações a partir do cliente, os argumentos chegam sempre a null ao serviço. O que se passa de errado?
Resposta: Provavelmente a razão está no atributo endpointInterface da anotação @Webservice da classe que implementa o serviço. Certifique-se que endpointInterface refere a interface que foi gerada pelo wsimport (normalmente essa interface tem o nome que foi atribuído ao portType no WSDL do serviço).
Pergunta: No Eclipse, como remover o aviso: Access restriction: The type 'WebService' is not API (restriction on required library 'C:\Program Files\Java\jre1.8.0_31\lib\rt.jar') sobre a anotação @WebService da classe HelloImpl.java?
Resposta:
É necessário atualizar a versão do JRE System Library associado ao projeto.
No Eclipse, deve-se proceder da seguinte forma:
Pergunta:[IMPORTANTE] Ao tentar executar o meu cliente de Web Service, a invocação remota falha com um erro
Cannot load WSDL from http://...
Resposta: Um cliente JAX-WS necessita de carregar o WSDL para criar um novo ...Service. Podem consultar o código desta classe gerada para confirmar a dependência.
Para minorar este problema,
em vez de se ir buscar o WSDL diretamente ao servidor com HTTP,
pode optar-se por aceder a um ficheiro.
No pom.xml do exemplo abaixo,
vai-se buscar o ficheiro WSDL à pasta do servidor (ws),
que se assume estar ao lado da pasta do cliente (ws-cli).
... <plugin> <groupId>org.jvnet.jax-ws-commons</groupId> <artifactId>jaxws-maven-plugin</artifactId> <version>2.3</version> <executions> <execution> <goals> <goal>wsimport</goal> </goals> </execution> </executions> <configuration> <!-- https://jax-ws-commons.java.net/jaxws-maven-plugin/wsimport-mojo.html --> <wsdlDirectory>${basedir}/../ws/src/main/resources</wsdlDirectory> <wsdlFiles> <wsdlFile>Calc.wsdl</wsdlFile> </wsdlFiles> </configuration> ...
Em alternativa também se poderia copiar o ficheiro WSDL para ws-cli/src/main/resources
Existe ainda a opção -clientjar da ferramenta wsimport. Infelizmente, esta opção não é diretamente suportada pelo plug-in JAX-WS do Maven. Existe uma forma de usar a opção -clientjar mas é pouco elegante e, por esta razão, não é recomendada a sua utilização.
Pergunta: Como resolver o problema com o jaxws maven plugin "Exception in thread "main" java.lang.ClassCastException: java.lang.NoSuchMethodError " ?
Resposta:
... Exception in thread "main" java.lang.ClassCastException: java.lang.NoSuchMethodError cannot be cast to java.lang.Exception at org.jvnet.jax_ws_commons.jaxws.Invoker.main(Invoker.java:87) ...Este problema ainda não está completamente diagnosticado. Felizmente apenas acontece dentro do Eclipse e não na linha de comando.
Pergunta: Como lançar o jUDDI+Tomcat em Linux nos computadores dos laboratorios?
Resposta:
Pergunta:
Ao tentar lançar o jUDDI+Tomcat, obtenho um erro:
BASEDIR not found
Qual o problema?
Resposta:
Provavelmente algum dos shell scripts necessários não está configurado com permissões de execução.
Corrija as permissões dos ficheiros .sh por forma a terem permissões de execução para o seu utilizador.
chmod +x *.sh
Pergunta:
Ao tentar aceder ao jUDDI+Tomcat, obtenho o erro:
... ServletException ... ConfigurationException ... URISyntaxException: Illegal character in path at index
Qual o problema?
Resposta:
Provavelmente o caminho (path) para a pasta de instalação do jUDDI contém espaços ou caracteres acentuados.
Instalar numa path sem espaços nem caracteres acentuados,
por exemplo, em c:\temp\
Pergunta:
Ao tentar ligar-me ao UDDI, recebo a seguinte mensagem de erro:
org.apache.commons.configuration.ConfigurationException: Cannot locate configuration source META-INF/uddi.xml
Qual o problema?
Resposta: O ficheiro uddi.xml serve para definir vários parâmetros que são necessários para a ligação ao UDDI registry (e.g. endereços do registry). O caminho do ficheiro uddi.xml é indicado nas propriedades da ligação ao UDDI registry, como se pode perceber no exemplo dado no tutorial de UDDI. Este erro denota que o pathname indicado para o ficheiro está errado. No caso de um web service, este ficheiro deve ser colocado na directoria WEB-INF/classes dentro do .war. No caso de uma aplicação consola, é necessário definir um pathname que seja correcto.
Pergunta: Como posso limpar a base de dados do jUDDI através da linha de comandos?
Resposta:
Parar jUDDI/Tomcat (executar shutdown.bat / shutdown.sh caso não esteja).
Apagar a directoria bin/target/juddi-derby-test-db.
Pergunta:
Como resolver o seguinte erro do UDDI?
WSDLException (at /definitions/import[1]/definitions/import/definitions/types/xsd:schema/xsd:schema): faultCode=PARSER_ERROR: Problem parsing 'jar:file:/.../uddi-ws-3.1.3.jar!/www.w3.org/TR/xmldsig-core/xmldsig-core-schema.xsd'.: java.net.UnknownHostException: www.w3.org
Resposta:
O jUDDI gera os seus próprios Web Services a partir de diversos WSDL
e um deles refere um schema no domínio www.w3.org.
Isto significa que o jUDDI não funciona correctamente se a máquina não estiver ligada à internet.
Pergunta: O que significam as mensagens da biblioteca SLF4J?
Resposta: As linhas seguintes indicam que a biblioteca de logging SL4J não está incluída no classpath e que por isso as mensagens vão ser ignoradas.
SLF4J: Failed to load class "org.slf4j.impl.StaticLoggerBinder". SLF4J: Defaulting to no-operation (NOP) logger implementation SLF4J: See http://www.slf4j.org/codes.html#StaticLoggerBinder for further details.Estas linhas podem ser ignoradas, a não ser que se pretenda mesmo usar esta biblioteca. Nesse caso, consultar a página da biblioteca.
Pergunta:
Ainda tenhos erros no jUDDI ou wsimport que não são descritos noutras perguntas.
Exemplo 1 : O projecto encontra-se localizado num caminho a começar por "C:\program files"
directory not found: C:\programExemplo 2 : O repositório local do maven encontra-se em "C:\users\André"
Exception in thread "main" java.lang.ClassCastException: java.lang.AssertionError cannot be cast to java.lang.Exception at org.jvnet.jax_ws_commons.jaxws.Invoker.main(Invoker.java:87)Qual é o problema?
Resposta:
JUDDI e wsimport não funcionam bem com espaços e/ou caracteres acentuados na path de instalação (em Windows).
Por exemplo, usar as seguintes directorias poderá dar problemas:
C:\program files C:\users\AndréSugestão:
C:\java\ C:\dev\
Pergunta: Como detectar se um SOAP Handler está a processar uma mensagem que está a entrar ou a sair?
Resposta:
/** * This method checks if the SOAP message in context * is going out of Web Service (outbound - true) or in (inbound - false). */ public static boolean isOutboundMessage(SOAPMessageContext smc) { Boolean outboundProperty = (Boolean) smc.get(MessageContext.MESSAGE_OUTBOUND_PROPERTY); return outboundProperty.booleanValue(); }
Pergunta: Porque é que mesmo depois de substituir a mensagem SOAP por outra nova, esta última não é utilizada?
Resposta: Internamente a biblioteca de Web Services guarda a referência para o objecto SOAPMessage original. Se se substituir a original por uma nova mensagem, não é lançada nenhuma excepção, mas a nova mensagem é ignorada e é usada a original (ou seja, aquela que continua a ser referenciada pelo Web Service). A forma de resolver este problema é manter a mensagem original mas substituir-lhe o conteúdo pelo da nova mensagem. Assim a referência interna da biblioteca de Web Services continua a ser válida.
MessageFactory factory = MessageFactory.newInstance(); SOAPMessage newMessage = factory.createMessage(oldMessage.getMimeHeaders(), inputByteArray); oldMessage.getSOAPPart().setContent(newMessage.getSOAPPart().getContent());
Pergunta: É possível chamar uma operação de um Web Service remoto de dentro do método de um SOAPHandler?
Resposta: Sim. Basta seguir a mesma abordagem usada para qualquer cliente de web service.
Pergunta: A que se deve o erro Caused by: com.sun.xml.ws.util.UtilException: Could not find handler chain file ...Service_handler.xml for class ... ?
Resposta:
O ficheiro de configuração ...Service_handler.xml é gerado pelo wsimport
juntamente com os stubs de invocação.
Devido a um bug
este ficheiro é por vezes apagado.
A forma de contornar o erro é fazer uma compilação limpa: mvn clean compile
ou forçar a inclusão do ficheiro de configuração através da seguinte definição no pom.xml do programa cliente:
<build> <resources> <resource> <directory>src/main/resources</directory> <filtering>true</filtering> </resource> <resource> <directory>src/jaxws</directory> <filtering>true</filtering> </resource> </resources>
Para confirmar que o ficheiro faz parte do código, pode-se consultar a pasta target/classes
Pergunta: Como pode um handler receber parâmetros de configuração? [atualizada]
Resposta: Os handlers podem receber parâmetros via contexto (ver exemplo handler_relay), ou via variável de ambiente definida na VM, ou via ficheiro de propriedades (ver exemplo java-app-config).
Caso se pretenda fazer uma configuração para todos os handlers da mesma classe numa dada VM,
pode optar por uma variável public static na classe do Handler que é preenchida durante o arranque do programa.
Na prática é uma variável global.
Pergunta: Qual é a diferença na configuração de handlers no cliente e no servidor?
Resposta: Ver esta client-ws-handlers-tutorial com ilustrações.
© Docentes de Sistemas Distribuídos,
Dep. Eng. Informática,
Instituto Superior Técnico, Universidade de Lisboa