Why am I having trouble accessing a .properties file in a standalone instance of tomcat but not in an eclipse-embedded instance? - eclipse

I wrote a simple Hello World Servlet in Eclipse containing the following in the doGet method of my HelloWorldServlet.java
PrintWriter writer = response.getWriter();
String hello = PropertyLoader.bundle.getProperty("hello");
writer.append(hello);
writer.flush();
PropertyLoader is a simple class in the same package as the Servlet that does the following:
public class PropertyLoader {
public static final Properties bundle = new Properties();
static {
InputStream stream = null;
URL url = PropertyLoader.class.getResource("/helloSettings.properties");
stream = new FileInputStream(url.getFile());
bundle.load(stream);
}
}//End of class
I placed a file called helloSettings.properties in /WebContent/WEB-IND/classes that contains the following single line of content:
hello=Hello Settings World
When I add Tomcat 6.0 to my project and run it in eclipse it successfully prints
"Hello Settings World" to the web browser.
However when I export the project as a war file and manually place it in
.../Tomcat 6.0/webapps I then get "null" as my result.
Is it a problem with the classpath/classloader configuration? permissions? any of the other configuration files? I know for a fact that the helloSettings.properties file is in the WEB-INF/classes folder.
Any help?

Well, after much browsing I found what seems a "normal" why to do what I'm trying to do:
Instead of...(how I was doing it)
public class PropertyLoader {
public static final Properties bundle = new Properties();
static {
InputStream stream = null;
URL url = PropertyLoader.class.getResource("/helloSettings.properties");
stream = new FileInputStream(url.getFile());
bundle.load(stream);
}
}//End of class
THE FIX
public class PropertyLoader {
public static final Properties bundle = new Properties();
static {
InputStream stream = null;
stream = SBOConstants.class.getResourceAsStream("/sbonline.properties");
bundle.load(stream);
}
}//End of class
I'm modifiying someone else's code so I'm not sure why they did it the other way in the first place... but I guess url.getFile() was my problem and I don't know why.

Related

How to write integration tests for spring-batch-integration?

I'm using spring-integration bundled with spring-batch and got stuck trying to write integration tests to test the whole flow, not just single config.
I've created Embedded Sftp Server for this tests and trying to send message to sftpInboundChannel - the message is sent, but nothing happens, but when i send this message to the next channel (after sftpInboundChannel) it goes ok. Also i'm not able to load test source properties, even though i'm using #TestPropertySource annotation.
This are my class annotations
#TestPropertySource(properties = {
//here goes all the properties
})
#EnableConfigurationProperties
#RunWith(SpringRunner.class)
#Import({TestConfig.class, SessionConfig.class})
#ActiveProfiles("it")
#SpringIntegrationTest
#EnableIntegration
#SpringBootTest
#DirtiesContext(classMode = DirtiesContext.ClassMode.BEFORE_EACH_TEST_METHOD)
This is my class body
#Autowired
private PollableChannel sftpInboundChannel;
#Autowired
private SessionFactory<ChannelSftp.LsEntry> defaultSftpSessionFactory;
#Autowired
private EmbeddedSftpServer server;
#Test
public void shouldDoSmth() {
RemoteFileTemplate<ChannelSftp.LsEntry> template;
try {
template = new RemoteFileTemplate<>(defaultSftpSessionFactory);
SftpTestUtils.moveToRemoteFolder(template);
final List<ChannelSftp.LsEntry> movedFiles = SftpTestUtils.listFilesFromDirectory("folder/subfolder", template);
log.info("Moved file {}", movedFiles.size());
final MessageBuilder<String> messageBuilder = MessageBuilder.withPayload("Sample.txt") // path to file
.setHeader("file_Path", "Sample.txt")
boolean wasSent = this.sftpInboundChannel.send(messageBuilder.build());
log.info("Was sent to sftpInboundChannel channel {}", wasSent);
log.info("message {}", messageBuilder.build());
} finally {
SftpTestUtils.cleanUp();
}
}
To the case of not read the property file one solution is add in your Test class something like this:
#BeforeClass
public static void beforeClass() {
System.setProperty("propertyfile", "nameOfFile.properties");
}
A second way is to create a xml (or class) config where you add the tag:
<context:property-placeholder
location="nameOfFile.properties"
ignore-resource-not-found="true" system-properties-mode="OVERRIDE" />
and your file will be localized.
The property file should be inside of resources folder.

Where to place Rythm template files

I am having a weird problem with Rythm templates. Currently, I have these templates placed under
myPrj/src/main/java/resources/templates folder.
And all the Java source code is under myPrj/src/main/java folder.
When I try to render, sometimes Rythm is generating the XML file and sometimes I get the file name as is.
I have the home.template set to "templates" folder:
params.put("home.template", "templates");
String myTemplateString = Rythm.render("MyTemplate.xml", parameters);
Looks like Rythm is not able to locate MyTemplate.xml and resulting in emitting MyTemplate.xml as the output.
Can you please help me on how to solve this problem?? In addition, would appreciate if you can guide me on what should be the appropriate location to place these templates.
home.template is the configuration key to initialize template engine, not the parameter to render your template.
My implementation of your app looks like
public class App {
private static RythmEngine engine;
private static void echo(String msg, Object ... args) {
System.out.println(String.format(msg, args));
}
private static void init() {
echo("initializing rythmengine");
Map<String, Object> conf = new HashMap<String, Object>();
conf.put("home.template", "templates");
engine = new RythmEngine(conf);
echo("engine initialized");
}
private static void render() {
Map<String, Object> params = new HashMap<String, Object>();
params.put("foo", "FOO");
params.put("bar", "BAR");
String result = engine.render("MyTemplate.xml", params);
echo(result);
}
private static void doJob() {
echo("start doing real job now...");
render();
}
public static void main( String[] args ) {
init();
doJob();
}
}
The complete sample code could be found at https://github.com/greenlaw110/Rythm/tree/master/samples/demo_fo_SO_150529. Download the sample code and run mvn compile exec:java to see the result
It seems your problem lies within the path for the home.template. The example on their website might help.
If I'm not mistaken, you should use params.put("home.template", "resources/templates"); rather than params.put("home.template", "templates");.
Generally speaking, this kind of behaviour takes place any time Rythm can't find the template. I found it is best to check both, the path and file name. If necessary, simply use an absolute path to your template to make sure it points to the right directory. After you got the right path, you might want to change it back to be relative.

Attach a CSV in Mail

I want to attach a csv file in mail(grails)
The file in the path is already present. I am using the following code
sendMail {
multipart true
from "$senderName <$fromAddress>"
to toAddress
cc message.cc
subject message.subject
body content.plaintext
html content.html
attachBytes './web-app/ReadyOrdersFor-${vendor.name}','text/csv', new File('./web-app/ReadyOrdersFor-${vendor.name}').readBytes()
}
Error prompted is.
java.io.FileNotFoundException: ./web-app/ReadyOrdersFor-${vendor.name}.csv (No such file or directory)
neither this works prompting the same error
attachBytes './web-app/ReadyOrdersFor-${vendor.name}.csv','text/csv', new File('./web-app/ReadyOrdersFor-${vendor.name}.csv').readBytes()
The issue is that you trying you use the file path string as a GStringImpl, but the string is enclosed in single quotes. GStringImpl is natively supported in groovy in double quotes.
You code should be
attachBytes "./web-app/ReadyOrdersFor-${vendor.name}",'text/csv', new File("./web-app/ReadyOrdersFor-${vendor.name}").readBytes()
This link should help you understand the difference between using single and double quotes in groovy.
Instead of trying to get a File reference using new File(path), use the Spring ResourceLoader interface. The ApplicationContext implements this interface, so you can get a reference to it from a controller (for example) like this:
class MyController implements ApplicationContextAware {
private ResourceLoader resourceLoader
void setApplicationContext(ApplicationContext applicationContext) {
resourceLoader = applicationContext
}
def someAction() {
String path = "classpath:/ReadyOrdersFor-${vendor.name}"
File csvFile = resourceLoader.getResource(path).file
}
}
I'm not 100% sure the path value above is correct, you may need to remove the '/'

How to programmatically new a java class which implements sepecified interface in eclipse plugin development

Friends,
Now we are developing a eclipse plugin, it contains a action to generated a service interface and it's impl stub.
Now the interface is generated, I want to use eclipse JDT to create a java class which implements sepecified interface, but don't know how.
The info we have:
the interface name, the impl class name, the packagename, the java project contains them.
Thanks in advance for your kindly help.
A quick scan of how the new class wizard does it, it seems that there is no public easy to use API for this. You can have a look at org.eclipse.jdt.ui.wizards.NewTypeWizardPage.createType(IProgressMonitor) method to see how JDT itself creates new classes.
It should be possible to extend the org.eclipse.jdt.ui.wizards.NewTypeWizardPage, so you can leverage the createType() method.
Probably the minimal steps you would have to do is simply generate source content into the correctly placed IFile. ex:
public Object execute(ExecutionEvent event) throws ExecutionException {
final String PACKAGE_PATH = "z.ex/src/z/ex/go";
final String CONTENT = "package z.ex.go;\n"
+ "public class RunAway {\npublic static void main(String[] args) {\n"
+ "System.out.println(\"Run Away\");\n}\n}\n";
final IWorkspaceRoot root = ResourcesPlugin.getWorkspace().getRoot();
final IResource packageResource = root.findMember(PACKAGE_PATH);
if (packageResource instanceof IFolder) {
IFolder packageFolder = (IFolder) packageResource;
final IFile file = packageFolder.getFile("RunAway.java");
try {
if (!file.exists()) {
file.create(new ByteArrayInputStream(CONTENT.getBytes()),
true, new NullProgressMonitor());
} else {
file.setContents(
new ByteArrayInputStream(CONTENT.getBytes()),
IFile.FORCE | IFile.KEEP_HISTORY,
new NullProgressMonitor());
}
} catch (CoreException e) {
e.printStackTrace();
}
}
return null;
}
See AbstractNewClassWizard for a smaller example that is similar to NewTypeWizardPage and uses some of the JDT APIs.
You can use the new class wizard to create classes.
This will prompt the user for the class name, et cetera. You can initialize the values of the wizard page. Below I am setting the source folder only (and tell the wizard that it cannot be changed, thus the second false parameter). You might want to set the interface and possible the package as well.
OpenNewClassWizardAction wizard = new OpenNewClassWizardAction();
wizard.setOpenEditorOnFinish(false);
NewClassWizardPage page = new NewClassWizardPage();
page.setPackageFragmentRoot(sourceFolder, false);
wizard.setConfiguredWizardPage(page);
wizard.run();
return (IType) wizard.getCreatedElement();
Hope that helps!
Create the entire java file using the JDT - AST. First create the AST and then write it to a java file. It might look as hefty work, but its the best one. You will have complete control.

How can I use properties taken from a file in the code of an eclipse PDE fragment/plugin project?

I have created an eclipse plugin project and a corresponding fragment project which I use for junit tests.
In the fragment I specify the plugin project as the "Host plugin". Further I specify the following on the build.properties pane:
source.. = src/
output.. = bin/
bin.includes = META-INF/,\
.,\
my.properties
where my.properties is a file located at the root of the fragment project. I have then written a test where I try to load the my.properties file like this:
Properties properties = new Properties();
InputStream istream = this.getClass().getClassLoader()
.getResourceAsStream("my.properties");
try {
properties.load(istream);
} catch (IOException e) {
e.printStackTrace();
}
but istream is null and the test fails with a NullPointerException when calling load in the try block.
I have tried to do the same thing in the host plugin and there it works fine. Any ideas about why I can't read resouces in my PDE fragment when using Junit?
Try using Bundle#getEntry. If your plug-in has an Activator, you get a BundleContext object when your plugin is started (use Bundle-ActivationPolicy: lazy in your manifest). You can get the Bundle object from the BundleContext:
public class Activator implements BundleActivator {
private static Bundle bundle;
public static Bundle getBundle() {
return myBundle;
}
public void start(BundleContext context) throws Exception {
bundle = context.getBundle();
}
}
...
URL url = Activator.getBundle().getEntry("my.properties");
InputStream stream = url.openStream();
properties.load(stream);
One problem you MIGHT be having is that
InputStream istream = this.getClass().getClassLoader().
getResourceAsStream("my.properties");
behaves differently in two situations where "this" is located in a different package. Since you did not append "/" to the beginning, java will automatically start looking at the package root instead of the classpath root for the resource. If the code in your plug-in project and your fragment project exist in different packages, you have a problem.
Andrew Niefer has pointed the direction, but the solution is wrong. That is one that works:
1) Add super(); to the your Activator constructor.
2) Put this into the constructor of your plugin:
Properties properties = new Properties();
try {
Bundle bundle=Activator.getDefault().getBundle();
URL url = bundle.getEntry("plugin.properties");
InputStream stream;
stream = url.openStream();
properties.load(stream);
} catch (Exception e) {
e.printStackTrace();
}
And you have functioning "properties".
Explanations:
Doing (1) you will reach all that functionality:
public class Activator implements BundleActivator {
private static Bundle bundle;
public static Bundle getBundle() {
return myBundle;
}
public void start(BundleContext context) throws Exception {
bundle = context.getBundle();
}
}
It is present already in the pre-parent class Plugin. And you simply can't put it into Activator, because getBundle() is final in Plugin.
Notice Activator.getDefault() in (2). Without it bundle is unreachable, it is not static. And if you simply create a new instance of activator, bundle of it will be null.
There is one more way to take a bundle:
Bundle bundle = Platform.getBundle(Activator.PLUGIN_ID);
Only check that Activator.PLUGIN_ID is set to the correct string - as is in the ID field of the Overview page of the plugin. BTW, you should check this Activator.PLUGIN_ID after every change of the plugin ID anyway.