I'm having a huge problem with my java webstart application, I have tries a lot of solutions, but none seems to work correctly in th end.
I need to write a webstart applet to load basic hardware info about the client computer to check if my client can connect on our systems and use the software four our courses. I use Sigar to load the CPU and Memory information and then use JNI to load a custom c++ script that check the graphic card name (This one works perfectly).
I've put all my dlls in src/resources folder to load them in the jar, I also use what we call here "engines" which are classed that do specified operations (In our case, Jni Engine, Config Engine and Data Engine (Code below)), I'm new to webstart so I'm not sure if this concept works well with library loading.
I've tries to add the dlls in a jar as a library in Netbeans, I've tried to add the dlls in the jnlp, but each run recreates it and I can't add them with project properties, finnaly, I've built my Data Engine in a way that should load the dlls in the java temp directory in case they are not there, but Sigar still don't want to work. I've also put my dll in the java.library.path correctly cofigured (As it works in local).
It work when I run my main class locally (With right click-run), but when I click the run button to load the webstart, it crashes with this error message (it happens in ConfigEngine as it extends SigarBase) :
JNLPClassLoader: Finding library sigar-amd64-winnt.dll.dll
no sigar-amd64-winnt.dll in java.library.path
org.hyperic.sigar.SigarException: no sigar-amd64-winnt.dll in java.library.path
Here's the code :
JNi Engine (Loads the c++ code for the graphic card)
package Engine;
public class JniEngine
{
static private final String nomLibJni = "JniEngine";
static private final String nomLibJni64 = "JniEngine_x64";
static
{
if (System.getProperty("os.arch").contains("86"))
{
System.loadLibrary(nomLibJni);
}
else
{
System.loadLibrary(nomLibJni64);
}
}
public native String getInfoGPU() throws Error;
}
ConfigEngine
package Engine;
import java.net.NetworkInterface;
import java.net.SocketException;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import org.hyperic.sigar.Sigar;
import org.hyperic.sigar.SigarException;
import org.hyperic.sigar.cmd.SigarCommandBase;
public class ConfigEngine extends SigarCommandBase
{
private final String nomOsAcceptes = "Windows";
static
{
DataEngine data;
}
public ConfigEngine()
{
super();
}
#Override
public void output(String[] args) throws SigarException
{
}
public HashMap<String, String> getMap() throws SigarException, SocketException
{
HashMap<String, String> hmConfig = new HashMap<>();
loadInfoCpu(hmConfig);
loadInfoRam(hmConfig);
loadInfoOs(hmConfig);
loadInfoNet(hmConfig);
loadInfoGpu(hmConfig);
return hmConfig;
}
private void loadInfoCpu(HashMap<String,String> Hashmap) throws SigarException
{
org.hyperic.sigar.CpuInfo[] configCpu = this.sigar.getCpuInfoList();
org.hyperic.sigar.CpuInfo infoCpu = configCpu[0];
long cacheSize = infoCpu.getCacheSize();
Hashmap.put("Builder", infoCpu.getVendor());
Hashmap.put("Model" , infoCpu.getModel());
Hashmap.put("Mhz", String.valueOf(infoCpu.getMhz()));
Hashmap.put("Cpus nbr", String.valueOf(infoCpu.getTotalCores()));
if ((infoCpu.getTotalCores() != infoCpu.getTotalSockets()) ||
(infoCpu.getCoresPerSocket() > infoCpu.getTotalCores()))
{
Hashmap.put("Cpus", String.valueOf(infoCpu.getTotalSockets()));
Hashmap.put("Core", String.valueOf(infoCpu.getCoresPerSocket()));
}
if (cacheSize != Sigar.FIELD_NOTIMPL) {
Hashmap.put("Cache", String.valueOf(cacheSize));
}
}
private void loadInfoRam(HashMap<String,String> Hashmap) throws SigarException
{
org.hyperic.sigar.Mem mem = this.sigar.getMem();
Hashmap.put("RAM" , String.valueOf(mem.getRam()));
Hashmap.put("Memoery", String.valueOf(mem.getTotal()));
Hashmap.put("Free", String.valueOf(mem.getUsed()));
}
private void loadInfoOs(HashMap<String,String> Hashmap) throws SigarException
{
Hashmap.put("OS", System.getProperty("os.name"));
Hashmap.put("Version", System.getProperty("os.version"));
Hashmap.put("Arch", System.getProperty("os.arch"));
}
private void loadInfoNet(HashMap<String,String> Hashmap) throws SocketException
{
List<NetworkInterface> interfaces = Collections.
list(NetworkInterface.getNetworkInterfaces());
int i = 1;
for (NetworkInterface net : interfaces)
{
if (!net.isVirtual() && net.isUp())
{
Hashmap.put("Port Name " + String.valueOf(i), net.getDisplayName());
}
i++;
}
}
private void loadInfoGpu(HashMap<String,String> Hashmap) throws SocketException
{
if (System.getProperty("os.name").contains(nomOsAcceptes))
{
JniEngine Jni = new JniEngine();
Hashmap.put("VGA", Jni.getInfoGPU());
}
}
}
Finally my Data Engine which tries to load all the dlls and change the library path (Most of it is temporary as it is patches on patches)
package Engine;
import java.io.File;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.net.URL;
public class DataEngine
{
static private final String nomLibSigar = "sigar-x86-winnt";
static private final String nomLibSigar64 = "sigar-amd64-winnt";
static private final String nomLibJni = "JniEngine";
static private final String nomLibJni64 = "JniEngine_x64";
static private final String NomJar86 = "lib_config_x86";
static private final String nomJar64 = "lib_config_x64";
static private final String path = "Resources\\";
static
{
try
{
if (System.getProperty("os.arch").contains("86"))
{
System.loadLibrary(nomLibJni);
System.loadLibrary(nomLibSigar);
}
else
{
System.loadLibrary(nomLibJni64);
System.loadLibrary(nomLibSigar64);
}
}
catch (UnsatisfiedLinkError ex)
{
loadJniFromJar();
loadSigarFromJar();
}
}
public static void loadSigarFromJar()
{
try
{
File dll;
InputStream is;
if (System.getProperty("os.arch").contains("86"))
{
is = DataEngine.class.getResourceAsStream(
path + nomLibSigar + ".dll");
dll = File.createTempFile(path + nomLibSigar, ".dll");
}
else
{
is = DataEngine.class.getResourceAsStream(
path + nomLibSigar64 + ".dll");
dll = File.createTempFile(path + nomLibSigar64, ".dll");
}
FileOutputStream fos = new FileOutputStream(dll);
byte[] array = new byte[1024];
for (int i = is.read(array);
i != -1;
i = is.read(array))
{
fos.write(array, 0, i);
}
fos.close();
is.close();
System.load(dll.getAbsolutePath());
System.setProperty("java.library.path", dll.getAbsolutePath());
}
catch (Throwable e)
{
}
}
public static void loadJniFromJar()
{
try
{
File dll;
InputStream is;
if (System.getProperty("os.arch").contains("86"))
{
is = DataEngine.class.getResourceAsStream(
path + nomLibJni + ".dll");
dll = File.createTempFile(path + nomLibJni, ".dll");
}
else
{
is = DataEngine.class.getResourceAsStream(
path + nomLibJni64 + ".dll");
dll = File.createTempFile(path + nomLibJni64, ".dll");
}
FileOutputStream fos = new FileOutputStream(dll);
byte[] array = new byte[1024];
for (int i = is.read(array);
i != -1;
i = is.read(array))
{
fos.write(array, 0, i);
}
fos.close();
is.close();
System.load(dll.getAbsolutePath());
}
catch (Throwable e)
{
}
}
}
I also have some problem with my main class (NetBeans don't want my JAppletForm to be the main class of my project, but I'll probably recreate the project anyway since the hundreds of patches I tries have corrupted the build. My main class simply load the HashMap with GetMap of ConfigEngine and show it in the console if local or in the JAppletForm if it runs with webstart.
Its a pretty big problem so I'll update my question with all the info you'll need if asked.
Related
I want to use pre-populated database in Android Room. I found a way to make it through using the callback, and filled up the database files.
But something is wrong, I'm sure that the database is copied normally, but it remains empty in the device monitor and android emulator. Can you please help me
public abstract class AppDatabase extends RoomDatabase {
private static AppDatabase INSTANCE;
private static final String DB_NAME = "base.db";
static Context ctx;
public abstract Dao dao();
public static AppDatabase getDatabase(Context context) {
if (INSTANCE == null) {
ctx = context;
synchronized (AppDatabase.class) {
if (INSTANCE == null) {
INSTANCE = Room.databaseBuilder(context,
AppDatabase.class, DB_NAME)
.allowMainThreadQueries()
.addCallback(rdc)
.build();
}
}
}
return INSTANCE;
}
private static RoomDatabase.Callback rdc = new RoomDatabase.Callback() {
public void onCreate(SupportSQLiteDatabase db) {
new PopulateDbAsync(INSTANCE, ctx).execute();
Log.d("db create ", "table created when db created first time in onCreate");
}
public void onOpen(#NonNull SupportSQLiteDatabase db) {
ContentValues contentValues = new ContentValues();
}
};
private static class PopulateDbAsync extends AsyncTask<Void, Void, Void> {
private Dao dao;
AssetManager assetManager = ctx.getAssets();
PopulateDbAsync(AppDatabase db, Context context) {
Dao = db.Dao();
ctx = context;
}
#Override
protected Void doInBackground(final Void... params) {
String DB_PATH = "/data/data/mypackage/databases/";
String DB_NAME = "base.db";
try {
Log.d("AppDatabase","Trying copy database file");
OutputStream myOutput = new FileOutputStream(DB_PATH + DB_NAME);
byte[] buffer = new byte[1024];
int length;
InputStream myInput = ctx.getAssets().open("base.db");
while ((length = myInput.read(buffer)) > 0) {
myOutput.write(buffer, 0, length);
}
myInput.close();
myOutput.flush();
myOutput.close();
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
}
}
I solved after spending 6 hours on researching and R & D .
Context is that : - I want to put already existing finaldb.db(which is present inside assests folder) into room database .
Step 1 :
copy this framework files from here link
Step 2 :
You need to migrate , chill i have code :)
#Database(entities = {Status.class}, version = 1,exportSchema = false)
public abstract class AppDatabase extends RoomDatabase {
public abstract DataDao StatusDao();
private static AppDatabase INSTANCE;
public static AppDatabase getDatabase(Context context) {
if (INSTANCE == null) {
INSTANCE = createDatabase(context);
}
return (INSTANCE);
}
private static final Migration MIGRATION_2_3 = new Migration(1, 2) {
#Override
public void migrate(#NonNull SupportSQLiteDatabase database) {
Log.d("kkkk","bc");
String SQL_CREATE_TABLE = "CREATE TABLE IF NOT EXISTS 'Status' " +
"( 'id' INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT," +
" 'category' TEXT NOT NULL," +
" 'sub_category' TEXT NOT NULL," +
" 'content' TEXT NOT NULL," +
" 'favourite' INTEGER DEFAULT(0))";
database.execSQL(SQL_CREATE_TABLE);
}
};
private static AppDatabase createDatabase(Context context) {
RoomDatabase.Builder<AppDatabase> builder =
Room.databaseBuilder(context.getApplicationContext(), AppDatabase.class,
context.getString(R.string.dbase_name));
return (builder.openHelperFactory(new AssetSQLiteOpenHelperFactory())
.allowMainThreadQueries()
.addMigrations(MIGRATION_2_3)
.build());
}
}
In MIGRATION_2_3 you have to create table exactly same as current database(which is present in assests folder)
want to learn about migration
Step 3 :
Now table is created successfully in room database !
In case of crash see your logcat , in which its written in understandable form .
You cannot, properly, do the copy of the database in the onCreate method.
When the onCreate method is called the database has been created (the created database is passed to the method). You have to do the copy before the onCreate method and before the database is opened.
You could override's the RoomDatabase init method and do the copy from that method or do the copy before invoking the databaseBuilder.
I'm solved it.
Database class:
#Database(entities = {Entity1.class, Entity2.class, Entity3.class}, version = 1, exportSchema = false)
public abstract class AppDatabase extends RoomDatabase {
private static AppDatabase INSTANCE;
public abstract Entity1Dao 1Dao();
public abstract Entity2Dao 2Dao();
public abstract Entity3Dao 3Dao();
public static AppDatabase getDatabase(Context context) {
if (INSTANCE == null) {
INSTANCE = createDatabase(context);
}
return (INSTANCE);
}
private static AppDatabase createDatabase(Context context) {
RoomDatabase.Builder<AppDatabase> builder =
Room.databaseBuilder(context.getApplicationContext(), AppDatabase.class,
context.getString(R.string.dbase_name));
return (builder.openHelperFactory(new AssetSQLiteOpenHelperFactory())
.allowMainThreadQueries()
.build());
}
}
Also you should get SQL Helpers, link
My issue is a little bit different than the OP.
I was copying the database file from internal storage which I downloaded from the internet, not from assets. And java.lang.RuntimeException: Unable to copy database file is raised because I didn't grant READ_EXTERNAL_STORAGE before this, or in general granting WRITE_EXTERNAL_STORAGE as READ_EXTERNAL_STORAGE is included in WRITE_EXTERNAL_STORAGE and already need the write permission for downloading the file.
I am trying to extract data from the Samples namespace that comes with Intersystems Cache install. Specifically, I am trying to retrieve Sample.Company global data using XEP. Inorder to achieve this, I created Sample.Company class like this -
package Sample;
public class Company {
public Long id;
public String mission;
public String name;
public Long revenue;
public String taxId;
public Company(Long id, String mission, String name, Long revenue,
String taxId) {
this.id = id;
this.mission = mission;
this.name = name;
this.revenue = revenue;
this.taxId = taxId;
}
public Company() {
}
}
XEP related code looks like this -
import java.util.ArrayList;
import java.util.List;
import org.springframework.stereotype.Service;
import Sample.Company;
import com.intersys.xep.Event;
import com.intersys.xep.EventPersister;
import com.intersys.xep.EventQuery;
import com.intersys.xep.EventQueryIterator;
import com.intersys.xep.PersisterFactory;
import com.intersys.xep.XEPException;
#Service
public class CompanyService {
public List<Company> fetch() {
EventPersister myPersister = PersisterFactory.createPersister();
myPersister.connect("SAMPLES", "user", "pwd");
try { // delete any existing SingleStringSample events, then import
// new ones
Event.isEvent("Sample.Company");
myPersister.deleteExtent("Sample.Company");
String[] generatedClasses = myPersister.importSchema("Sample.Company");
for (int i = 0; i < generatedClasses.length; i++) {
System.out.println("Event class " + generatedClasses[i]
+ " successfully imported.");
}
} catch (XEPException e) {
System.out.println("import failed:\n" + e);
throw new RuntimeException(e);
}
EventQuery<Company> myQuery = null;
List<Company> list = new ArrayList<Company>();
try {
Event newEvent = myPersister.getEvent("Sample.Company");
String sql = "Select * from Sample.Company";
myQuery = newEvent.createQuery(sql);
newEvent.close();
myQuery.execute();
EventQueryIterator<Company> iterator = myQuery.getIterator();
while (iterator.hasNext()) {
Company c = iterator.next();
System.out.println(c);
list.add(c);
}
myQuery.close();
myPersister.close();
return list;
} catch (XEPException e) {
System.out.println("createQuery failed:\n" + e);
throw new RuntimeException(e);
}
}
}
When I try executing the fetch() method of the above class, I am seeing the following exception -
com.intersys.xep.XEPException: Cannot import - extent for Sample.Company not empty.
at com.intersys.xep.internal.Generator.generate(Generator.java:52)
at com.intersys.xep.EventPersister.importSchema(EventPersister.java:954)
at com.intersys.xep.EventPersister.importSchema(EventPersister.java:363)
I got the simple string example working. Does it mean, we can not read the existing data using XEP? If we can read, Could some please help me in resolving the above issue? Thanks in advance.
You are trying to create a new class named Sample.Company in your instance:
String[] generatedClasses = myPersister.importSchema("Sample.Company");
But you still have data and an existing class there.
I am looking for a way to (re)deploy an exploded bundle (meaning not jarred but in a folder) to a running Apache Felix OSGi container from within Eclipse, preferably using a launch task.
I found this question, which has an answer that comes close but it depends on typing commands into a Gogo shell, which is not convenient for long-term development use. I'd like to use Eclipse's launch task mechanism for this, but if there are alternatives that are equally fast and convenient I am open to that as well.
Now I think that if I can fire Gogo shell commands from an Eclipse launch tasks, that would be a solution, but I also can't get my head around how to do that. I presume I need the Remote Shell bundle for that right?
I am starting to think about writing a telnet client in Java that can connect to the Remote Shell bundle and execute Gogo commands in an automated fashion. I have seen some example of that already which I can modify to suit my needs... However I am getting a 'reinventing the wheel' kind of feeling from that. Surely there is a better way?
Some background to help you understand what I am doing:
I have set up an Eclipse 'OSGiContainer' project which basically contains the Apache Felix jar and the third party bundles I want to deploy (like Gogo shell), similar to the project setup described here. Then I created a second 'MyBundle' project that contains my bundle. I want to start the OSGi container by launching the OSGiContainer project, and then just develop on my bundle and test my changes by launching the MyBundle project into the OSGiContainer that I just want to keep running the whole time during development.
Project layout:
OSGiContainer
bin (contains felix jar)
bundles (third party bundles)
conf (Felix' config.properties file)
MyBundle
src
target
classes
I am then able to deploy my bundle to the OSGi container by invoking these commands on the Gogo shell:
install reference:file:../MyBundle/target/classes
start <bundleId>
To re-deploy, I invoke these commands:
stop <bundleId>
uninstall <bundleId>
install reference:file:../MyBundle/target/classes
start <bundleId>
You can imagine having to invoke 4 commands on the shell each time is not that much fun... So even if you can give me a way to boil this down to less commands to type it would be a great improvement already.
UPDATE
I hacked around a bit and came up with the class below. It's an adaptation of the telnet example with some small changes and a main method with the necessary commands to uninstall a bundle and then re-install and start it. The path to the bundle should be given as an argument to the program and would look like:
reference:file:../MyBundle/target/classes
I still very much welcome answers to this question, as I don't really like this solution at all. I have however verified that this works:
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintStream;
import java.net.SocketException;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.LinkedBlockingQueue;
import org.apache.commons.net.telnet.TelnetClient;
public class GogoDeployer {
static class Responder extends Thread {
private StringBuilder builder = new StringBuilder();
private final GogoDeployer checker;
private CountDownLatch latch;
private String waitFor = null;
private boolean isKeepRunning = true;
Responder(GogoDeployer checker) {
this.checker = checker;
}
boolean foundWaitFor(String waitFor) {
return builder.toString().contains(waitFor);
}
public synchronized String getAndClearBuffer() {
String result = builder.toString();
builder = new StringBuilder();
return result;
}
#Override
public void run() {
while (isKeepRunning) {
String s;
try {
s = checker.messageQueue.take();
} catch (InterruptedException e) {
break;
}
synchronized (Responder.class) {
builder.append(s);
}
if (waitFor != null && latch != null && foundWaitFor(waitFor)) {
latch.countDown();
}
}
System.out.println("Responder stopped.");
}
public String waitFor(String waitFor) {
synchronized (Responder.class) {
if (foundWaitFor(waitFor)) {
return getAndClearBuffer();
}
}
this.waitFor = waitFor;
latch = new CountDownLatch(1);
try {
latch.await();
} catch (InterruptedException e) {
e.printStackTrace();
return null;
}
String result = null;
synchronized (Responder.class) {
result = builder.toString();
builder = new StringBuilder();
}
return result;
}
}
static class TelnetReader extends Thread {
private boolean isKeepRunning = true;
private final GogoDeployer checker;
private final TelnetClient tc;
TelnetReader(GogoDeployer checker, TelnetClient tc) {
this.checker = checker;
this.tc = tc;
}
#Override
public void run() {
InputStream instr = tc.getInputStream();
try {
byte[] buff = new byte[1024];
int ret_read = 0;
do {
if (instr.available() > 0) {
ret_read = instr.read(buff);
}
if (ret_read > 0) {
checker.sendForResponse(new String(buff, 0, ret_read));
ret_read = 0;
}
} while (isKeepRunning && (ret_read >= 0));
} catch (Exception e) {
System.err.println("Exception while reading socket:" + e.getMessage());
}
try {
tc.disconnect();
checker.stop();
System.out.println("Disconnected.");
} catch (Exception e) {
System.err.println("Exception while closing telnet:" + e.getMessage());
}
}
}
private static final String prompt = "g!";
private static GogoDeployer client;
private String host;
private BlockingQueue<String> messageQueue = new LinkedBlockingQueue<String>();
private int port;
private TelnetReader reader;
private Responder responder;
private TelnetClient tc;
public GogoDeployer(String host, int port) {
this.host = host;
this.port = port;
}
public void stop() {
responder.isKeepRunning = false;
reader.isKeepRunning = false;
try {
Thread.sleep(10);
} catch (InterruptedException e) {
}
responder.interrupt();
reader.interrupt();
}
public void send(String command) {
PrintStream ps = new PrintStream(tc.getOutputStream());
ps.println(command);
ps.flush();
}
public void sendForResponse(String s) {
messageQueue.add(s);
}
public void connect() throws SocketException, IOException {
tc = new TelnetClient();
tc.connect(host, port);
reader = new TelnetReader(this, tc);
reader.start();
responder = new Responder(this);
responder.start();
}
public String waitFor(String s) {
return responder.waitFor(s);
}
private static String exec(String cmd) {
String result = "";
System.out.println(cmd);
client.send(cmd);
result = client.waitFor(prompt);
return result;
}
public static void main(String[] args) {
try {
String project = args[0];
client = new GogoDeployer("localhost", 6666);
client.connect();
System.out.println(client.waitFor(prompt));
System.out.println(exec("uninstall " + project));
String result = exec("install " + project);
System.out.println(result);
int start = result.indexOf(":");
int stop = result.indexOf(prompt);
String bundleId = result.substring(start + 1, stop).trim();
System.out.println(exec("start " + bundleId));
client.stop();
} catch (SocketException e) {
System.err.println("Unable to conect to Gogo remote shell: " + e.getMessage());
} catch (IOException e) {
System.err.println("Unable to conect to Gogo remote shell: " + e.getMessage());
}
}
}
When I met the same requirement (deploy bundle from target/classes as fast as I can) my first thought was also extending my container with some shell functionality. My second thought was, however, to write a simple bundle that opens up an always-on-top window and I can simply drag-and-drop any project(s) from Eclipse (or total commander or whatever) to that window. The code than checks if the folder(s) that was dropped has a target/classes folder and if it has it will be deployed.
The source code is available at https://github.com/everit-org/osgi-richconsole
The dependency is available from the maven-central.
The dependency is:
<dependency>
<groupId>org.everit.osgi.dev</groupId>
<artifactId>org.everit.osgi.dev.richconsole</artifactId>
<version>1.2.0</version>
</dependency>
You can use the bundle it while you develop and remove it when you set up your live server. However it is not necessary as if the container is running in a headless mode the pop-up window is not shown.
I called it richconsole as I would like to have more features in the future (not just deployment) :)
I use org.apache.commons.fileupload to upload file
class StorageService is a service that use cloud storage APIs to store file
This is my code
public class UploadFileAction extends org.apache.struts.action.Action {
private static final String SUCCESS = "success";
private StorageService storage = new StorageService();
private static final int BUFFER_SIZE = 1024 * 1024;
#Override
public ActionForward execute(ActionMapping mapping, ActionForm form,
HttpServletRequest request, HttpServletResponse response)
throws Exception {
ServletFileUpload upload = new ServletFileUpload();
FileItemIterator iter = upload.getItemIterator(request);
while (iter.hasNext()) {
FileItemStream item = iter.next();
String fileName = item.getName();
String mime = item.getContentType();
storage.init(fileName, mime);
InputStream is = item.openStream();
byte[] b = new byte[BUFFER_SIZE];
int readBytes = is.read(b, 0, BUFFER_SIZE);
while (readBytes != -1) {
storage.storeFile(b, BUFFER_SIZE);
readBytes = is.read(b, 0, readBytes);
}
is.close();
storage.destroy();
}
return mapping.findForward(SUCCESS);
}
}
package storageservice;
import com.google.appengine.api.files.*;
import com.google.appengine.api.files.GSFileOptions.GSFileOptionsBuilder;
import java.io.*;
import java.nio.channels.Channels;
public class StorageService {
private static final String BUCKET_NAME = "thoitbk";
private FileWriteChannel writeChannel = null;
private OutputStream os = null;
public void init(String fileName, String mime) throws Exception {
FileService fileService = FileServiceFactory.getFileService();
GSFileOptionsBuilder builder = new GSFileOptionsBuilder()
.setAcl("public_read")
.setBucket(BUCKET_NAME)
.setKey(fileName)
.setMimeType(mime);
AppEngineFile writableFile = fileService.createNewGSFile(builder.build());
boolean lock = true;
writeChannel = fileService.openWriteChannel(writableFile, lock);
os = Channels.newOutputStream(writeChannel);
}
public void storeFile(byte[] b, int readSize) throws Exception {
os.write(b, 0, readSize);
os.flush();
}
public void destroy() throws Exception {
os.close();
writeChannel.closeFinally();
}
}
In local this works fine but error when I deploy my app
Please help me!
Make sure your app's service account has WRITE access to the bucket in question, either by adding the service account to the team with can edit rights or else update the bucket acl to explicitly grant the service account WRITE access. See this question for more details.
import java.io.IOException;
import utils.myDate;
import utils.myLog;
import de.schlichtherle.truezip.file.TArchiveDetector;
import de.schlichtherle.truezip.file.TFile;
public class Main
{
/**
* #param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
Extract(new String("C:/Documents and Settings/mitracomm/My Documents/Downloads/JAR"), new String("D:/Source/Extract Result") , "");
}
private static void Extract(String src, String dst, String incPath)
{
TFile srcFile = new TFile(src + "/" + incPath);
TFile dstFile = new TFile(dst);
try {
TFile.cp_rp(srcFile, dstFile, TArchiveDetector.ALL);
} catch (IOException e) {
myLog.add(myDate.today("yyyyMMdd") + ".log", "error", e.getMessage());
}
}
Will the above code work with a large archive? Also, how can I extract every archive in a directory without having to fill the incPath or specify archives' name? I have tried to do this but I end up with copies of all the archives from origin directory and not extracted files.
The code is principally OK, but I'ld use:
public class Main {
public static void main(String[] args) {
Extract(new String("C:/Documents and Settings/mitracomm/My Documents/Downloads/JAR"), new String("D:/Source/Extract Result") , "");
}
private static void Extract(String src, String dst, String incPath) {
TFile srcFile = new TFile(src, incPath);
TFile dstFile = new TFile(dst);
try {
TFile.cp_rp(srcFile, dstFile, TArchiveDetector.NULL);
} catch (IOException e) {
// I don't like logging for this purpose, but if you must...
myLog.add(myDate.today("yyyyMMdd") + ".log", "error", e.getMessage());
}
}
}
I'm not sure if you really want three arguments for the Extract method, though.
And finally, yes TrueZIP handles ZIP files beyond 4GB size correctly.