Environment:
Java API google-api-services-datastore-protobuf v1beta2-rev1-3.0.0.
OS: Windows 7.
Goal:
Start Local Datastore Server using the method:
public void start(String sdkPath, String dataset, String cmdLineOptions)
from com.google.api.services.datastore.client.LocalDevelopmentDatastore.java in order to use it in unit tests.
Steps:
I downloaded gcd tool gcd-v1beta2-rev1-3.0.2.zip and put it to C:\gcd folder
(paths to gcd.cmd and gcd.sh are `C:\gcd).
Also, I set environment variables:
"DATASTORE_HOST"="http://localhost:8080" and
"DATASTORE_DATASET"="myapp".
Problem:
LocalDevelopmentDatastoreException occurs.
Caused by: java.io.IOException: Cannot run program "./gcd.sh" (in directory "C:\gcd"): CreateProcess error=2, The system cannot find the file specified.
Note that it tries to find ./gcd.sh but not gcd.cmd.
Java code:
String datasetName = "myapp";
String hostName = "http://localhost:8080";
DatastoreOptions options = new DatastoreOptions.Builder()
.host(hostName)
.dataset(datasetName).build();
LocalDevelopmentDatastoreOptions localOptions = new LocalDevelopmentDatastoreOptions.Builder()
.addEnvVar("DATASTORE_HOST", hostName)
.addEnvVar("DATASTORE_DATASET", datasetName).build();
LocalDevelopmentDatastore datastore = LocalDevelopmentDatastoreFactory.get().create(options, localOptions);
datastore.start("C:\\gcd", datasetName);
This code is based on the example from LocalDevelopmentDatastore.java documentation.
Please help.
It seems as though the method is only programmed to look for gcd.sh, as it doesn't appear there's anything in your config which could have helped this to not fail. I suggest you open a defect report in the Cloud Platform Public Issue Tracker.
Did you consider gcloud-java for using the Datastore?
It also has an option for programmatically starting the local datastore using LocalGcdHelper which should work on Windows.
Related
I need the functionality like that of the rsync linux tool in my Java program. For that, I chose the rsync4j library.
Using their documentation, I wrote the following program:
import com.github.fracpete.processoutput4j.output.ConsoleOutputProcessOutput;
import com.github.fracpete.rsync4j.RSync;
public class MainClass {
public static void main(String [] args) {
System.out.println("Started");//check
RSync rsync = new RSync()
.source("/home/arth/DataSourceFolder/a.txt")
.destination("/home/arth/DataDestinationFolder/")
.recursive(true);
// or if you prefer using commandline options:
// rsync.setOptions(new String[]{"-r", "/one/place/", "/other/place/"});
CollectingProcessOutput output = null;
try {
System.out.println("Inside try");
output = rsync.execute();
System.out.println("End of try");
} catch (Exception e) {
e.printStackTrace();
}
System.out.println(output.getStdOut());
System.out.println("Exit code: " + output.getExitCode());
if (output.getExitCode() > 0)
System.err.println(output.getStdErr());
}
}
In the snippet, in out local machine, a file a.txt is copied from one location to another. This works perfectly. The file is successfully copied when I run it and here is the output:
Started
Inside try
End of try
Exit code: 0
But my need is to sync a local directory with a directory lying at a remote host/machine. When I tried to do it using a simple rsync command from a terminal using the following command
rsync remoteUserName#23.24.25.244:/home/beth/remoteFolder/a.png /home/arth/DataSourceFolder
it works like a charm. a.png IS copied to local machine at path specified, although a password of remote machine is asked first.
But the problem when I use the above Java program to do the same operation, by replacing line # 11 and 12 by:
.source("remoteUserName#23.24.25.244:/home/beth/remoteFolder/a.png")
.destination("/home/arth/DataDestinationFolder/")
the program gets stuck after printing Started in the console. Neither an exception is thrown nor does the program proceed.
The question is that how do I fix this problem?
(old post, I know, but here it goes...) The rsync4j library does not allow interaction. In your case, the underlying rysnc binary prompts for a password in the process that the Java library created, but never receives one.
Starting with release 3.2.3-7, you can supply an instance of the sshpass wrapper to feed in the password (see this comment for an example).
I use Apache Batik to convert SVG into PDF in one of the projects. The project is Spring application running in Tomcat 7. Everything works OK on development machine which runs under Ubuntu with Tomcat being started using $CATALINA_HOME/bin/startup.sh. But when I try to run the app on production server with CentOS 6 and Tomcat started using service tomcat7 start command the app falls into infinite loop on convertation. I've tried to debug the problem and found this piece of code:
/**
* Creates the {#link FontInfo} instance for the given configuration.
* #param cfg the configuration
* #param useComplexScriptFeatures true if complex script features enabled
* #return the font collection
* #throws FOPException if an error occurs while setting up the fonts
*/
public static FontInfo createFontInfo(Configuration cfg, boolean useComplexScriptFeatures)
throws FOPException {
FontInfo fontInfo = new FontInfo();
final boolean strict = false;
if (cfg != null) {
URI thisUri = new File(".").getAbsoluteFile().toURI();
InternalResourceResolver resourceResolver
= ResourceResolverFactory.createDefaultInternalResourceResolver(thisUri);
//TODO The following could be optimized by retaining the FontManager somewhere
FontManager fontManager = new FontManager(resourceResolver, FontDetectorFactory.createDefault(),
FontCacheManagerFactory.createDefault());
//TODO Make use of fontBaseURL, font substitution and referencing configuration
//Requires a change to the expected configuration layout
DefaultFontConfig.DefaultFontConfigParser parser
= new DefaultFontConfig.DefaultFontConfigParser();
DefaultFontConfig fontInfoConfig = parser.parse(cfg, strict);
DefaultFontConfigurator fontInfoConfigurator
= new DefaultFontConfigurator(fontManager, null, strict);
List<EmbedFontInfo> fontInfoList = fontInfoConfigurator.configure(fontInfoConfig);
fontManager.saveCache();
FontSetup.setup(fontInfo, fontInfoList, resourceResolver, useComplexScriptFeatures);
} else {
FontSetup.setup(fontInfo, useComplexScriptFeatures);
}
return fontInfo;
}
in PDFDocumentGraphics2DConfigurator class. When I'm running the app on developer machine the line URI thisUri = new File(".").getAbsoluteFile().toURI(); results with thisUri being assigned with ~/tomcat/bin/. folder. When the app is running on production machine it is assigned with /. value. I think that this is the main problem because the value of thisUri is the folder in which FOP starts fonts search and on the production machine this is the root of file system and recursive search on the whole FS structure is very slow. I tried to add fop.xconf file to the WEB-INF directory with fonts configuration but it didn't affected the behavior of FOP. And I can't start Tomcat on production server the same way as I start on the dev machine.
Has anyone ideas on how to configure the base directory for font scan of FOR? Or am I doing something wrong?
I've found the workaround for the problem. I'm not sure if its wright or wrong to do stuff like that but it works. The workaround is based on the fact that File.getAbsolutFile() by default returns the directory resolved against the directory defined by user.dir option. So I need some way to pass this option on Tomcat service start. The only way I've found to do this is to add -Duser.dir=/%CATALINA_HOME/ to the CATALINA_OPTS variable defined in %CATALINA_HOME/bin/setenv.sh file. After that the font scan process took normal amount of time and my app started to work fine.
I want to point my play application to a particular application config file based on the environment it is running in. There are three and they correspond to the standard Play states:
application.dev.conf
application.test.conf
application.prod.conf
A co-worker shared a method for doing this which requires setting an OS environment variable.
I'd like to eliminate the need to set an OS variable.
My preference is the use whatever Play uses at startup to know what mode it is in.
For example, if you execute play run from the command line, part of the output is "[info] play - Application started (Dev)"
I want to use this information in my Global.java where I override onLoadConfig like so:
public Configuration onLoadConfig(Configuration baseConfiguration, File f, ClassLoader loader) {
String playEnv=<some static method to get mode>;
Config additionalConfig = ConfigFactory.parseFile(new File(f,"conf/application."+playEnv+".conf"));
Config baseConfig = baseConfiguration.getWrappedConfiguration().underlying();
return new Configuration(baseConfig.withFallback(additionalConfig));
}
Everything that I find is how to do this after the application has been started i.e. using isDev(), isTest(), isProd().
Is there static method that provides the mode while I am overriding onLoadConfig in Global.java?
I think play run is dev, play start is prod.
EDIT: If you're looking to see what the current mode is, it's passed in through play.api.Play.current:
Play.current.mode match {
case Play.Mode.Dev => "dev"
case Play.Mode.Prod => "prod"
}
The issue appeared to be addressed in the latest Play (3.0.0). There is another onLoadConfig method added to Global witch has a mode: {Dev,Prod,Test} parameter.
public Configuration onLoadConfig(Configuration config, File path, ClassLoader classloader, Mode mode) {
return onLoadConfig(config, path, classloader); // default implementation
}
Play allows to specifying alternative configuration file with command line so no need for setting OS variables.
You can of course create some bash script / bat file to avoid writing it every time
I have been googling a little and did not find an answer which suited my specific case.
I am working on a project file manager classes, and discovered that it was developped to behave differently on Windows and Unix filesystems.
More specifically, it is compensating for the case-senstivity in Unix: when a file is not found, the manager will look for it in a case-insensitive way.
Before changing this code, I would like to implement some unit tests. However, our development machines and our CIP are both on Windows, and I have no Unix machine available. The machines and IDEs are provided by the customer. Virtualization is not an option, and dual-booting is even less.
Is there a way to test both Windows and Unix mode while being platform-independant for the build? I think the ideal would be to run the whole Test Class in a mode, and then in the other, but even a more hands-on solution would be great.
In production mode, the file managers are initialized using Spring, but they are the lowest level of the chain, using directly java.io.
Versions: Java 6, JUnit 4.9
You can use Jimfs with dependency
<dependency>
<groupId>com.google.jimfs</groupId>
<artifactId>jimfs</artifactId>
<version>1.1</version>
</dependency>
Then you could create a linux, windows and Mac file systems using
FileSystem fileSystem = Jimfs.newFileSystem(Configuration.osX());
FileSystem fileSystem = Jimfs.newFileSystem(Configuration.windows());
FileSystem fileSystem = Jimfs.newFileSystem(Configuration.unix());
example
class FilePathReader {
String getSystemPath(Path path) {
try {
return path
.toRealPath()
.toString();
} catch (IOException ex) {
throw new UncheckedIOException(ex);
}
}
}
class FilePathReaderUnitTest {
private static String DIRECTORY_NAME = "baeldung";
private FilePathReader filePathReader = new FilePathReader();
#Test
#DisplayName("Should get path on windows")
void givenWindowsSystem_shouldGetPath_thenReturnWindowsPath() throws Exception {
FileSystem fileSystem = Jimfs.newFileSystem(Configuration.windows());
Path path = getPathToFile(fileSystem);
String stringPath = filePathReader.getSystemPath(path);
assertEquals("C:\\work\\" + DIRECTORY_NAME, stringPath);
}
#Test
#DisplayName("Should get path on unix")
void givenUnixSystem_shouldGetPath_thenReturnUnixPath() throws Exception {
FileSystem fileSystem = Jimfs.newFileSystem(Configuration.unix());
Path path = getPathToFile(fileSystem);
String stringPath = filePathReader.getSystemPath(path);
assertEquals("/work/" + DIRECTORY_NAME, stringPath);
}
private Path getPathToFile(FileSystem fileSystem) throws Exception {
Path path = fileSystem.getPath(DIRECTORY_NAME);
Files.createDirectory(path);
return path;
}
}
All this copied from Baeldung.
You could dualboot Ubuntu easily by installing it with wubi.
I've learnt that unit-test should not access the file system for different reasons (speed being one of them).
For Java 6 look into theese:
http://docs.oracle.com/javase/6/docs/api/javax/tools/JavaFileManager.html
http://docs.oracle.com/javase/6/docs/api/javax/swing/filechooser/FileSystemView.html
If you were to use Java 7 this might help you:
http://download.oracle.com/javase/7/docs/technotes/guides/io/fsp/filesystemprovider.html
you could use a VM to test it on unix. Virtual Box by Oracle is agood virtualization software. Install Ubuntu, or Fedora, or some other unix based OS' Disk Image. Transfer your files to the VM. You can directly check out from your source control into the VM and you should be good to go. Atleast I am assuming that is what you want to do : test your software in both windows and linux, but currently don't have linux at your disposal
I've use Adobe native process to run java program from my air app. Here the code and it works fine. But i should write absolute path to java runtime for that:
/System/Library/Java/JavaVirtualMachines/1.6.0.jdk/Contents/Home/bin/java.
If user installed java runtime in diff folder, or have diff version then this code would not work. How i can detect where java were installed or maybe there is another right way to run java applications from air applications? If i run java library from terminal command line then i could just write "java -jar pdfbox-app-1.6.0.jar" etc. and it runs fine.
private function convertPdf2Txt():void{
var arg:Vector.<String> = new Vector.<String>;
arg.push("-jar");
arg.push(File.applicationDirectory.resolvePath("pdfbox-app-1.6.0.jar").nativePath);
arg.push("ExtractText");
arg.push("-force");
arg.push(File.applicationStorageDirectory.resolvePath("Data/1.pdf").nativePath);
arg.push(File.applicationStorageDirectory.resolvePath("Data/1.txt").nativePath);
var fjava:File = new File("/System/Library/Java/JavaVirtualMachines/1.6.0.jdk/Contents/Home/bin/java");
if (fjava.exists==false){
Alert.show("Can't find Java Runtime in default folder.","Idea Rover",mx.controls.Alert.OK, null,null,imgInfo);
return;
}
var npInfo:NativeProcessStartupInfo;
npInfo = new NativeProcessStartupInfo();
npInfo.executable = fjava;
npInfo.arguments = arg;
var nativeProcess:NativeProcess;
nativeProcess = new NativeProcess();
nativeProcess.addEventListener(NativeProcessExitEvent.EXIT,onNativeProcessExit);
nativeProcess.start(npInfo);
}
Absolute path is:
Mac OS: /usr/bin/java
Win OS: (default)
64bit : C:\Program Files\Java
32bit : C:\Program Files (x86)\Java
rather than popping up an Alert, you could open a file selection dialog, using File.browseForOpen(). then, the File you want is contained in the event passed by the Event.SELECT handler. this flow seems standard for applications i've used that need to access other applications, but aren't sure where to find their executables.
var npInfo:NativeProcessStartupInfo = new NativeProcessStartupInfo();
// setup npInfo, nativeProcess...
var fjava:File = new File("/System/Library/Java/JavaVirtualMachines/1.6.0.jdk/Contents/Home/bin/java");
if (!fjava.exists) {
fjava.addEventListener(Event.SELECT, onFileSelected);
fjava.browseForOpen("Where is Java located?");
}
private function onFileSelected (evt:Event) :void {
npInfo.executable = evt.target;
nativeProcess.start(npInfo);
fjava.removeEventListener(Event.SELECT, onFileSelected);
}
of course, you can use the same logic to find the file java needs to launch as well.
You may be able to determine where the Java binaries are by looking at the JAVA_HOME environment variable. I'd like to do the same thing as you're doing, so I'll post more after I do more research.