Tomcat classpath/classloader Application aus Tomcat Container starten

Hallo liebe Leut,

hänge an einem Problem. Vielleicht könnt ihr mir helfen.

kurz zur Vorgeschichte. Ich habe ein Linux Cluster, auf diesem soll eine verteilte Hadoop Anwendung laufen. (Hadoop ist wahrscheinlich nicht wichtig für das Problem). Kurz gesagt diese Hadoop Anwendung wird als Jar gestartet. Beim Start werden noch classpath Einträge gesetzt. In etwa so habe ich das immer gestartet:

$ java –cp $(hadoop classpath) : /etc/hadoop/*: /opt/application.jar org.yarnbook.Main –jar /opt/application.jar

Diese Classpath einträge waren wichtig weil sich dort die Config Dateien usw befinden.

Nun hat sich das Vorgehen geändert: Nun starte ich auf (ich nenne ihn mal) “HauptHadoopRechner” einen EmbeddedTomcat der eine Website hostet über die ich dann mit ihm kommuniziere. Auf Knopfdruck soll dann die HadoopApplication gestartet werden. Dies habe ich in etwa so realisiert: statt der ursprünglichen Main Methode starte ich einfach einen neuen Thread mit dem Inhalt der alten MainMethode. Also aus dem Container des Tomcats herraus.

Nun was passiert: er findet die Config Dateien des Hadoop Frameworks usw nicht. Also alles was ich früher im Classpath gesetzt habe. Diese Classpath Einträge habe ich auch schon versucht beim Start des EmbeddedTomcat zu setzen. Ohne Erfolg.

Laut Google läuft es wohl darauf hinaus, dass Tomcat eben seinen eigenen Classpath hat, hat wohl was mit Catalina zu tun.
Die einzige mir sinnvoll vorkommende Lösung im Internet war: innerhalb der embeddedtomcat.jar ist catalina enthalten, darin catalina.properties. Dort habe ich versucht den absoluten Pfad zu setzen. Leider ohne Erfolg.

Hat jemand eine Idee für mich.

In jedem Falle schonmal vielen Dank

Gruß Helmut

Wie startest du den embeddedTomcat? Kannst du nicht bei dessen Start den Classpath um deinen Hadoop CP erweitern?

Hallo freezly,

ersteinmal vielen herzlichen Dank für deine Antwort.

Ich habe es leider immernoch nicht hingekriegt.
Ich starte den mit Spring und Maven, also ich habe eine embeddedtomcat dependency und starte dann per Mavenbefehl spring-boot:run eine Main Methode die einen Application start aufruft.

Ich weiss nicht wie du das meinst. Wo kann ich hier einen classpath erweitern?

Ich versuche zurzeit folgendes: in der embeddedtomcat.jar gibt es ein embeddedtomcatCORE.jar. in diesem gibt es Catalina. und darin gibt es catalina.properties. Dort kann man unter commonLoader einen absoluten Pfad angeben.
Habe es leider nicht hingekriegt.

Aber ich glaube es muss was mit Catalina zu tun haben.

Gruß Helmut

Bei maven wäre es doch möglich einen Einblick in die pom.xml zu gewähren?

Oh natürlich entschuldigung.

pom.xml:


<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <groupId>de.xapio</groupId>
  <artifactId>embeddedtomcatapp</artifactId>
  <packaging>jar</packaging>
  <version>0.0.1-SNAPSHOT</version>
  <name>embeddedtomcatapp Maven Webapp</name>
  <url>http://maven.apache.org</url>
   <parent>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-starter-parent</artifactId>
		<version>1.1.8.RELEASE</version>
	</parent>
  <dependencies>

		<dependency> 
             <groupId>org.springframework.boot</groupId> 
             <artifactId>spring-boot-starter-websocket</artifactId>
             <exclusions>
            <exclusion>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-logging</artifactId>
            </exclusion>
        </exclusions>

             
         </dependency> 

		  <dependency>
		    <groupId>org.springframework.security</groupId>
		    <artifactId>spring-security-web</artifactId>
		    <version>3.2.5.RELEASE</version>
		  </dependency>
		  <dependency>
		    <groupId>org.springframework.security</groupId>
		    <artifactId>spring-security-config</artifactId>
		    <version>3.2.5.RELEASE</version>
		  </dependency>
 		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-messaging</artifactId>
			
		</dependency>

		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-web</artifactId>
			
		</dependency>
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-websocket</artifactId>
			
		</dependency>
		<dependency>
		   <groupId>org.apache.tomcat.embed</groupId>
		   <artifactId>tomcat-embed-websocket</artifactId>
		   <version>7.0.55</version>
		</dependency>
    
    <dependency>
			<groupId>org.apache.hadoop</groupId>
			<artifactId>hadoop-common</artifactId>
			<version>${hadoop.version}</version>
			<scope>provided</scope>
		</dependency>
		<dependency>
			<groupId>org.apache.hadoop</groupId>
			<artifactId>hadoop-yarn-api</artifactId>
			<version>${hadoop.version}</version>
			<scope>provided</scope>
		</dependency>
		<dependency>
			<groupId>org.apache.hadoop</groupId>
			<artifactId>hadoop-yarn-client</artifactId>
			<version>${hadoop.version}</version>
			<scope>provided</scope>
		</dependency>
		<dependency>
			<groupId>org.apache.hadoop</groupId>
			<artifactId>hadoop-yarn-server-nodemanager</artifactId>
			<version>${hadoop.version}</version>
			<scope>provided</scope>
		</dependency>

  </dependencies>
  
  <build>
    <finalName>embeddedtomcatapp</finalName>
     <plugins>
    <plugin>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-maven-plugin</artifactId>
            
            <configuration>
		        <mainClass>de.xapio.server.Application</mainClass>
		        
		      </configuration>
            
        </plugin>
        
 </plugins>

    
  </build>

</project>


ist ein bisschen groß weil ich mehrere frameworks einbinde wie zum beispiel springsecurity etc…

Die Main Klasse beinhaltet lediglich folgendes:

@EnableAutoConfiguration
public class Application {

    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
        System.out.println("Server gestartet");
    }
}```

und das ganze starte ich dann mittels:spring-boot:run (Mavenbefehl, stammt denk ich aus dem spring boot maven plugin)


nunja der tomcat server, die webseite, websockets etc funktionieren auch ganz gut. Ziel des Projekts ist aber eben dieses programm mit dem embeddedtomcat auf dem Master des HadoopClusters zu starten und über die weboberfläche dann verteilte 
Anwendungen im HadoopCluster zu starten. Dies mache ich so: eine nachricht wird vom client per Websockets gesendet und der Websocket Endpoint startet dann einen neuen Thread. Dieser lässt code laufen, welcher -WENN MANN IHN ALS MAIN METHODE JAR AUF DEM MASTER STARTET - erfolgreich die verteilte application startet. Nur funktioniert es eben aus dem tomcatcontainer heraus nicht. er findet das Framework nicht und config dateien nicht.... 
Beim normalen Start würde ich diese Pfade beim start setzen (wie oben beschrieben)

Wie kann ich das hier machen?

Vielen Dank in jedem Falle schonmal für eure Antworten

Gruß Helmut