TomCat não encontra WEBService

Bom dia a todos

Estou tendo um problema no tomcat em um servidor, vou descrever como estou fazendo isso.

Em minha maquina local eu uso:

-Netbeans versão full 8.1 (já tentei com uma anterior)
-java jdk 1.8.0-71
-Apache Tomcat 8.0.27

Em meu servidor (Digital Ocean) eu uso:

-Ubuntu 15.10 x64
-Tomcat 8.0.30

As duas maquinas possuem o web.xml exatamente iguais, inclusive a cópia que o netbeans faz dentro da pasta “users”.

No Netbeans tentei fazer o serviço da seguinte maneira

  • Novo Projeto > Java WEB > Aplicação Web
    Escolho o Tomcat 8.0.27 e o java EE 7 e clico em finalizar
  • Com o botão direito em cima do projeto escolho Novo > WEB service, coloco o nome do pacote e finalizo, depois aparece uma mensagem e clico em sim para oferecer suporte ao JSR-109

Quando realizo um teste clicando no projeto e em run ou executar o tomcat é aberto no navegador e tudo ocorre normalmente, quando abro o método ele mostra o link para acesso ao XML onde posso ver como acessar o método. Então mando o Netbeans construir a aplicação para gerar o .WAR

Se eu carregar esse .WAR pelo tomcat local na porta 8080(Esse não carrega pelo Netbeans, o Netbeans vai pela 8084) ele funciona exatamente igual o que vai pela porta 8084.

Se eu carregar esse WAR no Tomcat da Digital Ocean ele exibe a seguinte mensagem.

HTTP Status 404 - /MyWebService/

type Status report

message /MyWebService/

description The requested resource is not available.

Apache Tomcat/8.0.30

Já tentei passar o WAR direto pelo ssh, passei algumas pastas que o netbeans gera. Como já disse anteriormente os web.xml que ficam na pasta config do tomcat são exatamente iguais. A configuração de permissão de pastas no ubuntu são as mesma que são utilizadas no tutorial da Digital Ocean.

Agora estou na dúvida do que esta afetando a abertura deste aplicativo.

Olá

Alguém sabe o que posso fazer?

Alterei algumas configurações e vi que havia uma incompatibilidade com o java através do log do tomcat, então coloquei o servidor na versão 1.8.0_72 assim como na maquina local e voilá, a versão que tinha feito funcionou, então voltei ao sistema local para fazer um novo teste, adivinha? o local simplesmente parou de funcionar.

Resolvi reinstalar tudo, removi o Netbeans da minha maquina juntamente com o java e reinstalai e reconfigurei o servidor.

Acabei voltando a estaca zero, no local funciona e no servidor não, e não consigo nem mesmo ver algum erro pois o tomcat não grava log algum.

Alguma ideia do que posso fazer? Tenho outra alternativa de comunicação dessa maneira entre cliente e servidor que não apresenta esse tipo de problema?

Olá, acho que o tomcat é incompativel ou problematico com o java 8:

tomcat.apache.org/whichversion.html

Tente usar outras versões, do jdk ou tomcat

Obrigado @Phelps
Então, consegui fazer funcionar o webservice com o Java 8 mesmo, aparentemente tenho que usar o mesmo relase na maquina local e no servidor web, percebi também que o tomcat dura em torno de 500 a 750 segundos para compilar o arquivo java até que eu possa usar.

Agora surgiu outro problema. Preciso usar este servidor para armazenar alguns dados, para isso instalei o Postgresql no servidor.

Já consigo fazer CRUD normalmente na maquina local, porém no servidor não consigo inserir nada.
Tem algum log que posso acompanhar erros do WebService durante a execução dele?

Você que fez o web service ?

Certo, estou usando uma classe para testar o funcionamento do WebService, atualmente tenho a seguinte estrutura no WebService

As classes são estas:

DAO - inserção dos dados

 package Dao;

 import VO.ClienteVO;
 import java.sql.PreparedStatement;
 import java.sql.SQLException;

 public class ClienteDAO {

    public void create(ClienteVO cliente) {
        Conexao conexao = null;
        PreparedStatement stmt = null;
        String sql = "insert into demo (nome) values (?) ";
        
        conexao = new Conexao();
        
        try{
            stmt = conexao.getConexao().prepareStatement(sql);
            stmt.setString(0, cliente.getNome());
            
            stmt.execute();
            stmt.close();
        } catch (SQLException e) {
            System.out.println("erro ao inserir.  "+e);
            e.printStackTrace();
        } finally {
            conexao.desconectar();
        }
     }            
   } 

Percebi que o sistema apresentou erro na seguinte linha

stmt = conexao.getConexao().prepareStatement(sql);
stmt.setString(0, cliente.getNome());
  • já tentei também com posição numero 1 no stmt.setString

Classe de conexão

package Dao;

import java.sql.Connection;
import java.sql.DriverManager;

public class Conexao  extends Dados{
    
    private Connection conexao;
	
	public Conexao(){ 
		super();
		conectar();
	}
	
	public Connection getConexao(){
		return conexao;
	}
	
	private void conectar(){
            Dados dados = new Dados();
            try{
                    Class.forName(DRIVER).newInstance();
                    this.conexao = DriverManager.getConnection(URL, USER, PWD);			
            }catch (Exception e){
                    System.out.println("Problema ao conectar-se com o banco de dados "+dados.URL+":"+e);
            }
	}
	
	public void desconectar(){
		try{
		      if(this.conexao != null){
		           this.conexao.close();
		      }
		}catch(Exception e){
			System.out.println("Problemas ao desconectar-se com o banco de dados, ou ja esta desconectada:"+ e);
		}
	}  

E nesta classe se encontra os dados de conexão

package Dao;

public class Dados {
    
    	public final String DRIVER = "org.postgresql.Driver";
	public final String USER = "postgres";
	public final String PWD = "1234";  //alterei a senha lá dentro do postgres e usei ela aqui
	public final String PORTA = "5432";
	public final String ENDERECO = "localhost";
	public final String BANCO = "test";
	public final String URL = "jdbc:postgresql://"+ENDERECO+":"+PORTA+"/"+BANCO;
        
}

Nesta classe fica o WebService

package hg;

import Dao.ClienteDAO;
import VO.ClienteVO;
import javax.jws.WebService;
import javax.jws.WebMethod;
import javax.jws.WebParam;

@WebService(serviceName = "Test")
public class Test {

    /**
     * This is a sample web service operation
     */
    @WebMethod(operationName = "hello")
    public String hello(@WebParam(name = "name") String txt) {
        ClienteDAO dao = new ClienteDAO();
        ClienteVO c = new ClienteVO();
        c.setNome(txt);
        try{
            dao.create(c);  
        }catch(Exception e){
            return "Hello " + txt + " ! - erro: "+e;
        }
        return "Hello " + txt + " !";
    }
}

Vamos la, quando você diz "Percebi que o sistema apresentou erro na seguinte linha"
Qual o erro ?
E o certo é

stmt.setString(1, cliente.getNome());

A conexão com o banco está ok ?
Use o

stmt.executeUpdate();

http://docs.oracle.com/javase/6/docs/api/java/sql/PreparedStatement.html

E isso também fica no finally

stmt.close();

E de preferência assim

if(stmt.close != null)
stmt.close;

E por ultimo para você não ficar dependendo do log do container (catalina.out), e não ficar perdido sobre o que está acontecendo coloca um log4j no dao/webservice
http://logging.apache.org/log4j/2.x/

Obrigado @igomes

Então, dei uma estudada no log4j, porém é difícil de entender o funcionamento dele hahaha, a maioria dos exemplos e tutoriais na internet são muito incompletos, por exemplo, foi difícil achar onde devia colocar o arquivo .properties.

Fiz um pequeno teste antes e consegui gerar o log.

Basicamente adicionei o “log4j-1.2-api-2.5.jar” na biblioteca de um novo projeto. o código ficou da seguinte maneira:

 package javaapplication1;

  import org.apache.log4j.*;

  public class TesteLog { 

    private static final Logger log = Logger.getLogger(TesteLog.class);
     
    public static void main(String[] args) {
        try {
            PropertyConfigurator.configure("log4j.properties");
        }
        catch (Exception e) {
                e.printStackTrace();           
        }
        
        Logger logger = Logger.getLogger("lopes");
        logger.info("iniciando aplicação");
        logger.debug("debug here");
    }
        
 }

Na pasta principal do projeto eu coloquei o arquivo log4j,properties:

#### Usando 2 appenders, 1 para logar no console, outro para um arquivo
log4j.rootCategory=WARN,stdout,fileOut
#ordem: DEBUG – INFO – WARN – ERROR – FATAL
log4j.category.lopes=DEBUG
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%5p [%t] (%F:%L) – %m%n
log4j.appender.fileOut =org.apache.log4j.RollingFileAppender
log4j.appender.fileOut.File=log.log
log4j.appender.fileOut.MaxFileSize=100KB
log4j.appender.fileOut.MaxBackupIndex=1
log4j.appender.fileOut.layout=org.apache.log4j.PatternLayout
log4j.appender.fileOut.layout.ConversionPattern=%d [%t] %5p %F:%L – %m%n

Usando esta configuração consegui gerar o log na maquina local, porém não sei onde coloco o arquivo lá no servidor, alias, devo colocar o properties no servidor também?.

Quando tento rodar tenho a seguinte mensagem no console do NetBeans

Exception in thread "main" com.sun.xml.internal.ws.fault.ServerSOAPFaultException: Client received SOAP Fault from server: org/apache/logging/log4j/message/Message Please see the server log to find more detail regarding exact cause of the failure.

Obrigado pela ajuda até o momento.

arquivos de configuração fica em src/main/resources
Isso já é mapeado automaticamente e o log é gerado.

Certo

na pasta C:…\Documents\NetBeansProjects\JavaApplication1\src\javaapplication1
crio uma nova pasta chamada “resources” e coloco lá dentro o arquivo de configuração.

Eis um problema, se é uma configuração padrão eu posso remover a linha seguinte

 try {
        PropertyConfigurator.configure("log4j.properties");
   }
   catch (Exception e) {
        e.printStackTrace();           
   }

Neste caso recebo a seguinte mensagem

run:
log4j:WARN No appenders could be found for logger (lopes).
log4j:WARN Please initialize the log4j system properly.
log4j:WARN See http://logging.apache.org/log4j/1.2/faq.html#noconfig for more info.
CONSTRUÍDO COM SUCESSO (tempo total: 0 segundos)

Eu tentei colocando dessa maneira e funcionou, a pergunta é, esta configuração é compilada automaticamente para o arquivo .WAR que vou mandar para o tomcat?

try {
    PropertyConfigurator.configure("src/javaapplication1/resources/log4j.properties");
    }
    catch (Exception e) {
           e.printStackTrace();           
    }

Desculpe, não vi que estava usando netbeans, eu falei esse diretório de acordo com o eclipse.
Sim, nos casos que eu gero o .war a configuração do log vai junto e é gerado normalmente.
Faz o deploy do war, e entra no diretório que ele vai gerar, e ve se está dentro de WEB-INF/classes, da uma fuçada la

Ótimo, parece que estou avançando, ainda parece difícil, hahahaha

Fiz algumas mudanças, parece que o problema era na localização do arquivo properties, acredito que ele não tem uma pasta padrão ou algo assim, então fiz a troca do código seguinte.

PropertyConfigurator.configure("src/javaapplication1/resources/log4j.properties");

por

PropertyConfigurator.configure(getClass().getResource("/resources/log4j.properties"));

desse modo a estrutura do aplicativo do servidor ficou assim:

Quando testo no localmente em meu tomcat, o log é criado normalmente, porém no servidor Linux do DigitalOcean, não.

O arquivo properties também teve uma modificação, agora ele ficou com a seguinte linha alterada.

log4j.appender.fileOut.File=${catalina.home}/log.log

basicamente eu coloquei o comando ${catalina.home}

Algo que talvez influencie seria as permissões de pasta no servidor.

Então tentei alterar a linha log4j.appender.fileOut.File para salvar em outra pasta, por exemplo em

/opt/tomcat/logs

voilá, funcionou hehehe. Vamos ver se consigo arrumar a conexão com o banco agora

Obrigado

Com certeza consegue, porque agora com as informações dos logs, você sabe o que realmente acontece na aplicação, o log é seu amigo :slight_smile: hehe