CSV Reporting with Java and XML

classic Classic list List threaded Threaded
12 messages Options
Reply | Threaded
Open this post in threaded view
|

CSV Reporting with Java and XML

somemightsay
Camel 2.4
Spring 3.0.3

I apologise in advance if this is asking to much but I've been looking for help with this for a long time and still cannot find an answer.

I have a program which pulls data from a database and reports it to a CSV file. Simple enough.

I have the database info defined in a Camel-Context.xml file and a java class holds the routes code. The sql query and database login info are in external properties files.

The program was inicially from a camel example and was fully in the XML file, including the sql query etc. That originally ran with the 'Main' class in org.apache.camel.spring and after all these changes it still runs correctly as the run configuration with that class.

But when I'm putting it into a JAR it does not, and complains about not being able to find the class in the manifest. If I run this java class as the run config it only outputs the sql query and the logging (which i have removed, to save space below) and does not interact with the XML file at all. I think the best way to fix this would be to make the java class pull the defined data it needs from the XML file but I do not know how to do this.

It's rather annoying that it works so perfectly using the Main class in eclipse but not in a jar.

Thanks.

JAVA CLASS

package com.test.vprtacticalreports.routes;

import java.io.FileInputStream;
import java.util.Properties;
import org.apache.log4j.Logger;
import org.apache.camel.builder.RouteBuilder;
import org.apache.camel.dataformat.csv.CsvDataFormat;

public class Camelroutes extends RouteBuilder {

        public void configure() throws Exception {
                String query;
                Properties props = new Properties();

                try {
                        props.load(new FileInputStream("../vpr-tactical-report/src/main/resources/testquery.properties"));
                        query = props.getProperty("query");
                       
                        from("reportInputDir").startupOrder(1).to("reportOutputDir");
                               
                        CsvDataFormat csv = new CsvDataFormat();

                        from("cronSchedule")
                        .startupOrder(2)
                        .setBody(constant(query))
                        .to("jdbc:vprsitdb")
                        .marshal(csv)
                        .to("reportTargetDir");
                        System.out.println(query);
                }
                catch (Exception e) {
                }

        }
        public static void main(String[] args){
                try {
                        new Camelroutes().configure();
                } catch (Exception e) {
                        e.printStackTrace();
                }
        }

}


XML FILE


<?xml version="1.0" encoding="UTF-8"?>
        <beans xmlns="http://www.springframework.org/schema/beans" 
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
        xsi:schemaLocation="
       http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
       http://camel.apache.org/schema/spring http://camel.apache.org/schema/spring/camel-spring.xsd"> 

        <bean
                class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer"> 
                <property name="ignoreUnresolvablePlaceholders" value="true" /> 
                <property name="locations"> 
                        <list> 
                                <value>classpath:application.properties</value> 
                                <value>classpath:database-sit.properties</value> 
                        </list> 
                </property> 
        </bean> 
       
       
        <camelContext id="camel" trace="true"
                xmlns="http://camel.apache.org/schema/spring"> 
               
                <packageScan> 
      <package>com.test.vprtacticalreports.routes</package> 
      </packageScan> 
               
               
                <endpoint id="reportInputDir" uri="file://csv/input/?noop=true" /> 
                <endpoint id="reportOutputDir" uri="file://csv/output" /> 
                <endpoint id="reportArchiveDir"
                        uri="file://csv/archive/?fileName=${date:now:yyyyMMdd_kkmmss}_${reportName}" /> 
                <endpoint id="cronSchedule" uri="quartz://report?cron=${cronSchedule}" /> 
                <endpoint id="reportTargetDir"
                        uri="file://csv/output/?fileExist=Append&fileName=${reportName}"/> 
       
    </camelContext> 
       
        <bean id="vprsitdb"
                class="org.springframework.jdbc.datasource.DriverManagerDataSource"> 
                <property name="driverClassName" value="${driverClassName}" /> 
                <property name="url" value="${url}" /> 
                <property name="username" value="${username}" /> 
                <property name="password" value="${password}" /> 
        </bean> 

        <bean id="vprdevdb"
                class="org.springframework.jdbc.datasource.DriverManagerDataSource"> 
                <property name="driverClassName" value="${driverClassName}" /> 
                <property name="url" value="${url}" /> 
                <property name="username" value="${username}" /> 
                <property name="password" value="${password}" /> 
        </bean> 
       
</beans>
Reply | Threaded
Open this post in threaded view
|

Re: CSV Reporting with Java and XML

Willem.Jiang
Administrator
If you want to start a camel route without using
org.apache.camel.spring.Main or Spring application context, you need to
create a camel context yourself, then put the route into the camel
context. and start the camel context.

There is a good example[1] in the last page of Camel in Action chapter one.

[1]http://www.manning.com/ibsen/Camel_ch01_update.pdf

Willem

somemightsay wrote:

> Camel 2.4
> Spring 3.0.3
>
> I apologise in advance if this is asking to much but I've been looking for
> help with this for a long time and still cannot find an answer.
>
> I have a program which pulls data from a database and reports it to a CSV
> file. Simple enough.
>
> I have the database info defined in a Camel-Context.xml file and a java
> class holds the routes code. The sql query and database login info are in
> external properties files.
>
> The program was inicially from a camel example and was fully in the XML
> file, including the sql query etc. That originally ran with the 'Main' class
> in org.apache.camel.spring and after all these changes it still runs
> correctly as the run configuration with that class.
>
> But when I'm putting it into a JAR it does not, and complains about not
> being able to find the class in the manifest. If I run this java class as
> the run config it only outputs the sql query and the logging (which i have
> removed, to save space below) and does not interact with the XML file at
> all. I think the best way to fix this would be to make the java class pull
> the defined data it needs from the XML file but I do not know how to do
> this.
>
> It's rather annoying that it works so perfectly using the Main class in
> eclipse but not in a jar.
>
> Thanks.
>
> JAVA CLASS
>
> package com.test.vprtacticalreports.routes;
>
> import java.io.FileInputStream;
> import java.util.Properties;
> import org.apache.log4j.Logger;
> import org.apache.camel.builder.RouteBuilder;
> import org.apache.camel.dataformat.csv.CsvDataFormat;
>
> public class Camelroutes extends RouteBuilder {
>
>         public void configure() throws Exception {
>                 String query;
>                 Properties props = new Properties();
>
>                 try {
>                         props.load(new
> FileInputStream("../vpr-tactical-report/src/main/resources/testquery.properties"));
>                         query = props.getProperty("query");
>                        
>                        
> from("reportInputDir").startupOrder(1).to("reportOutputDir");
>                                
>                         CsvDataFormat csv = new CsvDataFormat();
>
>                         from("cronSchedule")
>                         .startupOrder(2)
>                         .setBody(constant(query))
>                         .to("jdbc:vprsitdb")
>                         .marshal(csv)
>                         .to("reportTargetDir");
>                         System.out.println(query);
>                 }
>                 catch (Exception e) {
>                 }
>
>         }
>         public static void main(String[] args){
>                 try {
>                         new Camelroutes().configure();
>                 } catch (Exception e) {
>                         e.printStackTrace();
>                 }
>         }
>
> }
>
>
> XML FILE
>
>
> <?xml version="1.0" encoding="UTF-8"?>
>         <beans xmlns="http://www.springframework.org/schema/beans"
>         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
>         xsi:schemaLocation="
>        http://www.springframework.org/schema/beans
> http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
>        http://camel.apache.org/schema/spring
> http://camel.apache.org/schema/spring/camel-spring.xsd">
>
>         <bean
>                
> class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
>                 <property name="ignoreUnresolvablePlaceholders" value="true"
> />
>                 <property name="locations">
>                         <list>
>                                
> <value>classpath:application.properties</value>
>                                
> <value>classpath:database-sit.properties</value>
>                         </list>
>                 </property>
>         </bean>
>        
>        
>         <camelContext id="camel" trace="true"
>                 xmlns="http://camel.apache.org/schema/spring">
>                
>                 <packageScan>
>       <package>com.test.vprtacticalreports.routes</package>
>       </packageScan>
>                
>                
>                 <endpoint id="reportInputDir"
> uri="file://csv/input/?noop=true" />
>                 <endpoint id="reportOutputDir" uri="file://csv/output" />
>                 <endpoint id="reportArchiveDir"
>                        
> uri="file://csv/archive/?fileName=${date:now:yyyyMMdd_kkmmss}_${reportName}"
> />
>                 <endpoint id="cronSchedule"
> uri="quartz://report?cron=${cronSchedule}" />
>                 <endpoint id="reportTargetDir"
>                        
> uri="file://csv/output/?fileExist=Append&fileName=${reportName}"/>
>        
>     </camelContext>
>        
>         <bean id="vprsitdb"
>                
> class="org.springframework.jdbc.datasource.DriverManagerDataSource">
>                 <property name="driverClassName" value="${driverClassName}"
> />
>                 <property name="url" value="${url}" />
>                 <property name="username" value="${username}" />
>                 <property name="password" value="${password}" />
>         </bean>
>
>         <bean id="vprdevdb"
>                
> class="org.springframework.jdbc.datasource.DriverManagerDataSource">
>                 <property name="driverClassName" value="${driverClassName}"
> />
>                 <property name="url" value="${url}" />
>                 <property name="username" value="${username}" />
>                 <property name="password" value="${password}" />
>         </bean>
>        
> </beans>

Reply | Threaded
Open this post in threaded view
|

Re: CSV Reporting with Java and XML

somemightsay
Thanks for the reply.

The thing is, I do want to use org.apache.camel.spring.Main to start the route, but how do you allow this class to be the run configuration when running from a JAR?

I'm not understanding how I can run it perfectly well in eclipse, yet I cannot choose to use that as the run configuration when creating a Jar.
Reply | Threaded
Open this post in threaded view
|

Re: CSV Reporting with Java and XML

somemightsay
Actually, I have used your advice and followed the example in the link you provided.

But I'm assuming that is creating a new CamelContext from within the Java class? That would mean having to add al the enpoints, beans etc to the class.

Is there a way to pull in my existing CamelContext?

Basically what I would be needing is PackageScan, but for an XML to Java class rather than the other way around.
Reply | Threaded
Open this post in threaded view
|

Re: CSV Reporting with Java and XML

Willem.Jiang
Administrator
In reply to this post by somemightsay
somemightsay wrote:
> Thanks for the reply.
>
> The thing is, I do want to use org.apache.camel.spring.Main to start the
> route, but how do you allow this class to be the run configuration when
> running from a JAR?

You can extends the Main class or just use it in your Main class to
start the camel context.

If you want to start a JVM from JAR, you just need to specify the Main
class name in the Manifest file of the JAR.

like this
Main-Class                              YourMainClass
>
> I'm not understanding how I can run it perfectly well in eclipse, yet I
> cannot choose to use that as the run configuration when creating a Jar.
Please make sure the configuration file can be find in the classpath.

Willem

Reply | Threaded
Open this post in threaded view
|

Re: CSV Reporting with Java and XML

Willem.Jiang
Administrator
In reply to this post by somemightsay
Do You mean to pull the Spring configuration file ?
If the CamelContext is created, you can use it directly.

Willem
somemightsay wrote:
> Actually, I have used your advice and followed the example in the link you
> provided.
>
> But I'm assuming that is creating a new CamelContext from within the Java
> class? That would mean having to add al the enpoints, beans etc to the
> class.
>
> Is there a way to pull in my existing CamelContext?

Reply | Threaded
Open this post in threaded view
|

Re: CSV Reporting with Java and XML

somemightsay
In reply to this post by Willem.Jiang
The CamelContext.xml is created. It is used when you run Main.class, but obviously not when I run the Java.class i have created to define the routes.


So when you run Main.class, CamelContext.xml and Camelroutes.java are both used, and it works correctly.

But I can't seem to get Main.class to be used when running the jar. I have tried adding it to the manifest but with no success.

Unless I can get that working the other option is to not use the Main.class and instead just use camelcontext and camelroutes.

This would mean having to find a way for the Camelroutes.java to reference the XML file, because at present it does not see it, so does not use the endpoints/db login data.
Reply | Threaded
Open this post in threaded view
|

Re: CSV Reporting with Java and XML

Willem.Jiang
Administrator
somemightsay wrote:
> The CamelContext.xml is created. It is used when you run Main.class, but
> obviously not when I run the Java.class i have created to define the routes.
>
>
> So when you run Main.class, CamelContext.xml and Camelroutes.java are both
> used, and it works correctly.
>
> But I can't seem to get Main.class to be used when running the jar. I have
> tried adding it to the manifest but with no success.

What kind of error did you get?

>
> Unless I can get that working the other option is to not use the Main.class
> and instead just use camelcontext and camelroutes.
If you already have a CamelContext.xml, you can create a
ClassPathApplicationContext yourself, and spring will create a camel
context and start it for you.
>
> This would mean having to find a way for the Camelroutes.java to reference
> the XML file, because at present it does not see it, so does not use the
> endpoints/db login data.

Your CamelRoutes.java don't need to know the Spring configure, if you
have some properties file need to be loaded, you can take a look at
camel-properties component[1]

[1]http://camel.apache.org/properties.html

Willem

Reply | Threaded
Open this post in threaded view
|

Re: CSV Reporting with Java and XML

somemightsay
How then do you define the database information in the Java class?

The examples only show how to do it in the XML camel context.

I would however still much prefer to have the program how it is but find a way for the Main.class to be used in the JAR. It seems that it would be a very simple solution, considering it runs fine within the IDE.

Could you give an example of what the manifest should refer to as I have tried without success.

Thanks.
Reply | Threaded
Open this post in threaded view
|

Re: CSV Reporting with Java and XML

somemightsay
In reply to this post by Willem.Jiang
In reply to what kind of error did I get:

I got "Could not find the main class: org.apache.camel.spring.Main. program will now exit."

The manifest holds:

Main-Class: org.apache.camel.spring.Main.

i also tried:

Main-Class: Main.
Reply | Threaded
Open this post in threaded view
|

Re: CSV Reporting with Java and XML

Willem.Jiang
Administrator
In reply to this post by somemightsay
How about using google to find it out?

Here is link for the it.

http://download.oracle.com/javase/tutorial/deployment/jar/manifestindex.html

Willem

somemightsay wrote:

> How then do you define the database information in the Java class?
>
> The examples only show how to do it in the XML camel context.
>
> I would however still much prefer to have the program how it is but find a
> way for the Main.class to be used in the JAR. It seems that it would be a
> very simple solution, considering it runs fine within the IDE.
>
> Could you give an example of what the manifest should refer to as I have
> tried without success.
>
> Thanks.

Reply | Threaded
Open this post in threaded view
|

Re: CSV Reporting with Java and XML

somemightsay
I have tried that before with the manifest, it still says it cannot find org.apache.camel.spring.Main.

But thanks anyway.