How to add Microsoft Word content in Email Body from Java Code - javax

I am trying to put content of Microsoft Word Document in Email body from Java Code but getting following error:
Exception in thread "main" java.lang.RuntimeException: javax.mail.MessagingException: IOException while sending message;
nested exception is:
javax.activation.UnsupportedDataTypeException: no object DCH for MIME type application/msword
at co.kush.DemoEmail.main(DemoEmail.java:134)
Caused by: javax.mail.MessagingException: IOException while sending message;
nested exception is:
javax.activation.UnsupportedDataTypeException: no object DCH for MIME type application/msword
at com.sun.mail.smtp.SMTPTransport.sendMessage(SMTPTransport.java:625)
at co.kush.DemoEmail.main(DemoEmail.java:128)
Caused by: javax.activation.UnsupportedDataTypeException: no object DCH for MIME type application/msword
at javax.activation.ObjectDataContentHandler.writeTo(DataHandler.java:896)
at javax.activation.DataHandler.writeTo(DataHandler.java:317)
at javax.mail.internet.MimeBodyPart.writeTo(MimeBodyPart.java:1350)
Refer my code :
package co.kush;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.FileWriter;
import java.io.IOException;
import java.io.OutputStream;
import java.io.UnsupportedEncodingException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Properties;
import javax.activation.DataHandler;
import javax.activation.DataSource;
import javax.activation.FileDataSource;
import javax.mail.*;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeBodyPart;
import javax.mail.internet.MimeMessage;
import javax.mail.internet.MimeMultipart;
import org.apache.poi.hwpf.HWPFDocument;
import org.apache.poi.hwpf.extractor.WordExtractor;
import org.apache.poi.hwpf.usermodel.CharacterRun;
/**
* #author Kush
*
*/
public class DemoEmail {
public static void main(String[] args) throws FileNotFoundException, IOException {
Properties prop = new Properties();
String Filepath = "Email.Properties";
FileInputStream propFile = new FileInputStream(Filepath);
prop.load(propFile);
String timeStamp = new SimpleDateFormat("M/dd # HH:mm:ss").format(Calendar.getInstance().getTime());
// Fetching values from property file
String sender = prop.getProperty("sender");
String recevier = prop.getProperty("recevier");
String password = prop.getProperty("password");
String proxyHost = prop.getProperty("proxyHost");
String proxyPort = prop.getProperty("proxyPort");
String smtpHost = prop.getProperty("smtpHost");
String smtpPort = prop.getProperty("smtpPort");
String attachFilePath = prop.getProperty("attachFilePath");
String mailSubject=prop.getProperty("mailSubject")+" on " + timeStamp;
String mailBody = prop.getProperty("mailBody");
Properties sys_prop = System.getProperties();
// Setting values for sending Email
sys_prop.put("mail.smtp.starttls.enable", "true");
sys_prop.put("mail.transport.protocol", "SMTP");
sys_prop.put("mail.smtp.host", smtpHost);
sys_prop.put("mail.smtp.auth", "true");
sys_prop.put("mail.smtp.port", smtpPort);
sys_prop.put("mail.smtp.debug", "true");
sys_prop.put("mail.smtp.socketFactory.port", smtpPort);
sys_prop.put("mail.smtp.socketFactory.class", "javax.net.ssl.SSLSocketFactory");
sys_prop.put("mail.smtp.socketFactory.fallback", "false");
sys_prop.put("proxySet", "true");
sys_prop.put("proxyPort", proxyPort);
sys_prop.put("socksProxyHost", proxyHost);
sys_prop.put("proxyHost", proxyHost);
Session session = Session.getDefaultInstance(sys_prop, null);
try {
//Adding Sender/Receiver address and Subject Line
MimeMessage msg = new MimeMessage(session);
msg.setFrom(new InternetAddress(sender));
msg.addRecipient(Message.RecipientType.TO, new InternetAddress(recevier));
msg.setSubject(mailSubject);
MimeBodyPart messageBodyPart=new MimeBodyPart();
Multipart multipart = new MimeMultipart();
//Reading Word Document
HWPFDocument doc = new HWPFDocument(new FileInputStream("<AbsolutePathWordDoc\\<WordDocFile>.doc"));
WordExtractor we = new WordExtractor(doc);
String[] paragraphs = we.getParagraphText();
for (String para : paragraphs) {
//Putting word document to email Body
messageBodyPart.setContent(paragraphs, "application/msword");
multipart.addBodyPart(messageBodyPart);
}
//Adding attachment and Body content to MIME msg object
msg.setContent(multipart);
//Sending the message
Transport transport = session.getTransport("smtp");
transport.connect(smtpHost, sender, password);
transport.sendMessage(msg, msg.getAllRecipients());
transport.close();
System.out.println("Mail sent succesfully!");
} catch (MessagingException e) {
throw new RuntimeException(e);
} finally {
//Removing System properties
sys_prop.remove("proxySet");
sys_prop.remove("proxyHost");
sys_prop.remove("proxyPort");
sys_prop.remove("socksProxyHost");
sys_prop.remove("mail.smtp.socketFactory.class");
sys_prop.remove("mail.smtp.socketFactory.fallback");
sys_prop.remove("mail.smtp.socketFactory.port");
}
}
}
Property file 'Email.Properties':
sender=helloqa86#gmail.com
recevier=k.b#xx.com
password=*****
proxyHost=web-proxy.**.**.com
proxyPort= 8080
smtpHost=smtp.gmail.com
smtpPort=465
From the error I can understand that problem is in this part
messageBodyPart.setContent(paragraphs, "application/msword"); where I am adding word document content to MIME message body part.
I have tried several other ways to achieve this but not able to do so. Please suggest a way to achieve this?

I got a resolution to this problem.Actually , I have to put different font face and font sizes in email body which I am trying to read from word document.To achieve this I have changed my approach,so instead of word document I have embedded my content into html tags which is quite simple :) , refer the below line of code which will replace word document part
String htmltext = "+
Different Font Size+
Different Font Size+
";
messageBodyPart.setContent(htmltext, "text/html");
During my research one of my friend suggested me following third party API's , it might be helpful to anyone
http://www.oracle.com/technetwork/java/javamail/third-party-136965.html
https://github.com/bbottema/simple-java-mail/

Related

Why am I getting random errors in my Minecraft 1.7.10 mod using eclipse?

Sorry, I'm not sure if I'm in the right forum or if I'm wording it right. People may call this vague or something. I won't care.
Anyway, I've started to get random errors after trying something. It didn't turn out well. Here's the code + errors of my main mod file.
package com.harry.MoStuff;
import cpw.mods.fml.common.Mod;
import cpw.mods.fml.common.Mod.EventHandler;
import cpw.mods.fml.common.event.FMLInitializationEvent;
import cpw.mods.fml.common.event.FMLPostInitializationEvent;
import cpw.mods.fml.common.event.FMLPreInitializationEvent;
import cpw.mods.fml.common.registry.GameRegistry;
import net.minecraft.block.Block;
import net.minecraft.block.material.Material;
import net.minecraft.init.Items;
import net.minecraft.item.Item;
import net.minecraft.item.ItemFood;
import net.minecraft.item.ItemStack;
#Mod(modid = "ms", name = "Mo' Stuff", version = "a-1.0")
public class MoStuff {
public static Item itemRuby;
public static Item itemChain;
public static Item itemRubyEssence;
public static Item itemRubyShard;
public static Item itemRedBull;
public static Block blockRubyOre;
#EventHandler
public void preInit(FMLPreInitializationEvent event) {
//Item/block init and registering
//Config handling
itemRuby = new ItemRuby().setUnlocalizedName("ruby").setTextureName("ms:ruby");
itemChain = new ItemChain().setUnlocalizedName("chain");
blockRubyOre = new BlockRubyOre(Material.rock).setBlockName("ruby_ore").setBlockTextureName("ms:ruby_ore");
itemRubyShard = new ItemRubyShard().setUnlocalizedName("ruby_shard");
itemRubyEssence = new ItemRubyEssence().setUnlocalizedName("ruby_essence");
itemRedBull = new ItemFood(8, 1.0F, true).setUnlocalizedName("red_bull").setTextureName("ms:red_bull");
}
GameRegistry.registerItem(itemRuby, itemRuby.getUnlocalizedName().substring(5));
GameRegistry.registerItem(itemChain, itemChain.getUnlocalizedName().substring(5));
GameRegistry.registerItem(itemRubyShard, itemRubyShard.getUnlocalizedName().substring(5));
GameRegistry.registerItem(itemRubyEssence, itemRubyEssence.getUnlocalizedName().substring(5));
GameRegistry.registerBlock(blockRubyOre, blockRubyOre.getUnlocalizedName().substring(5));
GameRegistry.registerItem(itemRedBull, itemRedBull.getUnlocalizedName().substring(5));
#EventHandler
public void init(FMLInitializationEvent event) {
//Proxy, tile entity, entity, GUI, packet reg.
GameRegistry.addRecipe(new ItemStack(itemRuby), new Object[]{"RRR","RRR","RRR", 'R', itemRubyShard});
GameRegistry.addRecipe(new ItemStack(itemChain), new Object[] {"III","I I","III", 'I', Items.iron_ingot});
GameRegistry.addRecipe(new ItemStack(itemRubyEssence, 5), new Object[]{" "," R "," ", 'R', itemRuby});
}
#EventHandler
public void postInit(FMLPostInitializationEvent event) {
}
}
The errors are:
Multiple markers at this line (38, where GameRegistry.registerItem(itemRuby) and so on):
Syntax error on token ".", > expected.
Syntax error on token "(", < expected.
Syntax error on token ".", { expected.
Syntax error on token ")", delete this token.
Multiple markers at this line (46, where public void init(params) is.)
Syntax error on token "(", ; expected.
Syntax error on token ")", ; expected.
Multiple markers at this line (54, where public void postInit(params) is.)
Syntax error on token "(", ; expected.
Syntax error on token ")", ; expected.
That's all I can say. Thanks in advance.
On line 37, you closed the brace. Close it after all your GameRegistry.register

Casting java.sql.Connection to oracle.jdbc.OracleConnection results in compilation error

I would like to cast java.sql.Connection to oracle.jdbc.OracleConnection in order to bind data on ARRAY to my query.
When I try the following on scala 2.10, bonecp 0.8.0 and slick 2.0.0:
import com.jolbox.bonecp.ConnectionHandle
import oracle.jdbc.OracleConnection
def failsWithCompilationError() = {
Database.forDataSource(ds).withDynTransaction {
val connection = dynamicSession.conn.asInstanceOf[ConnectionHandle].getInternalConnection
println(connection.unwrap(classOf[OracleConnection]))
// When uncommenting following two lines a compilation error "error while loading AQMessage, class file '.../ojdbc6.jar(oracle/jdbc/aq/AQMessage.class)' is broken" will occur
// val oracleConnection: OracleConnection = connection.unwrap(classOf[OracleConnection])
// println(oracleConnection)
}
}
and uncomment the two lines with assignment to a val of type OracleConnection and printlna compilation failure
[error] error while loading AQMessage, class file '.../ojdbc6.jar(oracle/jdbc/aq/AQMessage.class)' is broken will occur.
I already verified that the ojdbc6.jar should not be corrupted by downloading newer version from Oracle.
It seems that the problem was with the Scala compiler.
As soon as I embedded the functionality that depended on oracle.jdbc.OracleConnection into a plain old Java class, built that into a separate .jar and linked with my Scala code things started to roll.
Here's how I got this to work:
OracleArray.java
package my.application.oracle.collections;
import oracle.jdbc.OracleConnection;
import oracle.jdbc.OraclePreparedStatement;
import oracle.sql.ARRAY;
import scala.Long;
import scala.Tuple2;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
/*
Wraps usage of Oracle ARRAYs since casting java.sql.Connection to oracle.jdbc.Connection does not compile on Scala.
*/
public class OracleArray {
public static List<Tuple2<Long, Long>> fetchAssetsByIds(List ids, Connection connection) throws SQLException {
OracleConnection oracleConnection = (OracleConnection) connection;
ARRAY oracleArray = oracleConnection.createARRAY("MY_ARRAY_SQL_TYPE", ids.toArray());
String sql = "SELECT a.id, a.value" +
"FROM ASSET a " +
"WHERE a.id IN (SELECT COLUMN_VALUE FROM TABLE(?))";
PreparedStatement statement = oracleConnection.prepareStatement(sql);
try {
OraclePreparedStatement oraclePreparedStatement = (OraclePreparedStatement) statement;
oraclePreparedStatement.setArray(1, oracleArray);
ResultSet resultSet = oraclePreparedStatement.executeQuery();
try {
ArrayList<Tuple2<Long, Long>> resultTuples = new ArrayList<>();
while (resultSet.next()) {
long id = resultSet.getLong(1);
long value = resultSet.getLong(2);
resultTuples.add(new Tuple2(id, value));
}
return resultTuples;
} finally {
resultSet.close();
}
} finally {
statement.close();
}
}
}
DataUser.scala
package my.application
import my.application.oracle.collections.OracleArray
import scala.slick.driver.JdbcDriver.backend.Database
import Database.dynamicSession
import com.jolbox.bonecp.ConnectionHandle
import java.sql.Connection
import collection.JavaConversions._
/*
Uses BoneCP and Slick to connect to database and relays java.sql.Connection to
OracleArray in order to run operations that use Oracle ARRAYs
*/
object DataUser {
def doSomethingWithAssets(ids: Seq[Long]): Unit = {
Database.forDataSource(ds).withDynTransaction {
val connection: Connection = dynamicSession.conn.asInstanceOf[ConnectionHandle].getInternalConnection
val assets: Seq[(Long, Long)] = OracleArray.fetchAssetsByIds(ids, connection)
println(assets)
}
}
}
Not sure if my situation is related, but using the Play framework, this works for me only when logSql=false:
db.withConnection { implicit c =>
val oracleConnection = c.unwrap(classOf[OracleConnection])
}
When I set logSql=true, I get:
com.sun.proxy.$Proxy17 cannot be cast to oracle.jdbc.OracleConnection
java.lang.ClassCastException: com.sun.proxy.$Proxy17 cannot be cast to
oracle.jdbc.OracleConnection
So something about the logSql configuration can actually cause unwrap to fail. No idea why.
I think this may be related to Hikari Connection Pool, but maybe your connection pool configuration is causing a similar problem.

eventhough i change the environmental variables and classpath, while running sqlite jdbc program i get the error stating no class definition doun

im running a jdbc program on Sqlite. though i change the environmental variables or define the classpath of the jar file sqlite-jdbc-3.7.2.jar, i get an error stating ClassNotFoundException: org.sqlite.JDBC... how to rectify it?
my code is`
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
public class Sample
{
public static void main(String[] args)throws ClassNotFoundException
{
// load the sqlite-JDBC driver using the current class loader
Class.forName("org.sqlite.JDBC");
Connection connection = null;
try
{
// create a database connection
connection = DriverManager.getConnection("jdbc:sqlite:sample.db");
Statement statement = connection.createStatement();
statement.setQueryTimeout(30); // set timeout to 30 sec.
statement.executeUpdate("drop table if exists person");
statement.executeUpdate("create table person (id integer, name string)");
statement.executeUpdate("insert into person values(1, 'leo')");
statement.executeUpdate("insert into person values(2, 'yui')");
ResultSet rs = statement.executeQuery("select * from person");
while(rs.next())
{
// read the result set
System.out.println("name = " + rs.getString("name"));
System.out.println("id = " + rs.getInt("id"));
}
}
catch(SQLException e)
{
// if the error message is "out of memory",
// it probably means no database file is found
System.err.println(e.getMessage());
}
finally
{
try
{
if(connection != null)
connection.close();
}
catch(SQLException e)
{
// connection close failed.
System.err.println(e);
}
}
}
}`
my jar file is sqlite-jdbc-3.7.2.jar
my class path is D:\jdk1.6.0_45\sqlite-jdbc-3.7.2.jar
my environmental variable is also the same
what should i do?
help pls
i found the solution to my problem...
the class path should be like
`javac Sample.java
java -classpath "D:\jdk1.6.0_45\sqlite-jdbc-3.7.2.jar";. Sample`
the problem is solved:)

Apache Velocity - Resource not found exception

I have a requirement to generate some automated mails and so I wanted to use velocity for this task.I have copied all velocity jars to the lib folder and created a hello.vm template and placed in WEB-INF/templates folder.Below is exception I am getting,
org.apache.velocity.exception.ResourceNotFoundException: Unable to find resource 'hello.vm'
userCount incremented to :1
at org.apache.velocity.runtime.resource.ResourceManagerImpl.loadResource(ResourceManagerImpl.java:474)
at org.apache.velocity.runtime.resource.ResourceManagerImpl.getResource(ResourceManagerImpl.java:352)
at org.apache.velocity.runtime.RuntimeInstance.getTemplate(RuntimeInstance.java:1533)
at org.apache.velocity.runtime.RuntimeInstance.getTemplate(RuntimeInstance.java:1514)
at org.apache.velocity.app.VelocityEngine.getTemplate(VelocityEngine.java:373)
at indian.test.handleRequest(test.java:34)
at org.apache.velocity.tools.view.VelocityViewServlet.doRequest(VelocityViewServlet.java:217)
at org.apache.velocity.tools.view.VelocityViewServlet.doGet(VelocityViewServlet.java:182)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:621)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:722)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:305)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
at org.netbeans.modules.web.monitor.server.MonitorFilter.doFilter(MonitorFilter.java:393)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:243)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
at listener.trimresponse.doFilter(trimresponse.java:46)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:243)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:225)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:169)
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:472)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:168)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:98)
at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:927)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:118)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:407)
at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:999)
at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:565)
at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:307)
at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908)
at java.lang.Thread.run(Thread.java:619)
I tried all the other ways to load resource using classloader/webapps and still the error remains the same.I am using netbeans 7.2.x with tomcat 7.27. Appreciate if someone can suggest something for this.
Below is my velocity properties file,
resource.loader = file
file.resource.loader.class = org.apache.velocity.runtime.resource.loader.FileResourceLoader
file.resource.loader.path = C:\Users\kiran\Desktop\Netbeans Projects\ourstory\web\WEB-INF\templates
file.resource.loader.cache = true
file.resource.loader.modificationCheckInterval = 2
runtime.log=/WEB-INF/logs/velocity.log
runtime.log.logsystem.class=org.apache.velocity.runtime.log.Log4JLogSystem
runtime.log.logsystem.log4j.pattern=%d - %m%n
runtime.log.logsystem.log4j.file.size=10000
runtime.log.logsystem.log4j.file.backups=1
and below is servlet I am using
import java.util.Properties;
import javax.servlet.http.*;
import org.apache.velocity.Template;
import org.apache.velocity.VelocityContext;
import org.apache.velocity.app.VelocityEngine;
import org.apache.velocity.context.Context;
import org.apache.velocity.tools.view.VelocityViewServlet;
public class test extends VelocityViewServlet {
private String htmlTemplate = "hello.vm";
VelocityContext context = new VelocityContext();
#Override
public Template handleRequest(HttpServletRequest request,
HttpServletResponse response,
Context context) {
// Properties props = new Properties();
// props.setProperty("resource.loader", "class");
// props.setProperty("class.resource.loader.class", "org.apache.velocity.runtime.resource.loader.ClasspathResourceLoader");
// props.setProperty("webapp.resource.loader.path", "/WEB-INF/templates/");
VelocityEngine engine = new VelocityEngine();
engine.init();
Template template = null;
try {
context.put("name", "Velocity Test");
template = engine.getTemplate(htmlTemplate);
} catch (Exception e) {
e.printStackTrace();
System.err.println("Exception caught: " + e.getMessage());
}
return template;
}
}
its simple servlet but for some reason I am unable to get it working.
(Answered in comments and edits. See Question with no answers, but issue solved in the comments (or extended in chat) )
The OP wrote:
Update Solved.
Finally After wasting good 2 days and pulling out lot of hairs,and banging the head many times, its resolved.here is what I did to resolve this, added couple of logging statements to ensure that it points correct to the templates folders and then pasing the absolute path to the template file. Watch out for backslashes and forward slashes. Need to log the folder paths and see where exactly its looking for and then keep dubugging. Its pain in the ass to fix such a simple stuff.
/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
/**
*
* #author kiran
*/
import java.io.File;
import java.util.Enumeration;
import java.util.Properties;
import javax.servlet.http.*;
import org.apache.velocity.Template;
import org.apache.velocity.app.VelocityEngine;
import org.apache.velocity.context.Context;
import org.apache.velocity.tools.view.VelocityViewServlet;
public class Hellotest extends VelocityViewServlet {
#Override
public Template handleRequest(HttpServletRequest request,
HttpServletResponse response,
Context context) {
Properties prop = new Properties();
// prop.put("resource.loader", "class");
// prop.put("class.resource.loader.class", "org.apache.velocity.runtime.resource.loader.ClasspathResourceLoader");
String absolutePath = new File(Thread.currentThread().getContextClassLoader().getResource("").getFile()).getParentFile().getParentFile().getPath();
prop.put("file.resource.loader.path", absolutePath + "\\templates\\");
System.out.println("absolute path is : " + absolutePath);
System.out.println("keyset is : " + prop.keySet());
Enumeration em = prop.keys();
while (em.hasMoreElements()) {
String str = (String) em.nextElement();
System.out.println(str + ": " + prop.get(str));
}
VelocityEngine Velocity = new VelocityEngine();
Velocity.init(prop);
Template template = null;
context.put("name", "Velocity Test");
try {
System.out.println("absolute path inside is : " + context);
template = Velocity.getTemplate("hello.vm","UTF-8");
} catch (Exception e) {
e.printStackTrace();
System.err.println("Exception caught: " + e.getMessage());
}
return template;
}
}
and here is updated velocity properties file,
resource.loader = file
file.resource.loader.class = org.apache.velocity.runtime.resource.loader.FileResourceLoader
file.resource.loader.cache = true
file.resource.loader.modificationCheckInterval = 2
and finally I put the templates under webpages folder. Maybe I will try to push this in web-inf and see how it goes. Its not good thing to keep templates under webpages given that we are exposing it.

JRI Fatal Error on Ubuntu

I have successfully installed JRI and rJava on Windows 7. I am now trying to get it to work on Ubuntu with 64bit OS. I can make rJava calls from within R but getting JRI to work is more difficult. I am running NetBeans 7.1.2 and I have followed various tricks in setting R_HOME and java.library.path to enable all the classes to be loaded. That is, I am past the error messages such as "jri library not found" and "R_HOME not set".
From my java code,I can see that R_HOME = /usr/lib64/R.
The error message I get now is
Fatal error: you must specify '--save', '--no-save' or '--vanilla'
This happens when Rengine is first called:
Rengine r = new Rengine(args,false,null);
This appears to be an error message from R; it seems to be expecting a command line argument. I haven't seen any posting with this error message. Any ideas? Thanks, Peter
Using R in this setting requires you to run R in non-interactive mode. To solve the issue, you need to choose on of the options given in the error message. I would try --no-save first. This prevents R from saving the workspace at the end of the run. In Java code:
String args[] = {"--no-save"};
Rengine re = new Rengine(args, false, null);
I will post my code for anyone trying to replicate these steps. The code is cobbled together from multiple web sources. Sorry for the re-formatting that occurs: I don't know how to show it as straight text.
/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
package testjri;
/**
*
* #author root
*/
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Image;
import java.io.File;
import java.io.IOException;
import java.lang.reflect.Field;
import java.util.Arrays;
import javax.imageio.ImageIO;
import javax.swing.JFrame;
import javax.swing.JPanel;
import org.rosuda.JRI.Rengine;
import org.rosuda.JRI.*;
import org.rosuda.REngine.*;
public class TestJRI {
/**
* #param args the command line arguments
*/
public static void main(String[] args) throws IOException
{//in the folder /etc/ld.so.conf.d I created a file called libR.conf with the single line "/usr/lib64/R/lib/" in it (without the quotes).
//In the same folder I created a file called rJava.conf with the single line "/usr/lib/jvm/java-6-openjdk/jre/lib/amd64/server/" in it (without the quotes).
//I then ran ldconfig to force these changes.
//To get R_HOME set, I had to modify netbeans.conf adding the line "export R_HOME=/usr/lib64/R"
System.out.println("R_HOME: "+System.getenv("R_HOME"));
try{//This next line is a trick to force a change to java.library.path at runtime
addLibraryPath("/usr/lib64/R/site-library/rJava/jri/");
// I copied libR.so to the jri folder so I am not sure if the next line does anything
addLibraryPath("/usr/lib64/R/lib/");
}catch(Exception e){System.out.println(e.toString());}
System.out.println("java.library.path: "+java.lang.System.getProperty("java.library.path"));
//Set some labels for the plot
String title = "R Plot in JFrame";
String xlab = "X Label";
String ylab = "Y Label";
//Start R
String newargs[] = {"--no-save"};
Rengine r = new Rengine(newargs, false, null);
//Do some calcs and plot the chart but save as a png in the working folder
r.eval("a<-c(1,2,3,4,5,6,7,8,9,10)");
r.eval("b<-c(1,3,2,4,5,6,7,8,9,10)");
r.eval("png(file=\"graph2.png\",width=1600,height=1600,res=400)");
r.eval("plot(a,b,type='o',col=\"Blue\",main=\"" + title + "\",xlab=\""
+ xlab + "\",ylab=\"" + ylab + "\")");
r.eval("dev.off()");
//It took me a search to find where R stuck the image. I found it in /proc/29285/cwd.
//I will have to learn how to control the working folder for R from java.
//get the image and create a new imagepanel
File file = new File("/proc/29285/cwd/graph2.png");
Image image = ImageIO.read(file);
imagePanel myPanel = new imagePanel(image);
//Create a new frame and add the imagepanel
JFrame aFrame = new JFrame();
aFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
aFrame.getContentPane().add(myPanel, BorderLayout.CENTER);
aFrame.pack();
aFrame.setVisible(true);
aFrame.setSize(new Dimension(600, 600));
}
static class imagePanel extends JPanel
{
Image image = null;
public imagePanel(Image image)
{
this.image = image;
}
#Override
public void paintComponent(Graphics g)
{
super.paintComponent(g);
//there is a picture: draw it
if (image != null)
{
int height = this.getSize().height;
int width = this.getSize().width;
g.drawImage(image, 0, 0, width, height, this);
}
}
}
/**
* Adds the specified path to the java library path
*
* #param path the new library path to add
* #throws Exception
*/
public static void addLibraryPath(String path) throws Exception {
String oldPath = System.getProperty("java.library.path");
if (oldPath.length() >0)path = path+":"+oldPath;
System.setProperty("java.library.path", path);
//set sys_paths to null
final Field sysPathsField = ClassLoader.class.getDeclaredField("sys_paths");
sysPathsField.setAccessible(true);
sysPathsField.set(null, null);
}
}

Resources