Parse method of BasicDexFileReader - arrays

I would like to know if I can use the parse method of BasicDexFileReader to load a dexfile which is decrypted into a byte array?
public void parse(byte[] dexBytes) throws IllegalArgumentException, IOException/*,
RefNotFoundException */ {
// Get a DalvikValueReader on the input stream.
reader = new DalvikValueReader(dexBytes, FILE_SIZE_OFFSET);
readHeader();
readStrings();
readTypes();
}
I would be glad if someone can explain what exactly is the purpose of parse method and can it be used in a way i have asked.
Thanks

Take a look at DexMaker.java, which needs to solve this problem for generating code rather than decrypting it.
Here's the relevant sample:
byte[] dex = ...;
/*
* This implementation currently dumps the dex to the filesystem. It
* jars the emitted .dex for the benefit of Gingerbread and earlier
* devices, which can't load .dex files directly.
*
* TODO: load the dex from memory where supported.
*/
File result = File.createTempFile("Generated", ".jar", dexCache);
result.deleteOnExit();
JarOutputStream jarOut = new JarOutputStream(new FileOutputStream(result));
jarOut.putNextEntry(new JarEntry(DexFormat.DEX_IN_JAR_NAME));
jarOut.write(dex);
jarOut.closeEntry();
jarOut.close();
try {
return (ClassLoader) Class.forName("dalvik.system.DexClassLoader")
.getConstructor(String.class, String.class, String.class, ClassLoader.class)
.newInstance(result.getPath(), dexCache.getAbsolutePath(), null, parent);
} catch (ClassNotFoundException e) {
throw new UnsupportedOperationException("load() requires a Dalvik VM", e);
} catch (InvocationTargetException e) {
throw new RuntimeException(e.getCause());
} catch (InstantiationException e) {
throw new AssertionError();
} catch (NoSuchMethodException e) {
throw new AssertionError();
} catch (IllegalAccessException e) {
throw new AssertionError();
}

Related

Reading Hadoop sequence file in Flink

How to read Hadoop sequence file in Flink? I hit multiple issues with the approach below.
I have:
DataSource<String> source = env.readFile(new SequenceFileInputFormat(config), filePath);
and
public static class SequenceFileInputFormat extends FileInputFormat<String> {
...
#Override
public void setFilePath(String filePath) {
org.apache.hadoop.conf.Configuration config = HadoopUtils.getHadoopConfiguration(configuration);
logger.info("Initializing:"+filePath);
org.apache.hadoop.fs.Path hadoopPath = new org.apache.hadoop.fs.Path(filePath);
try {
reader = new SequenceFile.Reader(hadoopPath.getFileSystem(config), hadoopPath, config);
key = (Writable) ReflectionUtils.newInstance(reader.getKeyClass(), config);
value = (Writable) ReflectionUtils.newInstance(reader.getValueClass(), config);
} catch (IOException e) {
logger.error("sequence file creation failed.", e);
}
}
}
One of the issues: Could not read the user code wrapper: SequenceFileInputFormat.
Once you get an InputFormat, you can call ExecutionEnvironment.createInput(<input format>) to create your DataSource.
For SequenceFiles, the type of the data is always Tuple2<key, value>, so you have to use a map function to convert to whatever type you're trying to read.
I use this code to read a SequenceFile that contains Cascading Tuples...
Job job = Job.getInstance();
FileInputFormat.addInputPath(job, new Path(directory));
env.createInput(HadoopInputs.createHadoopInput(new SequenceFileInputFormat<Tuple, Tuple>(), Tuple.class, Tuple.class, job);

How to use the retrieveConnected method?

I'd like to know how to use the retrieveConnected() method from the Bluetooth class please. This class is part of the CN1Bluetooth.cn1lib.
I don't know how to get the paired devices with this method.
Unfortunately, there are no examples about the using of this method.
EDIT:
I used retrieveConnected() as you told me to do:
Button retco = new Button("Retrieve");
this.add(retco);
retco.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent ev) {
try {
debug("Action performed 1: "+ev);
debug("Bt: "+bt);
ArrayList ar = new ArrayList();
//ar.add("180D");
debug("array: "+ar);
bt.retrieveConnected(
new ActionListener() {
public void actionPerformed(ActionEvent ev) {
debug("actionPerformed : " + ev);
main.add(new SpanLabel("TEST 3"));
debug("ev.getSource() = " + ev.getSource());
JSONObject res = (JSONObject)ev.getSource();
debug("RES = " + res);
try {
updateUI(res);
} catch (JSONException e) {
// TODO Auto-generated catch block
debug(e.getMessage());
}
};
},ar);
} catch (IOException e) {
// TODO Auto-generated catch block
debug(e.getMessage());
}
}
});
private void updateUI(JSONObject obj) throws JSONException {
this.add(new SpanLabel(obj.toString()));
this.add(new SpanLabel("TEST"));
this.revalidate();
}
But i have those error messages
ca.weblite.codename1.json.JSONException: A JSONObject text must begin with '{' at character 1 of []
at ca.weblite.codename1.json.JSONTokener.syntaxError(JSONTokener.java:448)
at ca.weblite.codename1.json.JSONObject.<init>(JSONObject.java:176)
at ca.weblite.codename1.json.JSONObject.<init>(JSONObject.java:253)
atcom.codename1.cordova.CordovaCallbackManager.sendResult(CordovaCallbackManager.java:50)
at com.codename1.cordova.CallbackContext.sendPluginResult(CallbackContext.java:26)
at com.codename1.bluetoothle.BluetoothLePlugin.retrieveConnectedAction(BluetoothLePlugin.java:1212)
at com.codename1.bluetoothle.BluetoothLePlugin.execute(BluetoothLePlugin.java:306)
at com.codename1.cordova.CordovaPlugin.execute(CordovaPlugin.java:34)
at com.codename1.cordova.CordovaNativeImpl.execute(CordovaNativeImpl.java:14)
at com.codename1.cordova.CordovaNativeStub.execute(CordovaNativeStub.java:9)
at com.codename1.cordova.Cordova.execute(Cordova.java:29)
at com.codename1.bluetoothle.Bluetooth.retrieveConnected(Bluetooth.java:129)
at be.ssii.app.forms.EidReader$3.actionPerformed(Unknown Source:97)
at com.codename1.ui.util.EventDispatcher.fireActionEvent(EventDispatcher.java:349)
at com.codename1.ui.Button.fireActionEvent(Button.java:570)
at com.codename1.ui.Button.released(Button.java:604)
at com.codename1.ui.Button.pointerReleased(Button.java:708)
at com.codename1.ui.Form.pointerReleased(Form.java:3369)
at com.codename1.ui.Component.pointerReleased(Component.java:4552)
at com.codename1.ui.Display.handleEvent(Display.java:2180)
at com.codename1.ui.Display.edtLoopImpl(Display.java:1152)
at com.codename1.ui.Display.mainEDTLoop(Display.java:1070)
at com.codename1.ui.RunnableWrapper.run(RunnableWrapper.java:120)
at com.codename1.impl.CodenameOneThread$1.run(CodenameOneThread.java:60)
at java.lang.Thread.run(Thread.java:764)
There is one device paired to the device which use the app but it doesn't detect the paired one. It should work, the paired device is a BLE device.
The method retrieved paired Bluetooth LE devices. In iOS, devices that are "paired" to will not return during a normal scan. Callback is "instant" compared to a scan. UUID filtering might not work on Android, so it returns all paired BLE devices.
bluetoothle.retrieveConnected(e -> { }, params);
The params value is an array of service IDs to filter the retrieval by. If no service IDs are specified, no devices will be returned.
E.g.
ArrayList a = new ArrayList();
a.add("180D");
a.add("180F");
On success you should get an array of device objects as a result.
However looking at the code here: https://github.com/chen-fishbein/bluetoothle-codenameone/blob/master/CN1Bluethooth/src/com/codename1/bluetoothle/Bluetooth.java#L135
It looks like this line is wrong and should be changed from this:
plugin.execute("retrieveConnected", j.toString(), callack);
To this:
plugin.execute("retrieveConnected", callack, callack, j.toString());
But I haven't tested this.

Selenium-Extent_Reports: Not able to view the failure screenshots on other Computer/Machine

-Failure Screenshot are visible in Extent_Reports on my local machine. But not able to view the failure screenshot in Extent_Reports on other Computer/Machine.
-When i trigger build from Jenkins, After build successful, Sending email to:Recipient List
To Capture Screenshot
public String captureScreen(String fileName) {
if(fileName =="") {
fileName="Screenshot"; }
File destFile=null;
Calendar calendar =Calendar.getInstance() ;
SimpleDateFormat formater= new SimpleDateFormat("dd_MM_yyy_hh_mm_ss");
File srcFile=((TakesScreenshot)driver).getScreenshotAs(OutputType.FILE);
try {
String reportDirectory = "/src/main/java/com/test/automation/Demo/screenshot/";
//String reportDirectory= new File(System.getProperty("user.dir")).getAbsolutePath()+"./src/main/java/com/test/automation/Demo/screenshot/";
destFile= new File((String)reportDirectory + fileName +"-" + formater.format(calendar.getTime())+ ".png");
FileUtils.copyFile(srcFile,destFile );
//This will help us to link screen shot in Extent report
Reporter.log("<a href='"+destFile+ "'><img src='" +destFile+"' height='100' width='100'/></a>");
//Reporter.log("<a href='"+destFile.getAbsolutePath()+ "'><img src='" +destFile.getAbsolutePath()+"' height='100' width='100'/></a>");
}
catch(IOException e) {
e.printStackTrace();
}
return destFile.toString();
}
For generating Extent reports with screenshots for Failure test cases
public void getresult(ITestResult result) {
if(result.getStatus()==ITestResult.FAILURE)
{
test.log(LogStatus.ERROR, result.getName()+" Test case FAILED due to below issues: "+result.getThrowable());
String screen = captureScreen("");
test.log(LogStatus.FAIL," Failure Screenshot : "+ test.addScreenCapture(screen));
}}
If You're using remoteWebDriver than it must be augmented before you can use the screenshot capability. Did You try to
WebDriver driver = new RemoteWebDriver();
driver = new Augmenter().augment(driver);
// or for mobile driver
androidDriver.setFileDetector(new LocalFileDetector());
//this is needed when using remoteDriver
Here is how I take screenshot for ExtentReport
File scrFile = driver.getScreenshotAs(OutputType.FILE);
String dest = System.getProperty("user.dir") + "/resources/screenshots/" + dataMethod.getAndroidDriver().getSessionId() + ".png";
File destination = new File(dest);
try {
FileUtils.copyFile(scrFile, destination);
// this is just utility which takes screenshot and copy it to desired destination
dataMethod.setScreenshotPath(destination.getAbsolutePath());
} catch (IOException e) {
e.printStackTrace();
}
And on code failure:
#Override
public synchronized void onTestFailure(ITestResult result) {
setTestEndTime(result);
ExtentTest extentTest = methodData.getExtentTest();
extentTest.addScreenCaptureFromPath(methodData.getScreenshotPath());
}
Hope this will help.
I didn't used Extent reports, i have my own implementation for reports. But i am expecting is there is issue with src
<img src='" +destFile+"' height='100' width='100'/></a>");
Here, destFile brings location of image or screenshot which is related to your machine. the same should not be works for others. We have to use relative path, see this
https://www.w3schools.com/html/html_filepaths.asp
And also make sure that when sharing reports, it should contains all requires files and folders also.
Normally, the issue happens as the local files are not allowed to be loaded. So even we put relative or absolute path, that seems not work for many cases.
So I try to take base64screenshot instead, and it displays quite good in Extent Report.
To have the screenshot in folder report, just need to take screenshot as usual.
public static String getBase64Screenshot(WebDriver driver, String screenshotName) throws IOException {
String encodedBase64 = null;
FileInputStream fileInputStream = null;
TakesScreenshot screenshot = (TakesScreenshot) driver;
File source = screenshot.getScreenshotAs(OutputType.FILE);
String destination = windowsPath + "\\FailedTestsScreenshots\\"+screenshotName+timeStamp+".png";
File finalDestination = new File(destination);
FileUtils.copyFile(source, finalDestination);
try {
fileInputStream =new FileInputStream(finalDestination);
byte[] bytes =new byte[(int)finalDestination.length()];
fileInputStream.read(bytes);
encodedBase64 = new String(Base64.encodeBase64(bytes));
}catch (FileNotFoundException e){
e.printStackTrace();
}
return encodedBase64;
}
Call it in failure cases:
public synchronized void onTestFailure(ITestResult result) {
System.out.println("==="+methodDes + "=== failed!");
try {
WebDriver driver = (WebDriver) result.getTestContext().getAttribute("driver");
String base64Screenshot = ExtentManager.getBase64Screenshot(driver, result.getName());
MediaEntityModelProvider mediaModel = MediaEntityBuilder.createScreenCaptureFromBase64String(base64Screenshot).build();
test.get().fail("image:", mediaModel);
} catch (IOException e) {
e.printStackTrace();
}
test.get().fail(result.getThrowable().getMessage());
}

Using Database as Alfresco ContentStore

I'm working with Alfresco 4.2 and I need to use a table in my database as document content store.
Collecting some information hither and thither over the internet, I read that I have to just implement my custom DBContentStore DBContentWriter and DBContentReader classes. Someone told me to take as reference the FileContentStore class.
I need some help to mapping the FileContentStore in order to match my new class.
For example;
The DBContentWriter has to extend AbstractContentWriter and in the API docs I read that the only methods I have to overwrite are:
getReader() to create a reader to the underlying content
getDirectWritableChannel() to write content to the repository.
What about the second method?
protected WritableByteChannel getDirectWritableChannel()
This is called by getContentOutputStream():
public OutputStream getContentOutputStream() throws ContentIOException
{
try
{
WritableByteChannel channel = getWritableChannel();
OutputStream is = new BufferedOutputStream(Channels.newOutputStream(channel));
// done
return is;
}
The main method is the putContent(InputStream is) which wants to write content into a DB table.
public final void putContent(InputStream is) throws ContentIOException
{
try
{
OutputStream os = getContentOutputStream();
copyStreams(is, os);
Where copyStreams does something like this:
public final int copyStreams(InputStream in, OutputStream out, long sizeLimit) throws IOException
{
int byteCount = 0;
IOException error = null;
long totalBytesRead = 0;
try
{
byte[] buffer = new byte[BYTE_BUFFER_SIZE];
int bytesRead = -1;
while ((bytesRead = in.read(buffer)) != -1)
{
// We are able to abort the copy immediately upon limit violation.
totalBytesRead += bytesRead;
if (sizeLimit > 0 && totalBytesRead > sizeLimit)
{
StringBuilder msg = new StringBuilder();
msg.append("Content size violation, limit = ")
.append(sizeLimit);
throw new ContentLimitViolationException(msg.toString());
}
out.write(buffer, 0, bytesRead);
byteCount += bytesRead;
}
out.flush();
}
finally
{
try
{
in.close();
}
catch (IOException e)
{
error = e;
logger.error("Failed to close output stream: " + this, e);
}
try
{
out.close();
}
catch (IOException e)
{
error = e;
logger.error("Failed to close output stream: " + this, e);
}
}
if (error != null)
{
throw error;
}
return byteCount;
}
}
The main target is to write some code in order to write and read from the DB using these methods.
When the out.flush() is called i should have to write into the BLOB field.
thanks
Without looking at the example implementation in FileContentStore it is difficult to determine everything that getDirectWritableChennel() needs to do. Needless to say actually creating a WritableByteChannel to your database should be relatively easy.
Assuming you are using the BLOB type and you are using JDBC to get at your database then you just need to set a stream for your BLOB and turn it in to a channel.
OutputStream stream = myBlob.setBinaryStream(1);
WritableByteChannel channel = Channels.newChannel(stream);
Will you need to overwrite other methods? Maybe. If you have specific issues with those feel free to raise them.

Get stream from java.sql.Blob in Hibernate

I'm trying to use hibernate #Entity with java.sql.Blob to store some binary data. Storing doesn't throw any exceptions (however, I'm not sure if it really stores the bytes), but reading does. Here is my test:
#Test
public void shouldStoreBlob() {
InputStream readFile = getClass().getResourceAsStream("myfile");
Blob blob = dao.createBlob(readFile, readFile.available());
Ent ent = new Ent();
ent.setBlob(blob);
em.persist(ent);
long id = ent.getId();
Ent fromDb = em.find(Ent.class, id);
//Exception is thrown from getBinaryStream()
byte[] fromDbBytes = IOUtils.toByteArray(fromDb.getBlob().getBinaryStream());
}
So it throws an exception:
java.sql.SQLException: could not reset reader
at org.hibernate.engine.jdbc.BlobProxy.getStream(BlobProxy.java:86)
at org.hibernate.engine.jdbc.BlobProxy.invoke(BlobProxy.java:108)
at $Proxy81.getBinaryStream(Unknown Source)
...
Why? Shouldn't it read bytes form DB here? And what can I do for it to work?
Try to refresh entity:
em.refresh(fromDb);
Stream will be reopened. I suspect that find(...) is closing the blob stream.
It is not at all clear how you are using JPA here, but certainly you do not need to deal with Blob data type directly if you are using JPA.
You just need to declare a field in the entity in question of #Lob somewhat like this:
#Lob
#Basic(fetch = LAZY)
#Column(name = "image")
private byte[] image;
Then, when you retrieve your entity, the bytes will be read back again in the field and you will be able to put them in a stream and do whatever you want with them.
Of course you will need a getter and setter methods in your entity to do the byte conversion. In the example above it would be somewhat like:
private Image getImage() {
Image result = null;
if (this.image != null && this.image.length > 0) {
result = new ImageIcon(this.image).getImage();
}
return result;
}
And the setter somewhat like this
private void setImage(Image source) {
BufferedImage buffered = new BufferedImage(source.getWidth(null), source.getHeight(null), BufferedImage.TYPE_INT_RGB);
Graphics2D g = buffered.createGraphics();
g.drawImage(source, 0, 0, null);
g.dispose();
ByteArrayOutputStream stream = new ByteArrayOutputStream();
try {
ImageIO.write(buffered, "JPEG", stream);
this.image = stream.toByteArray();
}
catch (IOException e) {
assert (false); // should never happen
}
}
}
You need to set a breakpoint on method org.hibernate.engine.jdbc.BlobProxy#getStream on line stream.reset() and examine a reason of IOException:
private InputStream getStream() throws SQLException {
try {
if (needsReset) {
stream.reset(); // <---- Set breakpoint here
}
}
catch ( IOException ioe) {
throw new SQLException("could not reset reader");
}
needsReset = true;
return stream;
}
In my case the reason of IOException was in usage of org.apache.commons.io.input.AutoCloseInputStream as a source for Blob:
InputStream content = new AutoCloseInputStream(stream);
...
Ent ent = new Ent();
...
Blob blob = Hibernate.getLobCreator(getSession()).createBlob(content, file.getFileSize())
ent.setBlob(blob);
em.persist(ent);
While flushing a Session hibernate closes Inpustream content (or rather org.postgresql.jdbc2.AbstractJdbc2Statement#setBlob closes Inpustream in my case). And when AutoCloseInputStream is closed - it rases an IOException in method reset()
update
In your case you use a FileInputStream - this stream also throws an exception on reset method.
There is a problem in test case. You create blob and read it from database inside one transaction. When you create Ent, Postgres jdbc driver closes InputStream while flushing a session. When you load Ent (em.find(Ent.class, id)) - you get the same BlobProxy object, that stores already closed InputStream.
Try this:
TransactionTemplate tt;
#Test
public void shouldStoreBlob() {
final long id = tt.execute(new TransactionCallback<long>()
{
#Override
public long doInTransaction(TransactionStatus status)
{
try
{
InputStream readFile = getClass().getResourceAsStream("myfile");
Blob blob = dao.createBlob(readFile, readFile.available());
Ent ent = new Ent();
ent.setBlob(blob);
em.persist(ent);
return ent.getId();
}
catch (Exception e)
{
return 0;
}
}
});
byte[] fromStorage = tt.execute(new TransactionCallback<byte[]>()
{
#Override
public byte[] doInTransaction(TransactionStatus status)
{
Ent fromDb = em.find(Ent.class, id);
try
{
return IOUtils.toByteArray(fromDb.getBlob().getBinaryStream());
}
catch (IOException e)
{
return new byte[] {};
}
}
});
}
My current and only solution is closing the write session and opening new Hibernate session to get back the streamed data. It works. However I do not know what is the difference. I called inputStream.close(), but that was not enough.
Another way:
I tried to call free() method of blob after session.save(attachment) call too, but it throws another exception:
Exception in thread "main" java.lang.AbstractMethodError: org.hibernate.lob.SerializableBlob.free()V
at my.hibernatetest.HibernateTestBLOB.storeStreamInDatabase(HibernateTestBLOB.java:142)
at my.hibernatetest.HibernateTestBLOB.main(HibernateTestBLOB.java:60)
I am using PostgreSQL 8.4 + postgresql-8.4-702.jdbc4.jar, Hibernate 3.3.1.GA
Is the method IOUtils.toByteArray closing the input stream?

Resources