"Link" against a SWC in Flex - apache-flex

I'm trying to do a very simple app in Flash/Flex, that loads an image embedded in the swf itself and then shows it. The thing is I'm trying to do it using the command line only (mxmlc and compc) and without using #Embed, and failing miserably.
I have a very simple Main.as :
package
{
import flash.display.*;
import flash.utils.*;
public class Main extends Sprite
{
public function Main () : void
{
var pDef:Class = getDefinitionByName("icon_big.png") as Class;
var _image:BitmapData = new pDef(0, 0);
var pSprite:Sprite = new Sprite();
pSprite.graphics.beginBitmapFill(_image);
pSprite.graphics.drawRect(0, 0, _image.width, _image.height);
pSprite.graphics.endFill();
addChild(pSprite);
}
}
}
This works fine if I add icon_big.png to the Library using the Flash IDE, but I can't figure out how to do it from the command line.
I'm using compc to put the png inside a swc :
compc --include-file icon_big.png icon_big.png -output assets.swc
This generates a 17 kb assets.swf, slightly bigger than icon_big.png. Then I try to compile and link Main.as :
mxmlc -include-libraries+=assets.swc Main.as
This produces a 944 byte Main.swf, which clearly doesn't include the asset, and fails at runtime.
According to the mxmlc docs I found, -include-libraries should link with every class, including the ones not directly referenced by code (as is the case here, since I'm getting the class from code), and it unsurprisingly fails at runtime.
Note that this same code (or, more precisely, quite equivalent code) works when used within a Flash project - I'm not looking to fix the code, but how to do in the command line whatever Flash does internally.
I feel I'm just "not getting" something... any clues?

I recommend you to download the swftools from swftools.org. Once you have them, run:
swfdump -D assets.swf
Take a look in particular at the output which relates to SWF tag with value 76 (0x4C), called SYMBOLCLASS.
Here is an example of an exported class, named IntegerMemberBySlot:
[04c] 24 SYMBOLCLASS
exports 0001 as "IntegerMemberBySlot"
What symbols are you exporting from your assets.swf?

Have you tried adding the path of the assets to your source path parameter when compiling with mxmlc?
-source-path ./PATH/TO/ASSET

I think you need to embed the PNGs in a class, then compile that class into a SWC. I don't think you can put the PNGs directly into a SWC like you are trying to, but I could be wrong.

I had a similar situation (large project, resource swc with graphic assets), and no matter what I tried, I could't get Flex to include assets and classes not directly referenced from the project (I wanted to include different skins, and then instantiate the proper one at runtime, depending on the configuration).
Finally, I found a workaround by instead of static swc liking, switching over to runtime shared libraries (RSLs). Basically, flex unbundles the swc, and loads and links the included swf in runtime, before running the application itself. All of the classes and assets in the swf are loaded this way. May not be exactly what you're after, but it works for me.

Related

Flow-typed - Generate Libdef

I'm using Flow to help author a JS project. If I want to provide a libdef file to supplement it do I need to create it manually, or am I able to execute some magic command that I'm not aware of yet which will generate the lib def for me?
Something like $ flow-typed doyourmagic would be nice.
EDIT:
Found this https://stackoverflow.com/a/38906578/192999
Which says:
There's two things:
If the file is owned by you (i.e. not a third party lib inside node_modules or such), then you can create a *.js.flow file next to it that documents its exports.
If the file is not owned by you (i.e. third party lib inside node_modules or such), then you can create a libdef file inside flow-typed/name-of-library.js
For .js.flow files
you write the definitions like this:
// #flow
declare module.exports: { ... }
For libdef files you write the definitions like this:
declare module "my-third-party-library" { declare module.exports: {... } }
For my question I fall into the "is owned by you" camp.
I guess I'm confused as to:
How I write these files.
How/where I publish these files to package it up for another project to reference.
Also, why do I need to create the .js.flow file manually? Can this not be magically generated? Perhaps that's the intention going forward but not implemented yet.
I found a nice guide showing how to package flow code together with the compiled code. So:
You do not have to write your own libdefs, you can use the entire flow source code. If you want a definition with only the type declarations, you can look into flow gen-flow-files, although that is still experimental and might fail.
You can package them as *.js.flow and the flow checker will automatically pick those up when you import your library.

spring boot/spring web app embedded version number

What are the strategies to embed a unique version number in a Spring application?
I've got an app using Spring Boot and Spring Web.
Its matured enough that I want to version it and see it displayed on screen at run time.
I believe what you are looking for is generating this version number during build time (Usually by build tools like Ant, Maven or Gradle) as part of their build task chain.
I believe a quite common approach is to either put the version number into the Manifest.mf of the produced JAR and then read it, or create a file that is part of the produced JAR that can be read by your application.
Another solution would be just using Spring Boot's banner customization options described here: http://docs.spring.io/spring-boot/docs/current/reference/html/boot-features-spring-application.html#boot-features-banner
However, this will only allow you to change spring-boot banner.
I also believe that Spring Boot exposes product version that is set in Manifest.MF of your application. To achieve this you will need to make sure Implementation-Version attribute of the manifest is set.
Custom solution for access anywhere in the code
Lets assume you would like to have a version.properties file in your src/main/resources that contains your version information. It will contain placeholders instead of actual values so that these placeholders can be expanded during build time.
version=${prodVersion}
build=${prodBuild}
timestamp=${buildTimestamp}
Now that you have a file like this you need to fill it with actual data. I use Gradle so there I would make sure that processResources task which is automatically running for builds is expanding resources. Something like this should do the trick in the build.gradle file for Git-based code:
import org.codehaus.groovy.runtime.*
import org.eclipse.jgit.api.*
def getGitBranchCommit() {
try {
def git = Git.open(project.file(project.getRootProject().getProjectDir()));
def repo = git.getRepository();
def id = repo.resolve(repo.getFullBranch());
return id.abbreviate(7).name()
} catch (IOException ex) {
return "UNKNOWN"
}
}
processResources {
filesMatching("**/version.properties") {
expand (
"prodVersion": version,
"prodBuild": getGitBranchCommit(),
"buildTimestamp": DateGroovyMethods.format(new Date(), 'yyyy-MM-dd HH:mm')
)
}
}
processResources.outputs.upToDateWhen{ false }
In the code about the following is happening:
We defined a function that can take a build number out of the VCS
(in this case Git). The commit hash is limited to 7 characters.
We configure the processResources task to process
version.properties file and fill it with our variables.
prodVersion is taken from Gradle project version. It's usually set
as version in gradle.properties file (part of the general build
setup).
As a last step we ensure that it's always updated (Gradle
has some mechanics to detect if files ened to be processed
Considering you are on SVN, you will need to have a getSvnBranchCommit() method instead. You could for instance use SVNKit or similar for this.
The last thing that is missing now is reading of the file for use in your application.
This could be achieved by simply reading a classpath resource and parsing it into java.util.Properties. You could take it one step further and for instance create accessor methods specifically for each field, e.g getVersion(), getBuild(), etc.
Hope this helps a bit (even though may not be 100% applicable straight off)
Maven can be used to track the version number, e.g.:
<!-- pom.xml -->
<version>2.0.3</version>
Spring Boot can refer to the version, and expose it via REST using Actuator:
# application.properties
endpoints.info.enabled=true
info.app.version=#project.version#
Then use Ajax to render the version in the browser, for example using Polymer iron-ajax:
<!-- about-page.html -->
<iron-ajax auto url="/info" last-response="{{info}}"></iron-ajax>
Application version is: [[info.app.version]]
This will then show in the browser as:
Application version is: 2.0.3
I'm sure you've probably figured something out since this is an older question, but here's what I just did and it looks good. (Getting it into the banner requires you to duplicate a lot).
I'd recommend switching to git (it's a great SVN client too), and then using this in your build.gradle:
// https://github.com/n0mer/gradle-git-properties
plugins {
id "com.gorylenko.gradle-git-properties" version "1.4.17"
}
// http://docs.spring.io/spring-boot/docs/current/reference/html/deployment-install.html
springBoot {
buildInfo() // create META-INF/build-info.properties
}
bootRun.dependsOn = [assemble]
And this in your SpringBoot application:
#Resource
GitProperties props;
#Resource
BuildProperties props2;
Or this way to expose those properties into the standard spring environment:
#SpringBootApplication
#PropertySources({
#PropertySource("classpath:git.properties"),
#PropertySource("classpath:META-INF/build-info.properties")
})
public class MySpringBootApplication {
and then referencing the individual properties as needed.
#Value("${git.branch}")
String gitBranch;
#Value("${build.time}")
String buildTime;

How to deploy a Ruby class in a Java web project

I am trying to create an hybrid between a JRuby and a Java application, so that it may be possible to migrate single components at a time. What I am trying to do right now is really simple, here is the Ruby class:
require 'java'
java_package 'eu.netprophecy.test'
class RubyViewModel
java_signature 'String getGreeting()'
def getGreeting
puts "Hello, ZK, from Ruby!"
end
end
I want to be able to use this View Model from a ZK project:
<?page title="Hello, Ruby!" contentType="text/html;charset=UTF-8"?>
<zk>
<window title="Hello Ruby!!" border="normal" width="200px" apply="org.zkoss.bind.BindComposer"
viewModel="#id('vm') #init('eu.netprophecy.test.RubyViewModel')">
<label value="#load(vm.greeting)"/>
</window>
</zk>
I tried creating a jar with marbler, but it places the .class file with the java bytecode in a directory with the project name in front, messing with the expected package structure (in this case I get EJB/eu/netprophecy/test/RubyViewModel, which means I am unable to use the generated Java class in the Java code).
Does anyone know if this is at all possible, if there are better ways to do it,, or if I have to create manually the jar?
you need to generate a java class from your ruby class which is perfectly possible (even without pre-compilation) with become_java!, just make sure the ruby script gets executed before the view is rendered (or compiled I'm not sure what you're using).
class RubyViewModel
java_signature 'String getGreeting()'
def getGreeting
puts "Hello, ZK, from Ruby!"
end
end
require 'jruby/core_ext'
RubyViewModel.become_java! # returns a java.lang.Class
you might check the method is there (the java way) using :
RubyViewModel.java_class.getDeclaredMethods.map { |method| method.to_s }

Flex - error 1046 - some .as files don't get importet

I received a Flex project and when trying to compile it i get a few 1046 errors that say the Type was not found or was not a compile-time constant MyClass
however - the respective files are listed on the top of the file in an import clause like this:
import com.folder1.folder2.folder3.MyClass;
and if i check the folder structure, MyClass.as is there.
however, if i type this same line (import com.folder1.folder2.folder3.MyClass;) and check at each . what the autocompletion suggests, I see only a subset of the as classes that are actually there on the harddisk.
What determines which classes and folders are suggested by the autocompletion function? I don't get any compile error on the corresponding import statements that import MyClass
//edit:
screenshot 1 shows the file in which the error occurs that tries to import the class in question (Updater)
http://neo.cycovery.com/flex_problem.gif
screenshot 2 shows the file Updater.as
http://neo.cycovery.com/flex_problem2.gif
the censored part of the path matches in both cases (folder structure and package statement in Updater.as)
screenshot 3 shows where the error actually happens:
http://neo.cycovery.com/flex_problem3.gif
interestingly, the variable declaration
private var _updater:Updater = new Updater();
further up in the file does not give an error
This project is set up wrong. Its obvious your application can not find the classes.
Move your "com" folder and all of the contents into your "src" folder.
Or perhaps include the files in your source path?
right click on the project name->properties->flex Build Path->add folder
the import is based on the 'package' declaration within the file itself (at the top of the file). If the file's package declaration does not match the actual folder structure, you will get problems.
Check the classes you can't see in the autocompletion list. Maybe those classes' package name doesn't match the actual structure.
Rob
Check your actionscript source paths. Any chance that the folders you are seeing (events and objects) are in there explicitly, and the others are not? Normally, you have all your source inside a folder like src that is in the source path, so that the compiler can find anything anywhere inside it. But you can just as easily make your source paths too specific and just see a few things...

requires named attributes

After I migrated my project from Windows to Mac, every time I try to embed an asset in Flash builder like this:
[Bindable] [Embed("assets/assets.swf#mySymbol")]
public var myClass:Class;
I get this error:
[Embed] requires named attributes
if I close the files containing the embedding, it compiles fine and doesn't give any problem.
I googled the error, and haven't found anything similar.
If I remember correctly:
[Embed(source="assets/assets.swf", symbol="mySymbol")]
These are named attributes FB is telling you about - source and symbol.
Update: as Jason Towne mentioned, the only required attribute is source. Symbol allows to bind specific symbol from swf to variable.

Resources